[nexuiz-commits] r6600 - trunk/data/qcsrc/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon Apr 27 20:20:36 EDT 2009


Author: mand1nga
Date: 2009-04-27 20:20:36 -0400 (Mon, 27 Apr 2009)
New Revision: 6600

Modified:
   trunk/data/qcsrc/server/bots_scripting.qc
Log:
Converted the bot command queue from arrays to entities. Now server/ compiles again without optimizations nor 'extra' globals.


Modified: trunk/data/qcsrc/server/bots_scripting.qc
===================================================================
--- trunk/data/qcsrc/server/bots_scripting.qc	2009-04-27 23:56:59 UTC (rev 6599)
+++ trunk/data/qcsrc/server/bots_scripting.qc	2009-04-28 00:20:36 UTC (rev 6600)
@@ -4,21 +4,25 @@
 #define BOT_CMD_CONTINUE		2
 #define BOT_CMD_WAIT			3
 #define BOT_CMD_TURN			4
-#define BOT_CMD_MOVETO			5
-#define BOT_CMD_RESETGOAL		6
-#define BOT_CMD_CC				7
-#define BOT_CMD_IF      		8
-#define BOT_CMD_ELSE    		9
+#define BOT_CMD_MOVETO			5	// Not implemented yet
+#define BOT_CMD_RESETGOAL		6	// Not implemented yet
+#define BOT_CMD_CC			7
+#define BOT_CMD_IF      		8
+#define BOT_CMD_ELSE    		9
 #define BOT_CMD_FI      		10
 #define BOT_CMD_RESETAIM   		11
-#define BOT_CMD_AIM				12
-#define BOT_CMD_PRESSKEY		13
-#define BOT_CMD_RELEASEKEY		14
-#define BOT_CMD_SELECTWEAPON	15
+#define BOT_CMD_AIM			12
+#define BOT_CMD_PRESSKEY		13
+#define BOT_CMD_RELEASEKEY		14
+#define BOT_CMD_SELECTWEAPON		15
 #define BOT_CMD_IMPULSE			16
+#define BOT_CMD_WHILE			17	// Not implemented yet
+#define BOT_CMD_WEND			18	// Not implemented yet
+#define BOT_CMD_CHASE			19	// Not implemented yet
 #define BOT_CMD_COUNTER			17
 
 // NOTE: Following commands should be implemented on the bot ai
+//		 If a new command should be handled by the target ai(s) please declare it here
 .float(vector) cmd_moveto;
 .float() cmd_resetgoal;
 
@@ -27,23 +31,25 @@
 #define BOT_CMD_PARAMETER_FLOAT		1
 #define BOT_CMD_PARAMETER_STRING	2
 #define BOT_CMD_PARAMETER_VECTOR	3
-
-float bot_cmds_initialized;
-float bot_cmd_parm_type[BOT_CMD_COUNTER];
-string bot_cmd_string[BOT_CMD_COUNTER];
 
+float bot_cmds_initialized;
+float bot_cmd_parm_type[BOT_CMD_COUNTER];
+string bot_cmd_string[BOT_CMD_COUNTER];
+
 // Bots command queue
+entity bot_cmd;				// Current command
 
-#define BOT_CMD_QUEUE_SIZE 80
+.float is_bot_cmd;			// Tells if the entity is a bot command
+.float bot_cmd_index;			// Position of the command in the queue
+.float bot_cmd_type;			// If of command (see the BOT_CMD_* defines)
+.float bot_cmd_parm_float;		// Field to store a float parameter
+.string bot_cmd_parm_string;		// Field to store a string parameter
+.vector bot_cmd_parm_vector;		// Field to store a vector parameter
+.float bot_cmd_execution_counter;	// How many times this command on the queue was executed
 
-.float bot_cmd[BOT_CMD_QUEUE_SIZE];
-.float bot_cmd_parm_float[BOT_CMD_QUEUE_SIZE];
-.string bot_cmd_parm_string[BOT_CMD_QUEUE_SIZE];
-.vector bot_cmd_parm_vector[BOT_CMD_QUEUE_SIZE];
+.float bot_cmd_execution_index;		// Position in the queue of the command to be executed
+.float bot_cmd_queue_index;		// Position of the last command in the queue
 
-.float bot_cmd_execution_index;
-.float bot_cmd_queue_index;
-
 // Initialize global commands list
 // NOTE: New commands should be initialized here
 void bot_commands_init()
@@ -67,35 +73,35 @@
 	bot_cmd_parm_type[BOT_CMD_MOVETO]		= BOT_CMD_PARAMETER_VECTOR;
 
 	bot_cmd_string[BOT_CMD_RESETGOAL]		= "resetgoal";
-	bot_cmd_parm_type[BOT_CMD_RESETGOAL]	= BOT_CMD_PARAMETER_NONE;
+	bot_cmd_parm_type[BOT_CMD_RESETGOAL]		= BOT_CMD_PARAMETER_NONE;
 
-	bot_cmd_string[BOT_CMD_CC]				= "cc";
+	bot_cmd_string[BOT_CMD_CC]			= "cc";
 	bot_cmd_parm_type[BOT_CMD_CC]			= BOT_CMD_PARAMETER_STRING;
 
-	bot_cmd_string[BOT_CMD_IF]				= "if";
+	bot_cmd_string[BOT_CMD_IF]			= "if";
 	bot_cmd_parm_type[BOT_CMD_IF]			= BOT_CMD_PARAMETER_STRING;
 
 	bot_cmd_string[BOT_CMD_ELSE]			= "else";
 	bot_cmd_parm_type[BOT_CMD_ELSE]			= BOT_CMD_PARAMETER_NONE;
 
