Added missing close2 to Hunter Job Quest, merge it to stable

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9452 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
KarLaeda 2006-12-11 14:17:02 +00:00
parent 4ee424c45d
commit cfb110ab58
4 changed files with 344 additions and 341 deletions

View File

@ -35,6 +35,7 @@ Date Added
======
12/11
* Some cleanup & optimization for MvM Arena [KarLaeda]
- Added missing close2 to Hunter Job Quest
* Added Yuno Government Buildings warps. Thanks to $ephiroth [Lupus]
- Added missing next, removed extra line to Wizard Job Quest
* Fixed Rogue / Assassin exploit, thanks to El Nino

View File

@ -1,135 +1,135 @@
//(=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)
//( (c)2006 eAthena Development Team presents )
//( ______ __ __ )
//( /\ _ \/\ \__/\ \ v 1.00.00 )
//( __\ \ \_\ \ \ ,_\ \ \___ __ ___ __ )
//( /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ )
//( /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \_\.\_ )
//( \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ )
//( \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ )
//( _ _ _ _ _ _ _ _ _ _ _ _ _ )
//( / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ )
//( ( e | A | t | h | e | n | a ) ( S | c | r | i | p | t ) )
//( \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ )
//( )
//(=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)
// Programmed by [Lance] ver. 1.1
// ---------------------------------------------------------
// [ Sentry System ]
// - Guards main towns against aggresive monsters and bad
// players.
// [ Customization ]
// - See OnInit:
// =========================================================
- script sentry_system -1,{
function spawn_guardian {
set .mob_id[getarg(0)], mobspawn("Guardian Sentry",1904,.mob_map$[getarg(0)],.mob_x[getarg(0)],.mob_y[getarg(0)]);
mobattach .mob_id[getarg(0)]; // Attach events to this script.
setmobdata .mob_id[getarg(0)], 24, 1; // Enable killer mode.
setmobdata .mob_id[getarg(0)], 25,
AI_ACTION_TYPE_DETECT|
AI_ACTION_TYPE_KILL|
AI_ACTION_TYPE_UNLOCK|
AI_ACTION_TYPE_DEAD|
AI_ACTION_TYPE_ATTACK; // Define engine callback routines.
setmobdata .mob_id[getarg(0)], 26, 1; // Prevents random walking.
setmobdata .mob_id[getarg(0)], 10, 1; // Enable AI mode 1.
getmobdata .mob_id[getarg(0)], .@temp;
set .@temp[9], .@temp[9]^(0x400&.@temp[9]); // Check and remove MD_CHANGECHASE mode flag.
setmobdata .mob_id[getarg(0)], 9, .@temp[9];
return;
}
function search_entry {
set .@tmp, getarraysize(getarg(0));
for(set .@i, 0; .@i < .@tmp; set .@i, .@i + 1){
if(getelementofarray(getarg(0),.@i) == getarg(1))
break;
}
if(.@i == .@tmp)
return -1;
else
return .@i;
}
// Script Entry Point - When an event from the script engine is received.
if(getarraysize(.ai_action) == 4){ // Checks if the data is formatted correctly.
set .@tmp, search_entry(.mob_id, .ai_action[AI_ACTION_SRC]);
switch(.ai_action[AI_ACTION_TYPE]){
case AI_ACTION_TYPE_DETECT: // We see something...
if(.ai_busy[.@tmp] == 0){ // Not busy
switch(.ai_action[AI_ACTION_TAR_TYPE]){ // Check what have we here.
case AI_ACTION_TAR_TYPE_PC: // It's a player
if(Karma > .karma){ // pkarma is higher?
unittalk .ai_action[AI_ACTION_SRC], "Who goes there!";
unitemote .ai_action[AI_ACTION_SRC], e_gasp; // !
unitattack .ai_action[AI_ACTION_SRC],.ai_action[AI_ACTION_TAR];
// We're currently busy.
set .ai_busy[.@tmp], .ai_action[AI_ACTION_TAR];
}
break;
case AI_ACTION_TAR_TYPE_MOB: // It's a monster
if(.ai_action[AI_ACTION_TAR] != .ai_action[AI_ACTION_SRC]){
getmobdata .ai_action[AI_ACTION_TAR], .@temp;
if(.@temp[9]&0x804){ // In Aggressive mode?
unittalk .ai_action[AI_ACTION_SRC], "Protect the villagers we must!";
unitemote .ai_action[AI_ACTION_SRC], e_gasp; // !
unitattack .ai_action[AI_ACTION_SRC],.ai_action[AI_ACTION_TAR];
// We're currently busy.
set .ai_busy[.@tmp], .ai_action[AI_ACTION_TAR];
}
}
break;
}
}
break;
case AI_ACTION_TYPE_KILL: // We eliminated the criminal
if(.ai_action[AI_ACTION_TAR_TYPE] == AI_ACTION_TAR_TYPE_PC)
set Karma, 0;
case AI_ACTION_TYPE_UNLOCK: // Target lost :(
if(.@tmp != -1){
set .ai_busy[.@tmp], 0; // Remove him, we're free.
}
// Walk back to where we came from.
unitwalk .ai_action[AI_ACTION_SRC],.mob_x[.@tmp],.mob_y[.@tmp];
break;
case AI_ACTION_TYPE_DEAD: // We got killed :(
if(.ai_action[AI_ACTION_TAR_TYPE] == AI_ACTION_TAR_TYPE_PC){ // Attacker is a player?
if(Karma < 250)
set Karma, Karma + 5;
else
set Karma, 255;
}
sleep 10000; // 10 seconds until reinforcements arrive
spawn_guardian .@tmp;
break;
case AI_ACTION_TYPE_ATTACK: // Someone attacked us
if(.ai_action[AI_ACTION_TAR_TYPE] == AI_ACTION_TAR_TYPE_PC){ // Attacker is a player?
if(Karma < 250)
set Karma, Karma + 1;
else
set Karma, 255;
}
// The system's AI will auto attack any attackers. So we leave it here.
break;
}
}
deletearray .ai_action, getarraysize(.ai_action); // Cleans up and frees up memory
end;
OnInit:
// Customization ---------------------------------------------------------------------
setarray .mob_map$, "prt_fild08.gat", "prt_fild05.gat", "prt_fild06.gat", "prt_gld.gat";
setarray .mob_x,176,369,29,165;
setarray .mob_y,372,201,187,37;
set .karma, 5;
// -----------------------------------------------------------------------------------
set .@tmp, getarraysize(.mob_map$);
for(set .@i, 0; .@i < .@tmp; set .@i, .@i + 1){
spawn_guardian .@i;
}
debugmes "[Sentry System] Spawned " + .@i + " guardians.";
end;
//(=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)
//( (c)2006 eAthena Development Team presents )
//( ______ __ __ )
//( /\ _ \/\ \__/\ \ v 1.00.00 )
//( __\ \ \_\ \ \ ,_\ \ \___ __ ___ __ )
//( /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ )
//( /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \_\.\_ )
//( \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ )
//( \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ )
//( _ _ _ _ _ _ _ _ _ _ _ _ _ )
//( / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ )
//( ( e | A | t | h | e | n | a ) ( S | c | r | i | p | t ) )
//( \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ )
//( )
//(=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)
// Programmed by [Lance] ver. 1.1
// ---------------------------------------------------------
// [ Sentry System ]
// - Guards main towns against aggresive monsters and bad
// players.
// [ Customization ]
// - See OnInit:
// =========================================================
- script sentry_system -1,{
function spawn_guardian {
set .mob_id[getarg(0)], mobspawn("Guardian Sentry",1904,.mob_map$[getarg(0)],.mob_x[getarg(0)],.mob_y[getarg(0)]);
mobattach .mob_id[getarg(0)]; // Attach events to this script.
setmobdata .mob_id[getarg(0)], 24, 1; // Enable killer mode.
setmobdata .mob_id[getarg(0)], 25,
AI_ACTION_TYPE_DETECT|
AI_ACTION_TYPE_KILL|
AI_ACTION_TYPE_UNLOCK|
AI_ACTION_TYPE_DEAD|
AI_ACTION_TYPE_ATTACK; // Define engine callback routines.
setmobdata .mob_id[getarg(0)], 26, 1; // Prevents random walking.
setmobdata .mob_id[getarg(0)], 10, 1; // Enable AI mode 1.
getmobdata .mob_id[getarg(0)], .@temp;
set .@temp[9], .@temp[9]^(0x400&.@temp[9]); // Check and remove MD_CHANGECHASE mode flag.
setmobdata .mob_id[getarg(0)], 9, .@temp[9];
return;
}
function search_entry {
set .@tmp, getarraysize(getarg(0));
for(set .@i, 0; .@i < .@tmp; set .@i, .@i + 1){
if(getelementofarray(getarg(0),.@i) == getarg(1))
break;
}
if(.@i == .@tmp)
return -1;
else
return .@i;
}
// Script Entry Point - When an event from the script engine is received.
if(getarraysize(.ai_action) == 4){ // Checks if the data is formatted correctly.
set .@tmp, search_entry(.mob_id, .ai_action[AI_ACTION_SRC]);
switch(.ai_action[AI_ACTION_TYPE]){
case AI_ACTION_TYPE_DETECT: // We see something...
if(.ai_busy[.@tmp] == 0){ // Not busy
switch(.ai_action[AI_ACTION_TAR_TYPE]){ // Check what have we here.
case AI_ACTION_TAR_TYPE_PC: // It's a player
if(Karma > .karma){ // pkarma is higher?
unittalk .ai_action[AI_ACTION_SRC], "Who goes there!";
unitemote .ai_action[AI_ACTION_SRC], e_gasp; // !
unitattack .ai_action[AI_ACTION_SRC],.ai_action[AI_ACTION_TAR];
// We're currently busy.
set .ai_busy[.@tmp], .ai_action[AI_ACTION_TAR];
}
break;
case AI_ACTION_TAR_TYPE_MOB: // It's a monster
if(.ai_action[AI_ACTION_TAR] != .ai_action[AI_ACTION_SRC]){
getmobdata .ai_action[AI_ACTION_TAR], .@temp;
if(.@temp[9]&0x804){ // In Aggressive mode?
unittalk .ai_action[AI_ACTION_SRC], "Protect the villagers we must!";
unitemote .ai_action[AI_ACTION_SRC], e_gasp; // !
unitattack .ai_action[AI_ACTION_SRC],.ai_action[AI_ACTION_TAR];
// We're currently busy.
set .ai_busy[.@tmp], .ai_action[AI_ACTION_TAR];
}
}
break;
}
}
break;
case AI_ACTION_TYPE_KILL: // We eliminated the criminal
if(.ai_action[AI_ACTION_TAR_TYPE] == AI_ACTION_TAR_TYPE_PC)
set Karma, 0;
case AI_ACTION_TYPE_UNLOCK: // Target lost :(
if(.@tmp != -1){
set .ai_busy[.@tmp], 0; // Remove him, we're free.
}
// Walk back to where we came from.
unitwalk .ai_action[AI_ACTION_SRC],.mob_x[.@tmp],.mob_y[.@tmp];
break;
case AI_ACTION_TYPE_DEAD: // We got killed :(
if(.ai_action[AI_ACTION_TAR_TYPE] == AI_ACTION_TAR_TYPE_PC){ // Attacker is a player?
if(Karma < 250)
set Karma, Karma + 5;
else
set Karma, 255;
}
sleep 10000; // 10 seconds until reinforcements arrive
spawn_guardian .@tmp;
break;
case AI_ACTION_TYPE_ATTACK: // Someone attacked us
if(.ai_action[AI_ACTION_TAR_TYPE] == AI_ACTION_TAR_TYPE_PC){ // Attacker is a player?
if(Karma < 250)
set Karma, Karma + 1;
else
set Karma, 255;
}
// The system's AI will auto attack any attackers. So we leave it here.
break;
}
}
deletearray .ai_action, getarraysize(.ai_action); // Cleans up and frees up memory
end;
OnInit:
// Customization ---------------------------------------------------------------------
setarray .mob_map$, "prt_fild08.gat", "prt_fild05.gat", "prt_fild06.gat", "prt_gld.gat";
setarray .mob_x,176,369,29,165;
setarray .mob_y,372,201,187,37;
set .karma, 5;
// -----------------------------------------------------------------------------------
set .@tmp, getarraysize(.mob_map$);
for(set .@i, 0; .@i < .@tmp; set .@i, .@i + 1){
spawn_guardian .@i;
}
debugmes "[Sentry System] Spawned " + .@i + " guardians.";
end;
}

View File

@ -5,7 +5,7 @@
//= Converted by kobra_k88
//= Further bugfixed and tested by Lupus
//===== Current Version: =====================================
//= 2.3a
//= 2.4a
//===== Compatible With: =====================================
//= eAthena 1.0
//===== Description: =========================================
@ -31,7 +31,7 @@
//= 2.2 Merged JFunc, fixed missing dialogues [Lupus]
//= 2.2a Fixed Sharon resetting the test2 item set [Lupus]
//= 2.3a 7 official sets of Demon Hunter,thx to Dr.Evil [Lupus]
//= 2.4 Added missing next;, missing NPC names [Lupus]
//= 2.4a Added missing next;, missing NPC names [Lupus]
//============================================================
//<====================================== Job Changer ========================================>\\
@ -132,7 +132,7 @@ L_Start:
mes "[Hunter Sharon]";
mes "If you trained hard enough, you shouldn't have any problems becoming a Hunter.";
close;
M_End:
mes "[Hunter Sharon]";
mes "Ok, I'll see you later.";
@ -158,7 +158,7 @@ L_Start:
set @score, @score + 10;
M_1b:
mes "[Hunter Sharon]";
mes "Okay, so you picked your hunting spot! You plan to go to the Sograt Desert to hunt Hodes.";
next;
@ -344,11 +344,11 @@ L_Change:
close;
sL_NotRdy:
mes "[Hunter Sharon]";
mes "Hmmm, I received news of your success.... But you don't seem to have the ^5533FFNecklace of Wisdom^000000 as proof.";
mes "Hmmm, I received news of your success.... But you don't seem to have the ^5533FFNecklace of Wisdom^000000 as proof.";
emotion e_hmm;
next;
mes "[Hunter Sharon]";
mes "You will need the Necklace of Wisdom to become a Hunter. If you don't have it you will have to start the test over.";
mes "You will need the Necklace of Wisdom to become a Hunter. If you don't have it you will have to start the test over.";
next;
menu "Um... I've got it.... somewhere....",-, "Heh heh.... I must have misplaced it.....",sM_ReStart;
@ -362,7 +362,7 @@ L_Change:
emotion e_pif;
set HNTR_Q, 0;
set HNTR_Q2, 0;
close;
close;
}
@ -467,11 +467,12 @@ L_Start:
mes "Stop playing around "+strcharinfo(0)+", that's your name, right?";
next;
menu "Yes",M_Yes, "Uhhh no",sM_End;
sM_End:
mes "[Demon Hunter]";
mes "DON'T you mess around with me! If you're gonna fool around then LEAVE!";
emotion e_pif;
close2;
warp "hugel.gat", 207, 222;
end;
@ -609,7 +610,7 @@ L_Start:
if (countitem(1751) <= 5 && @HNTR_QA==0) callsub sF_GetArrows;
mes "[Guild Master]";
mes "Good luck, I'll send you to the test room now.";
next;
close2;
set HNTR_Q2, 1;
set @HNTR_QA,0;
savepoint "payon_in02.gat", 16, 26;
@ -619,7 +620,7 @@ L_Start:
sF_GetArrows:
mes "[Guild Master]";
mes "This is where your hard work in the 2nd test payed off. Here are some arrows, made with the items you collected.";
getitem 1751, 200;
getitem 1751, 200;
set @HNTR_QA,1;
next;
return;
@ -684,6 +685,7 @@ L_Start:
M_End:
mes "[Test Guide]";
mes "Alright, I'll send you back to Payon. Hopefully I'll see you again later. Don't forget to save!";
close2;
warp "payon_in02.gat", 16, 26;
end;

