Przeglądaj źródła

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
KarLaeda 18 lat temu
rodzic
commit
cfb110ab58
4 zmienionych plików z 344 dodań i 341 usunięć
  1. 1 0
      npc/Changelog.txt
  2. 134 134
      npc/custom/Lance/Sentry.cpp
  3. 12 10
      npc/jobs/2-1/hunter.txt
  4. 197 197
      npc/sample/monster_controller.cpp

+ 1 - 0
npc/Changelog.txt

@@ -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

+ 134 - 134
npc/custom/Lance/Sentry.cpp

@@ -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;
+
 }

+ 12 - 10
npc/jobs/2-1/hunter.txt

@@ -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;
 

+ 197 - 197
npc/sample/monster_controller.cpp

@@ -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;
 }