-	bot_cmd_string[BOT_CMD_FI]				= "fi";
+	bot_cmd_string[BOT_CMD_FI]			= "fi";
 	bot_cmd_parm_type[BOT_CMD_FI]			= BOT_CMD_PARAMETER_NONE;
 
 	bot_cmd_string[BOT_CMD_RESETAIM]		= "resetaim";
 	bot_cmd_parm_type[BOT_CMD_RESETAIM]		= BOT_CMD_PARAMETER_NONE;
 
-	bot_cmd_string[BOT_CMD_AIM]				= "aim";
+	bot_cmd_string[BOT_CMD_AIM]			= "aim";
 	bot_cmd_parm_type[BOT_CMD_AIM]			= BOT_CMD_PARAMETER_STRING;
-
-	bot_cmd_string[BOT_CMD_PRESSKEY]		= "presskey";
-	bot_cmd_parm_type[BOT_CMD_PRESSKEY]		= BOT_CMD_PARAMETER_STRING;
-
-	bot_cmd_string[BOT_CMD_RELEASEKEY]		= "releasekey";
-	bot_cmd_parm_type[BOT_CMD_RELEASEKEY]	= BOT_CMD_PARAMETER_STRING;
-
-	bot_cmd_string[BOT_CMD_SELECTWEAPON]	= "selectweapon";
-	bot_cmd_parm_type[BOT_CMD_SELECTWEAPON]	= BOT_CMD_PARAMETER_FLOAT;
 
+	bot_cmd_string[BOT_CMD_PRESSKEY]		= "presskey";
+	bot_cmd_parm_type[BOT_CMD_PRESSKEY]		= BOT_CMD_PARAMETER_STRING;
+
+	bot_cmd_string[BOT_CMD_RELEASEKEY]		= "releasekey";
+	bot_cmd_parm_type[BOT_CMD_RELEASEKEY]		= BOT_CMD_PARAMETER_STRING;
+
+	bot_cmd_string[BOT_CMD_SELECTWEAPON]		= "selectweapon";
+	bot_cmd_parm_type[BOT_CMD_SELECTWEAPON]		= BOT_CMD_PARAMETER_FLOAT;
+
 	bot_cmd_string[BOT_CMD_IMPULSE]			= "impulse";
 	bot_cmd_parm_type[BOT_CMD_IMPULSE]		= BOT_CMD_PARAMETER_FLOAT;
 
@@ -109,7 +115,7 @@
 
 	bot = findchainflags(flags, FL_CLIENT);
 	while (bot)