View File

@ -1,198 +1,198 @@
// Variables Logging:
// .mc_moblist[] - ID list of mobs
prontera.gat,180,200,4 script Monster Controller 123,{
function display_info {
getmobdata getarg(0), .@mob_data;
set .@array_size, getarraysize(.@mob_data);
for(set .@i, 0; .@i < .@array_size; set .@i, .@i + 1){
mes .@i + " - " + .@mob_data[.@i];
}
return;
}
function remove_mob {
removemob getarg(0);
set .@mob_size, getarraysize(.mc_moblist);
for(set .@i, 0; .@i < .@mob_size; set .@i, .@i + 1){
if(.mc_moblist[.@i] == getarg(0))
deletearray .mc_moblist[.@i], 1;
}
}
function make_menu {
set .@array_size, getarraysize(.mc_moblist);
set .@tmp_str$, "";
for(set .@i, 0; .@i < .@array_size; set .@i, .@i + 1){
set .@tmp_str$, .@tmp_str$ + .mc_moblist[.@i] + ":";
}
select .@tmp_str$;
return .mc_moblist[@menu-1];
}
function summon_mob {
set .@mob_size, getarraysize(.mc_moblist);
set .mc_moblist[.@mob_size], spawnmob("Slave - " + .@mob_size, getarg(0), "prontera.gat", 180, 200);
mobattach .mc_moblist[.@mob_size];
setmobdata .mc_moblist[.@mob_size], 25,
AI_ACTION_TYPE_ATTACK|
AI_ACTION_TYPE_DETECT|
AI_ACTION_TYPE_DEAD|
AI_ACTION_TYPE_ASSIST|
AI_ACTION_TYPE_KILL|
AI_ACTION_TYPE_UNLOCK|
AI_ACTION_TYPE_WALKACK|
AI_ACTION_TYPE_WARPACK;
return;
}
function list_mobs {
set .@mob_size, getarraysize(.mc_moblist);
for(set .@i, 0; .@i < .@mob_size; set .@i, .@i + 1){
mes "- " + .mc_moblist[.@i];
}
return;
}
if(getarraysize(.ai_action) == 4){
mapannounce "prontera.gat", "[Mob Control] AI Action Received from " + .ai_action[AI_ACTION_SRC] + "!",16;
switch(.ai_action[AI_ACTION_TAR_TYPE]){
case AI_ACTION_TAR_TYPE_PC:
set .@action_from$, "Player";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
case AI_ACTION_TAR_TYPE_MOB:
set .@action_from$, "Monster";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
case AI_ACTION_TAR_TYPE_PET:
set .@action_from$, "Pet";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
case AI_ACTION_TAR_TYPE_HOMUN:
set .@action_from$, "Homunculus";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
default:
set .@action_from$, "Unknown";
set .@action_name$, ""+.ai_action[AI_ACTION_TAR];
break;
}
switch(.ai_action[AI_ACTION_TYPE]){
case AI_ACTION_TYPE_ATTACK:
set .@action_type$, "Attacked by";
break;
case AI_ACTION_TYPE_DETECT:
set .@action_type$, "Detected";
break;
case AI_ACTION_TYPE_DEAD:
set .@action_type$, "Killed by";
remove_mob .ai_action[AI_ACTION_SRC];
break;
case AI_ACTION_TYPE_ASSIST:
set .@action_type$, "Assisting";
break;
case AI_ACTION_TYPE_UNLOCK:
set .@action_type$, "Unlocked target";
break;
case AI_ACTION_TYPE_KILL:
set .@action_type$, "Killed";
break;
case AI_ACTION_TYPE_WALKACK:
set .@action_type$, "Completed Walking";
break;
case AI_ACTION_TYPE_WARPACK:
set .@action_type$, "Warped";
break;
}
mapannounce "prontera.gat", "Details - " + .@action_type$ + " [" + .@action_from$ + "] " + .@action_name$ + "!", 16;
deletearray .ai_action, 4;
end;
}
L_MainMenu:
mes "[Monster Controller]";
mes "Current active monsters:";
list_mobs;
switch(select("Summon","Remove","Information","Actions")){
case 1: // Summon
next;
mes "[Monster Controller]";
mes "Monster ID -";
input @mob_id;
next;
summon_mob @mob_id;
goto L_MainMenu;
break;
case 2: // Remove
remove_mob make_menu();
next;
goto L_MainMenu;
break;
case 3: // Information
set .@tmp, make_menu();
next;
mes "[Monster Info]";
display_info .@tmp;
next;
goto L_MainMenu;
break;
case 4: // Actions
goto L_AttackMenu;
break;
}
L_AttackMenu:
switch(select("Walk","Follow","Attack","Stop","Defend","Talk","Emote","Random Walk","Callback","Back")){
case 1: // Walk
set .@src, make_menu();
input .@x;
input .@y;
mobwalk .@src,.@x,.@y; // Mode 1: Walk to location.
break;
case 2: // Follow
set .@src, make_menu();
input .@tar;
mobwalk .@src, .@tar; // Mode 2: Walk to target.
break;
case 3: // Attack
set .@src, make_menu();
input .@tar;
mobattack .@src, .@tar;
break;
case 4: // Stop
set .@src, make_menu();
mobstop .@src;
break;
case 5: // Defend/Assist
set .@src, make_menu();
input .@tar;
mobassist .@src, .@tar;
break;
case 6: // Talk
set .@src, make_menu();
input .@text$;
mobtalk .@src, .@text$;
break;
case 7: // Emote
set .@src, make_menu();
input .@emote;
mobemote .@src, .@emote;
break;
case 8:
set .@src, make_menu();
input .@flag;
mobrandomwalk .@src, .@flag;
break;
case 9:
set .@src, make_menu();
input .@flag;
setmobdata .@src, 25, .@flag;
break;
case 9:
next;
goto L_MainMenu;
}
goto L_AttackMenu;
// Variables Logging:
// .mc_moblist[] - ID list of mobs
prontera.gat,180,200,4 script Monster Controller 123,{
function display_info {
getmobdata getarg(0), .@mob_data;
set .@array_size, getarraysize(.@mob_data);
for(set .@i, 0; .@i < .@array_size; set .@i, .@i + 1){
mes .@i + " - " + .@mob_data[.@i];
}
return;
}
function remove_mob {
removemob getarg(0);
set .@mob_size, getarraysize(.mc_moblist);
for(set .@i, 0; .@i < .@mob_size; set .@i, .@i + 1){
if(.mc_moblist[.@i] == getarg(0))
deletearray .mc_moblist[.@i], 1;
}
}
function make_menu {
set .@array_size, getarraysize(.mc_moblist);
set .@tmp_str$, "";
for(set .@i, 0; .@i < .@array_size; set .@i, .@i + 1){
set .@tmp_str$, .@tmp_str$ + .mc_moblist[.@i] + ":";
}
select .@tmp_str$;
return .mc_moblist[@menu-1];
}
function summon_mob {
set .@mob_size, getarraysize(.mc_moblist);
set .mc_moblist[.@mob_size], spawnmob("Slave - " + .@mob_size, getarg(0), "prontera.gat", 180, 200);
mobattach .mc_moblist[.@mob_size];
setmobdata .mc_moblist[.@mob_size], 25,
AI_ACTION_TYPE_ATTACK|
AI_ACTION_TYPE_DETECT|
AI_ACTION_TYPE_DEAD|
AI_ACTION_TYPE_ASSIST|
AI_ACTION_TYPE_KILL|
AI_ACTION_TYPE_UNLOCK|
AI_ACTION_TYPE_WALKACK|
AI_ACTION_TYPE_WARPACK;
return;
}
function list_mobs {
set .@mob_size, getarraysize(.mc_moblist);
for(set .@i, 0; .@i < .@mob_size; set .@i, .@i + 1){
mes "- " + .mc_moblist[.@i];
}
return;
}
if(getarraysize(.ai_action) == 4){
mapannounce "prontera.gat", "[Mob Control] AI Action Received from " + .ai_action[AI_ACTION_SRC] + "!",16;
switch(.ai_action[AI_ACTION_TAR_TYPE]){
case AI_ACTION_TAR_TYPE_PC:
set .@action_from$, "Player";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
case AI_ACTION_TAR_TYPE_MOB:
set .@action_from$, "Monster";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
case AI_ACTION_TAR_TYPE_PET:
set .@action_from$, "Pet";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
case AI_ACTION_TAR_TYPE_HOMUN:
set .@action_from$, "Homunculus";
set .@action_name$, rid2name(.ai_action[AI_ACTION_TAR]);
break;
default:
set .@action_from$, "Unknown";
set .@action_name$, ""+.ai_action[AI_ACTION_TAR];
break;
}
switch(.ai_action[AI_ACTION_TYPE]){
case AI_ACTION_TYPE_ATTACK:
set .@action_type$, "Attacked by";
break;
case AI_ACTION_TYPE_DETECT:
set .@action_type$, "Detected";
break;
case AI_ACTION_TYPE_DEAD:
set .@action_type$, "Killed by";
remove_mob .ai_action[AI_ACTION_SRC];
break;
case AI_ACTION_TYPE_ASSIST:
set .@action_type$, "Assisting";
break;
case AI_ACTION_TYPE_UNLOCK:
set .@action_type$, "Unlocked target";
break;
case AI_ACTION_TYPE_KILL:
set .@action_type$, "Killed";
break;
case AI_ACTION_TYPE_WALKACK:
set .@action_type$, "Completed Walking";
break;
case AI_ACTION_TYPE_WARPACK:
set .@action_type$, "Warped";
break;
}
mapannounce "prontera.gat", "Details - " + .@action_type$ + " [" + .@action_from$ + "] " + .@action_name$ + "!", 16;
deletearray .ai_action, 4;
end;
}
L_MainMenu:
mes "[Monster Controller]";
mes "Current active monsters:";
list_mobs;
switch(select("Summon","Remove","Information","Actions")){
case 1: // Summon
next;
mes "[Monster Controller]";
mes "Monster ID -";
input @mob_id;
next;
summon_mob @mob_id;
goto L_MainMenu;
break;
case 2: // Remove
remove_mob make_menu();
next;
goto L_MainMenu;
break;
case 3: // Information
set .@tmp, make_menu();
next;
mes "[Monster Info]";
display_info .@tmp;
next;
goto L_MainMenu;
break;
case 4: // Actions
goto L_AttackMenu;
break;
}
L_AttackMenu:
switch(select("Walk","Follow","Attack","Stop","Defend","Talk","Emote","Random Walk","Callback","Back")){
case 1: // Walk
set .@src, make_menu();
input .@x;
input .@y;
mobwalk .@src,.@x,.@y; // Mode 1: Walk to location.
break;
case 2: // Follow
set .@src, make_menu();
input .@tar;
mobwalk .@src, .@tar; // Mode 2: Walk to target.
break;
case 3: // Attack
set .@src, make_menu();
input .@tar;
mobattack .@src, .@tar;
break;
case 4: // Stop
set .@src, make_menu();
mobstop .@src;
break;
case 5: // Defend/Assist
set .@src, make_menu();
input .@tar;
mobassist .@src, .@tar;
break;
case 6: // Talk
set .@src, make_menu();
input .@text$;
mobtalk .@src, .@text$;
break;
case 7: // Emote
set .@src, make_menu();
input .@emote;
mobemote .@src, .@emote;
break;
case 8:
set .@src, make_menu();
input .@flag;
mobrandomwalk .@src, .@flag;
break;
case 9:
set .@src, make_menu();
input .@flag;
setmobdata .@src, 25, .@flag;
break;
case 9:
next;
goto L_MainMenu;
}
goto L_AttackMenu;
}