-	{
+	{
 		if(clienttype(bot) == CLIENTTYPE_BOT)
 		if(bot.netname==name)
 			return bot;
@@ -142,13 +148,57 @@
 
 void bot_clearqueue()
 {
-	self.(bot_cmd[0]) = BOT_CMD_NULL;
+	entity head, newhead;
+
+	head = findchainfloat(is_bot_cmd, TRUE);
+	newhead = head;
+
+	while(newhead)
+	{
+		newhead = head.chain;
+
+		if(head.owner==self)
+			remove(head);
+
+		head = newhead;
+	}
+
 	self.bot_cmd_queue_index = 0;
 	self.bot_cmd_execution_index = 0;
 }
 
-void bot_queuecommand(entity bot, string cmd, string parm)
+entity bot_spawncmd(entity bot, float type)
 {
+	entity cmd;
+
+	bot.bot_cmd_queue_index++;
+
+	cmd = spawn();
+	cmd.owner = bot;
+	cmd.is_bot_cmd = TRUE;
+	cmd.bot_cmd_type = type;
+	cmd.bot_cmd_index = bot.bot_cmd_queue_index;
+
+	return cmd;
+}
+
+void bot_debugcmd(entity cmd)
+{
+	print(strcat("Owner: ",cmd.owner.netname, "\n"));
+	print(strcat("Cmd Type: ",ftos(cmd.bot_cmd_type), "\n"));
+	print(strcat("Cmd Index: ",ftos(cmd.bot_cmd_index), "\n"));
+
+	print(strcat("Param Float: ",ftos(cmd.bot_cmd_parm_float), "\n"));
+	print(strcat("Param String: ",cmd.bot_cmd_parm_string, "\n"));
+	print(strcat("Param Vector: ",vtos(cmd.bot_cmd_parm_vector), "\n"));
+
+	print(strcat("Bot queue index: ",	ftos(cmd.owner.bot_cmd_queue_index), "\n"));
+	print(strcat("Bot execution index: ",	ftos(cmd.owner.bot_cmd_execution_index), "\n\n"));
+}
+
+void bot_queuecommand(entity bot, string cmdstring, string parm)
+{
+	entity cmd;
 	local float queue_index, cmd_parm_type, i;
 
 	if not(bot.isbot)
@@ -156,76 +206,43 @@
 
 	if(!bot_cmds_initialized)
 		bot_commands_init();
-
-	queue_index = bot.bot_cmd_queue_index;
-
-	if(bot.bot_cmd[queue_index]!=BOT_CMD_NULL)
-	{
-		print( strcat("WARNING: Command queue of length (",ftos(BOT_CMD_QUEUE_SIZE),") is full. Command ignored.\n"));
-		return;
-	}
-
+
 	for(i=1;i<BOT_CMD_COUNTER;++i)
 	{
-		if(bot_cmd_string[i]!=cmd)
+		if(bot_cmd_string[i]!=cmdstring)
 			continue;
-
+
 		cmd_parm_type = bot_cmd_parm_type[i];
 
 		if(cmd_parm_type!=BOT_CMD_PARAMETER_NONE&&parm=="")
 		{
-			print("ERROR: Invalid parameters count\n");
+			print("ERROR: A parameter is required for this command\n");
 			return;
 		}
 
-		// Load command into queue
-		bot.(bot_cmd[queue_index]) = i;
-
-		// Load parameters into queue
+		// Load command into queue
+		cmd = bot_spawncmd(bot, i);
+
+		// Attach parameter
 		switch(cmd_parm_type)
 		{
 			case BOT_CMD_PARAMETER_FLOAT:
-				bot.(bot_cmd_parm_float[queue_index])	= stof(parm);
+				cmd.bot_cmd_parm_float = stof(parm);
 				break;
 			case BOT_CMD_PARAMETER_STRING:
-				bot.(bot_cmd_parm_string[queue_index])	= strzone(parm);
+				cmd.bot_cmd_parm_string = strzone(parm);
 				break;
 			case BOT_CMD_PARAMETER_VECTOR:
-				bot.(bot_cmd_parm_vector[queue_index])	= stov(parm);
+				cmd.bot_cmd_parm_vector = stov(parm);
 				break;
 			default:
 				break;
 		}
-
-		// Move the queue index to the next position
-		if(queue_index==BOT_CMD_QUEUE_SIZE-1)
-			bot.bot_cmd_queue_index = queue_index = 0;
-		else
-			bot.bot_cmd_queue_index += 1;
-
 		return;
-	}
+	}
 	print("ERROR: No such command");
 }
 
-float bot_cmd_getparm_float()
-{
-	local float index = self.bot_cmd_execution_index;
-	return self.bot_cmd_parm_float[index];
-}
-
-string bot_cmd_getparm_string()
-{
-	local float index = self.bot_cmd_execution_index;
-	return self.bot_cmd_parm_string[index];
-}
-
-vector bot_cmd_getparm_vector()
-{
-	local float index = self.bot_cmd_execution_index;
-	return self.bot_cmd_parm_vector[index];
-}
-
 void bot_cmdhelp(string scmd)
 {
 	local float i, index, ntype;
@@ -294,7 +311,7 @@
 				print("Conditions: a=b, a>b, a<b, a\t\t(spaces not allowed)\n");
 				print("            Values in conditions can be numbers, cvars in the form cvar.cvar_string or special fields\n");
 				print("Fields: health, speed, flagcarrier\n");
-				print("Examples: if health>50; if health>cvar.g_balance_laser_primary_damage; if flagcarrier;");
+				print("Examples: if health>50; if health>cvar.g_balance_laser_primary_damage; if flagcarrier;");
 				break;
 			case BOT_CMD_RESETAIM:
 				print("Points the aim to the coordinates x,y 0,0");
@@ -304,18 +321,18 @@
 				print("There is a 3rd optional parameter telling in how many seconds the aim has to reach the new position\n");
 				print("Examples: aim \"90 0\"	// Turn 90 degrees inmediately (positive numbers move to the left/up)\n");
 				print("          aim \"0 90 2\"	// Will gradually look to the sky in the next two seconds");
-				break;
-			case BOT_CMD_PRESSKEY:
-				print("Press one of the following keys: forward, backward, left, right, jump, crouch, attack1, attack2, use\n");
-				print("Multiple keys can be pressed at time (with many presskey calls) and it will remain pressed until the command \"releasekey\" is called");
-				print("Note: The script will not return the control to the bot ai until all keys are released");
-				break;
-			case BOT_CMD_RELEASEKEY:
-				print("Release previoulsy used keys. Use the parameter \"all\" to release all keys");
-				break;
-			default:
-				print("This command has no description yet.");
-				break;
+				break;
+			case BOT_CMD_PRESSKEY:
+				print("Press one of the following keys: forward, backward, left, right, jump, crouch, attack1, attack2, use\n");
+				print("Multiple keys can be pressed at time (with many presskey calls) and it will remain pressed until the command \"releasekey\" is called");
+				print("Note: The script will not return the control to the bot ai until all keys are released");
+				break;
+			case BOT_CMD_RELEASEKEY:
+				print("Release previoulsy used keys. Use the parameter \"all\" to release all keys");
+				break;
+			default:
+				print("This command has no description yet.");
+				break;
 		}
 		print("\n");
 	}
@@ -325,11 +342,11 @@
 {
 	local float i;
 	local string ptype;
-
-	if(!bot_cmds_initialized)
-		bot_commands_init();
 
-	print("List of all available commands:\n");
+	if(!bot_cmds_initialized)
+		bot_commands_init();
+
+	print("List of all available commands:\n");
 	print(" Command\t\t\t\tParameter Type\n");
 
 	for(i=1;i<BOT_CMD_COUNTER;++i)
@@ -350,7 +367,7 @@
 				break;
 		}
 		print(strcat(" ",bot_cmd_string[i],"\t\t\t\t<",ptype,"> \n"));
-	}
+	}
 }
 
 // Commands code
@@ -361,18 +378,18 @@
 #define BOT_EXEC_STATUS_WAITING	2
 
 #define CMD_STATUS_EXECUTING	0
-#define CMD_STATUS_FINISHED		1
-#define CMD_STATUS_ERROR		2
+#define CMD_STATUS_FINISHED	1
+#define CMD_STATUS_ERROR	2
 
-float bot_cmd_raw()
-{
-	clientcommand(self,bot_cmd_getparm_string());
+float bot_cmd_cc()
+{
+	clientcommand(self,bot_cmd.bot_cmd_parm_string);
 	return CMD_STATUS_FINISHED;
 }
 
 float bot_cmd_impulse()
 {
-	self.impulse = bot_cmd_getparm_float();
+	self.impulse = bot_cmd.bot_cmd_parm_float;
 	return CMD_STATUS_FINISHED;
 }
 
@@ -396,74 +413,74 @@
 			return CMD_STATUS_EXECUTING;
 	}
 
-	self.bot_cmd_wait_time = time + bot_cmd_getparm_float();
+	self.bot_cmd_wait_time = time + bot_cmd.bot_cmd_parm_float;
 	self.bot_exec_status |= BOT_EXEC_STATUS_WAITING;
 	return CMD_STATUS_EXECUTING;
 }
 
 float bot_cmd_turn()
-{
-	self.v_angle_y = self.v_angle_y + bot_cmd_getparm_float();
+{
+	self.v_angle_y = self.v_angle_y + bot_cmd.bot_cmd_parm_float;
 	self.v_angle_y = self.v_angle_y - floor(self.v_angle_y / 360) * 360;
 	return CMD_STATUS_FINISHED;
 }
-
-float bot_cmd_select_weapon()
-{
-	local float id;
-
-	id = bot_cmd_getparm_float();
-
-	if(id < WEP_FIRST || id > WEP_LAST)
-		return CMD_STATUS_ERROR;
-
-	if(client_hasweapon(self, id, TRUE, FALSE))
-		self.switchweapon = id;
-
-	return CMD_STATUS_FINISHED;
-}
 
+float bot_cmd_select_weapon()
+{
+	local float id;
+
+	id = bot_cmd.bot_cmd_parm_float;
+
+	if(id < WEP_FIRST || id > WEP_LAST)
+		return CMD_STATUS_ERROR;
+
+	if(client_hasweapon(self, id, TRUE, FALSE))
+		self.switchweapon = id;
+
+	return CMD_STATUS_FINISHED;
+}
+
 .float bot_cmd_condition_status;
 
-#define CMD_CONDITION_NONE			0
-#define CMD_CONDITION_TRUE			1
-#define CMD_CONDITION_FALSE			2
+#define CMD_CONDITION_NONE		0
+#define CMD_CONDITION_TRUE		1
+#define CMD_CONDITION_FALSE		2
 #define CMD_CONDITION_TRUE_BLOCK	4
 #define CMD_CONDITION_FALSE_BLOCK	8
-
-float bot_cmd_eval(string expr)
-{
-	// Search for numbers
-	if(strstrofs("0123456789", substring(expr, 0, 1), 0) >= 0)
-	{
-		return stof(expr);
-	}
-
-	// Search for cvars
-	if(substring(expr, 0, 5)=="cvar.")
-	{
-		return cvar(substring(expr, 5, strlen(expr)));
-	}
-
-	// Search for fields
-	switch(expr)
-	{
-		case "health":
-			return self.health;
-		case "speed":
-			return vlen(self.velocity);
-		case "flagcarrier":
-			return ((self.flagcarried!=world));
-	}
-
-	print(strcat("ERROR: Can not convert the expression '",expr,"' into a numeric value\n"));
-	return 0;
-}
 
+float bot_cmd_eval(string expr)
+{
+	// Search for numbers
+	if(strstrofs("0123456789", substring(expr, 0, 1), 0) >= 0)
+	{
+		return stof(expr);
+	}
+
+	// Search for cvars
+	if(substring(expr, 0, 5)=="cvar.")
+	{
+		return cvar(substring(expr, 5, strlen(expr)));
+	}
+
+	// Search for fields
+	switch(expr)
+	{
+		case "health":
+			return self.health;
+		case "speed":
+			return vlen(self.velocity);
+		case "flagcarrier":
+			return ((self.flagcarried!=world));
+	}
+
+	print(strcat("ERROR: Unable to convert the expression '",expr,"' into a numeric value\n"));
+	return 0;
+}
+
 float bot_cmd_if()
 {
 	local string expr, val_a, val_b;
-	local float cmpofs;
+	local float cmpofs;
 
 	if(self.bot_cmd_condition_status != CMD_CONDITION_NONE)
 	{
@@ -476,15 +493,15 @@
 	self.bot_cmd_condition_status |= CMD_CONDITION_TRUE_BLOCK;
 
 	// search for operators
-	expr = bot_cmd_getparm_string();
+	expr = bot_cmd.bot_cmd_parm_string;
 
 	cmpofs = strstrofs(expr,"=",0);
-
+
 	if(cmpofs>0)
 	{
 		val_a = substring(expr,0,cmpofs);
-		val_b = substring(expr,cmpofs+1,strlen(expr));
-
+		val_b = substring(expr,cmpofs+1,strlen(expr));
+
 		if(bot_cmd_eval(val_a)==bot_cmd_eval(val_b))
 			self.bot_cmd_condition_status |= CMD_CONDITION_TRUE;
 		else
@@ -523,13 +540,12 @@
   		return CMD_STATUS_FINISHED;
 	}
 
-
 	if(bot_cmd_eval(expr))
 		self.bot_cmd_condition_status |= CMD_CONDITION_TRUE;
 	else
 		self.bot_cmd_condition_status |= CMD_CONDITION_FALSE;
 
-  	return CMD_STATUS_FINISHED;
+  	return CMD_STATUS_FINISHED;
 }
 
 float bot_cmd_else()
@@ -562,8 +578,8 @@
 	if(self.bot_cmd_aim_endtime)
 	{
 		local float progress;
-
-		progress = min(1 - (self.bot_cmd_aim_endtime - time) / (self.bot_cmd_aim_endtime - self.bot_cmd_aim_begintime),1);
+
+		progress = min(1 - (self.bot_cmd_aim_endtime - time) / (self.bot_cmd_aim_endtime - self.bot_cmd_aim_begintime),1);
 		self.v_angle = self.bot_cmd_aim_begin + ((self.bot_cmd_aim_end - self.bot_cmd_aim_begin) * progress);
 
 		if(time>=self.bot_cmd_aim_endtime)
@@ -579,24 +595,24 @@
 	local string parms;
 	local float tokens, step;
 
-	parms = bot_cmd_getparm_string();
+	parms = bot_cmd.bot_cmd_parm_string;
 
-	tokens = tokenizebyseparator(parms, " ");
-
-	if(tokens==2)
-	{
-		self.v_angle_x -= stof(argv(1));
-		self.v_angle_y += stof(argv(0));
-		return CMD_STATUS_FINISHED;
-	}
-
+	tokens = tokenizebyseparator(parms, " ");
+
+	if(tokens==2)
+	{
+		self.v_angle_x -= stof(argv(1));
+		self.v_angle_y += stof(argv(0));
+		return CMD_STATUS_FINISHED;
+	}
+
 	if(tokens<1||tokens>3)
 		return CMD_STATUS_ERROR;
-
-	step = stof(argv(2));
 
-	self.bot_cmd_aim_begin = self.v_angle;
+	step = stof(argv(2));
 
+	self.bot_cmd_aim_begin = self.v_angle;
+
 	self.bot_cmd_aim_end_x = self.v_angle_x - stof(argv(1));
 	self.bot_cmd_aim_end_y = self.v_angle_y + stof(argv(0));
 	self.bot_cmd_aim_end_z = 0;
@@ -605,235 +621,266 @@
 	self.bot_cmd_aim_endtime = time + step;
 
 	return CMD_STATUS_EXECUTING;
-}
-
-.float bot_cmd_keys;
-
-#define BOT_CMD_KEY_NONE		0
-#define BOT_CMD_KEY_FORWARD 	1
-#define BOT_CMD_KEY_BACKWARD	2
-#define BOT_CMD_KEY_RIGHT		4
-#define BOT_CMD_KEY_LEFT		8
-#define BOT_CMD_KEY_JUMP		16
-#define BOT_CMD_KEY_ATTACK1 	32
-#define BOT_CMD_KEY_ATTACK2 	64
-#define BOT_CMD_KEY_USE			128
-#define BOT_CMD_KEY_HOOK		256
-#define BOT_CMD_KEY_CROUCH		512
-
-float bot_presskeys()
-{
-	self.movement = '0 0 0';
-
-	if(self.bot_cmd_keys == BOT_CMD_KEY_NONE)
-		return FALSE;
-
-	if(self.bot_cmd_keys & BOT_CMD_KEY_FORWARD)
-		self.movement_x = cvar("sv_maxspeed");
-	else if(self.bot_cmd_keys & BOT_CMD_KEY_BACKWARD)
-		self.movement_x = -cvar("sv_maxspeed");
-
-	if(self.bot_cmd_keys & BOT_CMD_KEY_RIGHT)
-		self.movement_y = cvar("sv_maxspeed");
-	else if(self.bot_cmd_keys & BOT_CMD_KEY_LEFT)
-		self.movement_y = -cvar("sv_maxspeed");
-
-	if(self.bot_cmd_keys & BOT_CMD_KEY_JUMP)
-		self.BUTTON_JUMP = TRUE;
-
-	if(self.bot_cmd_keys & BOT_CMD_KEY_CROUCH)
-		self.BUTTON_CROUCH = TRUE;
-
-	if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK1)
-		self.BUTTON_ATCK = TRUE;
-
-	if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK2)
-		self.BUTTON_ATCK2 = TRUE;
-
-	if(self.bot_cmd_keys & BOT_CMD_KEY_USE)
-		self.BUTTON_USE = TRUE;
-
-	return TRUE;
-}
-
-
-float bot_cmd_keypress_handler(string key, float enabled)
-{
-	switch(key)
-	{
+}
+
+.float bot_cmd_keys;
+
+#define BOT_CMD_KEY_NONE	0
+#define BOT_CMD_KEY_FORWARD 	1
+#define BOT_CMD_KEY_BACKWARD	2
+#define BOT_CMD_KEY_RIGHT	4
+#define BOT_CMD_KEY_LEFT	8
+#define BOT_CMD_KEY_JUMP	16
+#define BOT_CMD_KEY_ATTACK1 	32
+#define BOT_CMD_KEY_ATTACK2 	64
+#define BOT_CMD_KEY_USE		128
+#define BOT_CMD_KEY_HOOK	256
+#define BOT_CMD_KEY_CROUCH	512
+
+float bot_presskeys()
+{
+	self.movement = '0 0 0';
+
+	if(self.bot_cmd_keys == BOT_CMD_KEY_NONE)
+		return FALSE;
+
+	if(self.bot_cmd_keys & BOT_CMD_KEY_FORWARD)
+		self.movement_x = cvar("sv_maxspeed");
+	else if(self.bot_cmd_keys & BOT_CMD_KEY_BACKWARD)
+		self.movement_x = -cvar("sv_maxspeed");
+
+	if(self.bot_cmd_keys & BOT_CMD_KEY_RIGHT)
+		self.movement_y = cvar("sv_maxspeed");
+	else if(self.bot_cmd_keys & BOT_CMD_KEY_LEFT)
+		self.movement_y = -cvar("sv_maxspeed");
+
+	if(self.bot_cmd_keys & BOT_CMD_KEY_JUMP)
+		self.BUTTON_JUMP = TRUE;
+
+	if(self.bot_cmd_keys & BOT_CMD_KEY_CROUCH)
+		self.BUTTON_CROUCH = TRUE;
+
+	if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK1)
+		self.BUTTON_ATCK = TRUE;
+
+	if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK2)
+		self.BUTTON_ATCK2 = TRUE;
+
+	if(self.bot_cmd_keys & BOT_CMD_KEY_USE)
+		self.BUTTON_USE = TRUE;
+
+	return TRUE;
+}
+
+
+float bot_cmd_keypress_handler(string key, float enabled)
+{
+	switch(key)
+	{
 		case "all":
 			if(enabled)
-				self.bot_cmd_keys = power2of(20) - 1; // >:)
+				self.bot_cmd_keys = power2of(20) - 1; // >:)
 			else
 				self.bot_cmd_keys = BOT_CMD_KEY_NONE;
-		case "forward":
-			if(enabled)
-			{
-				self.bot_cmd_keys |= BOT_CMD_KEY_FORWARD;
-				self.bot_cmd_keys &~= BOT_CMD_KEY_BACKWARD;
-			}
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_FORWARD;
-			break;
-		case "backward":
-			if(enabled)
-			{
-				self.bot_cmd_keys |= BOT_CMD_KEY_BACKWARD;
-				self.bot_cmd_keys &~= BOT_CMD_KEY_FORWARD;
-			}
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_BACKWARD;
-			break;
-		case "left":
-			if(enabled)
-			{
-				self.bot_cmd_keys |= BOT_CMD_KEY_LEFT;
-				self.bot_cmd_keys &~= BOT_CMD_KEY_RIGHT;
-			}
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_LEFT;
-			break;
-		case "right":
-			if(enabled)
-			{
-				self.bot_cmd_keys |= BOT_CMD_KEY_RIGHT;
-				self.bot_cmd_keys &~= BOT_CMD_KEY_LEFT;
-			}
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_RIGHT;
-			break;
-		case "jump":
-			if(enabled)
-				self.bot_cmd_keys |= BOT_CMD_KEY_JUMP;
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_JUMP;
-			break;
-		case "crouch":
-			if(enabled)
-				self.bot_cmd_keys |= BOT_CMD_KEY_CROUCH;
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_CROUCH;
-			break;
-		case "attack1":
-			if(enabled)
-				self.bot_cmd_keys |= BOT_CMD_KEY_ATTACK1;
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_ATTACK1;
-			break;
-		case "attack2":
-			if(enabled)
-				self.bot_cmd_keys |= BOT_CMD_KEY_ATTACK2;
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_ATTACK2;
-			break;
-		case "use":
-			if(enabled)
-				self.bot_cmd_keys |= BOT_CMD_KEY_USE;
-			else
-				self.bot_cmd_keys &~= BOT_CMD_KEY_USE;
-			break;
-		default:
-			break;
-	}
-
-	return CMD_STATUS_FINISHED;
-}
-
-float bot_cmd_presskey()
-{
-	local string key;
-
-	key = bot_cmd_getparm_string();
-
-	bot_cmd_keypress_handler(key,TRUE);
-
-	return CMD_STATUS_FINISHED;
-}
-
-float bot_cmd_releasekey()
-{
-	local string key;
-
-	key = bot_cmd_getparm_string();
-
-	return bot_cmd_keypress_handler(key,FALSE);
-}
-
-float bot_cmd_pause()
-{
-	self.button1        = 0;
-	self.button8        = 0;
-	self.BUTTON_USE     = 0;
-	self.BUTTON_ATCK    = 0;
-	self.BUTTON_JUMP    = 0;
-	self.BUTTON_HOOK    = 0;
-	self.BUTTON_CHAT    = 0;
-	self.BUTTON_ATCK2   = 0;
-	self.BUTTON_CROUCH  = 0;
-
-	self.movement = '0 0 0';
-	self.bot_cmd_keys = BOT_CMD_KEY_NONE;
-
-	self.bot_exec_status = self.bot_exec_status | BOT_EXEC_STATUS_PAUSED;
-	return CMD_STATUS_FINISHED;
-}
-
-void bot_command_executed()
-{
-	local float index;
-	index = self.bot_cmd_execution_index;
-
-	self.(bot_cmd[index])=BOT_CMD_NULL;
-
-	if(index==BOT_CMD_QUEUE_SIZE-1)
-		self.bot_cmd_execution_index = 0;
-	else
-		self.bot_cmd_execution_index += 1;
-}
+		case "forward":
+			if(enabled)
+			{
+				self.bot_cmd_keys |= BOT_CMD_KEY_FORWARD;
+				self.bot_cmd_keys &~= BOT_CMD_KEY_BACKWARD;
+			}
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_FORWARD;
+			break;
+		case "backward":
+			if(enabled)
+			{
+				self.bot_cmd_keys |= BOT_CMD_KEY_BACKWARD;
+				self.bot_cmd_keys &~= BOT_CMD_KEY_FORWARD;
+			}
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_BACKWARD;
+			break;
+		case "left":
+			if(enabled)
+			{
+				self.bot_cmd_keys |= BOT_CMD_KEY_LEFT;
+				self.bot_cmd_keys &~= BOT_CMD_KEY_RIGHT;
+			}
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_LEFT;
+			break;
+		case "right":
+			if(enabled)
+			{
+				self.bot_cmd_keys |= BOT_CMD_KEY_RIGHT;
+				self.bot_cmd_keys &~= BOT_CMD_KEY_LEFT;
+			}
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_RIGHT;
+			break;
+		case "jump":
+			if(enabled)
+				self.bot_cmd_keys |= BOT_CMD_KEY_JUMP;
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_JUMP;
+			break;
+		case "crouch":
+			if(enabled)
+				self.bot_cmd_keys |= BOT_CMD_KEY_CROUCH;
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_CROUCH;
+			break;
+		case "attack1":
+			if(enabled)
+				self.bot_cmd_keys |= BOT_CMD_KEY_ATTACK1;
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_ATTACK1;
+			break;
+		case "attack2":
+			if(enabled)
+				self.bot_cmd_keys |= BOT_CMD_KEY_ATTACK2;
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_ATTACK2;
+			break;
+		case "use":
+			if(enabled)
+				self.bot_cmd_keys |= BOT_CMD_KEY_USE;
+			else
+				self.bot_cmd_keys &~= BOT_CMD_KEY_USE;
+			break;
+		default:
+			break;
+	}
 
+	return CMD_STATUS_FINISHED;
+}
+
+float bot_cmd_presskey()
+{
+	local string key;
+
+	key = bot_cmd.bot_cmd_parm_string;
+
+	bot_cmd_keypress_handler(key,TRUE);
+
+	return CMD_STATUS_FINISHED;
+}
+
+float bot_cmd_releasekey()
+{
+	local string key;
+
+	key = bot_cmd.bot_cmd_parm_string;
+
+	return bot_cmd_keypress_handler(key,FALSE);
+}
+
+float bot_cmd_pause()
+{
+	self.button1        = 0;
+	self.button8        = 0;
+	self.BUTTON_USE     = 0;
+	self.BUTTON_ATCK    = 0;
+	self.BUTTON_JUMP    = 0;
+	self.BUTTON_HOOK    = 0;
+	self.BUTTON_CHAT    = 0;
+	self.BUTTON_ATCK2   = 0;
+	self.BUTTON_CROUCH  = 0;
+
+	self.movement = '0 0 0';
+	self.bot_cmd_keys = BOT_CMD_KEY_NONE;
+
+	self.bot_exec_status = self.bot_exec_status | BOT_EXEC_STATUS_PAUSED;
+	return CMD_STATUS_FINISHED;
+}
+
+void bot_command_executed(float rm)
+{
+	entity cmd;
+
+	cmd = bot_cmd;
+
+	self.bot_cmd_execution_index++;
+
+	if(rm)
+	{
+		if(bot_cmd_parm_type[cmd.bot_cmd_type]==BOT_CMD_PARAMETER_STRING)
+		{
+			strunzone(cmd.bot_cmd_parm_string);
+		}
+		remove(cmd);
+		return;
+	}
+
+	cmd.bot_cmd_execution_counter++;
+}
+
+void bot_setcurrentcommand()
+{
+	entity cmd;
+
+	bot_cmd = world;
+
+	if(self.bot_cmd_execution_index==0)
+		self.bot_cmd_execution_index=1;
+
+	for (cmd = findchainfloat(bot_cmd_index, self.bot_cmd_execution_index); cmd; cmd = cmd.chain)
+	{
+		if(cmd.owner==self)
+		{
+			bot_cmd = cmd;
+			return;
+		}
+	}
+}
+
 // This function should be (the only) called directly from the bot ai loop
 // It maps commands to functions and deal with complex interactions between commands and execution states
-// NOTE: Of course you need to include your command here too :)
+// NOTE: Of course you need to include your commands here too :)
 float bot_execute_commands()
 {
-	local float cmd, status, index, ispressingkey;
+	local float status, index, ispressingkey;
+	local entity cmd;
 
-	index = self.bot_cmd_execution_index;
-
-	// Keep pressing keys raised by the "presskey" command
-	ispressingkey = bot_presskeys();
+	// Find command
+	bot_setcurrentcommand();
 
+	// Keep pressing keys raised by the "presskey" command
+	ispressingkey = bot_presskeys();
+
+	if(bot_cmd==world)
+		return ispressingkey;
+
 	// Ignore all commands except continue when the bot is paused
 	if(self.bot_exec_status & BOT_EXEC_STATUS_PAUSED)
-	if(self.bot_cmd[index]!=BOT_CMD_CONTINUE)
+	if(bot_cmd.bot_cmd_type!=BOT_CMD_CONTINUE)
 	{
-		if(self.bot_cmd[index]!=BOT_CMD_NULL)
+		if(bot_cmd.bot_cmd_type!=BOT_CMD_NULL)
 		{
-			bot_command_executed();
+			bot_command_executed(TRUE);
 			print( "WARNING: Commands are ignored while the bot is paused. Use the command 'continue' instead.\n");
 		}
 		return TRUE;
 	}
-
-	// Handle conditions
-	if not(self.bot_cmd[index]==BOT_CMD_FI||self.bot_cmd[index]==BOT_CMD_ELSE)
+
+	// Handle conditions
+	if not(bot_cmd.bot_cmd_type==BOT_CMD_FI||bot_cmd.bot_cmd_type==BOT_CMD_ELSE)
 	if(self.bot_cmd_condition_status & CMD_CONDITION_TRUE && self.bot_cmd_condition_status & CMD_CONDITION_FALSE_BLOCK)
 	{
-		bot_command_executed();
+		bot_command_executed(TRUE);
 		return TRUE;
 	}
 	else if(self.bot_cmd_condition_status & CMD_CONDITION_FALSE && self.bot_cmd_condition_status & CMD_CONDITION_TRUE_BLOCK)
 	{
-		bot_command_executed();
+		bot_command_executed(TRUE);
 		return TRUE;
 	}
 
-	// Map commands to functions
-	cmd = self.bot_cmd[index];
-	switch(cmd)
+	// Map commands to functions
+	switch(bot_cmd.bot_cmd_type)
 	{
 		case BOT_CMD_NULL:
-			return ispressingkey;
+			return ispressingkey;
 			break;
 		case BOT_CMD_PAUSE:
 			status = bot_cmd_pause();
@@ -851,12 +898,12 @@
 		//	status = bot.bot_cmd_moveto();
 			status = CMD_STATUS_FINISHED;
 			break;
-		case BOT_CMD_RESETGOAL:
+		case BOT_CMD_RESETGOAL:
 		//	status = bot.cmd_resetgoal();
 			status = CMD_STATUS_FINISHED;
 			break;
-		case BOT_CMD_CC:
-			status = bot_cmd_raw();
+		case BOT_CMD_CC:
+			status = bot_cmd_cc();
 			break;
 		case BOT_CMD_IF:
 			status = bot_cmd_if();
@@ -873,54 +920,53 @@
 		case BOT_CMD_AIM:
 			status = bot_cmd_aim();
 			break;
-		case BOT_CMD_PRESSKEY:
-			status = bot_cmd_presskey();
-			break;
-		case BOT_CMD_RELEASEKEY:
-			status = bot_cmd_releasekey();
-			break;
-		case BOT_CMD_SELECTWEAPON:
-			status = bot_cmd_select_weapon();
-			break;
+		case BOT_CMD_PRESSKEY:
+			status = bot_cmd_presskey();
+			break;
+		case BOT_CMD_RELEASEKEY:
+			status = bot_cmd_releasekey();
+			break;
+		case BOT_CMD_SELECTWEAPON:
+			status = bot_cmd_select_weapon();
+			break;
 		case BOT_CMD_IMPULSE:
 			status = bot_cmd_impulse();
 			break;
-		default:
-			print(strcat("ERROR: Invalid command on queue with id '",ftos(cmd),"'\n"));
-			self.(bot_cmd[index]) = BOT_CMD_NULL;
-			return TRUE;
+		default:
+			print(strcat("ERROR: Invalid command on queue with id '",ftos(bot_cmd.bot_cmd_type),"'\n"));
+			return FALSE;
 	}
-
-	if (status==CMD_STATUS_ERROR)
-		print(strcat("ERROR: The command '",bot_cmd_string[cmd],"' returned an error status\n"));
 
-	// Move execution pointer
-	if not(status==CMD_STATUS_EXECUTING)
-	{
-		if(cvar("g_debug_bot_commands"))
-		{
-			local string parms;
-
-			switch(bot_cmd_parm_type[cmd])
-			{
-				case BOT_CMD_PARAMETER_FLOAT:
-					parms = ftos(bot_cmd_getparm_float());
-					break;
-				case BOT_CMD_PARAMETER_STRING:
-					parms = bot_cmd_getparm_string();
-					break;
-				case BOT_CMD_PARAMETER_VECTOR:
-					parms = vtos(bot_cmd_getparm_vector());
-					break;
-				default:
-					parms = "";
-					break;
-			}
-			clientcommand(self,strcat("say ^7", bot_cmd_string[cmd]," ",parms,"\n"));
-		}
-
-		bot_command_executed();
+	if (status==CMD_STATUS_ERROR)
+		print(strcat("ERROR: The command '",bot_cmd_string[bot_cmd.bot_cmd_type],"' returned an error status\n"));
+
+	// Move execution pointer
+	if not(status==CMD_STATUS_EXECUTING)
+	{
+		if(cvar("g_debug_bot_commands"))
+		{
+			local string parms;
+
+			switch(bot_cmd_parm_type[bot_cmd.bot_cmd_type])
+			{
+				case BOT_CMD_PARAMETER_FLOAT:
+					parms = ftos(bot_cmd.bot_cmd_parm_float);
+					break;
+				case BOT_CMD_PARAMETER_STRING:
+					parms = bot_cmd.bot_cmd_parm_string;
+					break;
+				case BOT_CMD_PARAMETER_VECTOR:
+					parms = vtos(bot_cmd.bot_cmd_parm_vector);
+					break;
+				default:
+					parms = "";
+					break;
+			}
+			clientcommand(self,strcat("say ^7", bot_cmd_string[bot_cmd.bot_cmd_type]," ",parms,"\n"));
+		}
+
+		bot_command_executed(TRUE);
 	}
-
+
 	return TRUE;
-}
+}



More information about the nexuiz-commits mailing list