23 if(!bot.bot_cmdqueuebuf_allocated)
25 buf_del(bot.bot_cmdqueuebuf);
26 bot.bot_cmdqueuebuf_allocated =
false;
27 LOG_TRACE(
"bot ", bot.netname,
" queue cleared");
32 if(!bot.bot_cmdqueuebuf_allocated)
35 bot.bot_cmdqueuebuf_allocated =
true;
36 bot.bot_cmdqueuebuf_start = 0;
37 bot.bot_cmdqueuebuf_end = 0;
40 bufstr_set(bot.bot_cmdqueuebuf, bot.bot_cmdqueuebuf_end, cmdstring);
69 bot.bot_cmdqueuebuf_end += 1;
74 if(!bot.bot_cmdqueuebuf_allocated)
75 error(
"dequeuecommand but no queue allocated");
76 if(idx < bot.bot_cmdqueuebuf_start)
77 error(
"dequeueing a command in the past");
78 if(idx >= bot.bot_cmdqueuebuf_end)
79 error(
"dequeueing a command in the future");
80 bufstr_set(bot.bot_cmdqueuebuf, idx,
"");
81 if(idx == bot.bot_cmdqueuebuf_start)
82 bot.bot_cmdqueuebuf_start += 1;
83 if(bot.bot_cmdqueuebuf_start >= bot.bot_cmdqueuebuf_end)
89 if(!bot.bot_cmdqueuebuf_allocated)
90 error(
"readcommand but no queue allocated");
91 if(idx < bot.bot_cmdqueuebuf_start)
92 error(
"reading a command in the past");
93 if(idx >= bot.bot_cmdqueuebuf_end)
94 error(
"reading a command in the future");
95 return bufstr_get(bot.bot_cmdqueuebuf, idx);
141 this.bot_places_count += 1;
149 LOG_INFO(
"invalid place ", placename);
298 LOG_INFO(
"ERROR: A parameter is required for this command");
306 switch(cmd_parm_type)
317 LOG_INFOF(
"ERROR: expected vector type \'x y z\', got %s", parm);
327 LOG_INFO(
"ERROR: No such command '", cmdstring,
"'");
366 desc =
"Stops the bot completely. Any command other than 'continue' will be ignored.";
369 desc =
"Disable paused status";
372 desc =
"Pause command parsing and bot ai for N seconds. Pressed key will remain pressed";
375 desc =
"Pause command parsing and bot ai until time is N from the last barrier. Pressed key will remain pressed";
378 desc =
"Waits till all bots that have a command queue reach this command. Pressed key will remain pressed";
381 desc =
"Look to the right or left N degrees. For turning to the left use positive numbers.";
384 desc =
"Walk to an specific coordinate on the map. Usage: moveto \'x y z\'";
387 desc =
"Walk to the specific target on the map";
390 desc =
"Resets the goal stack";
393 desc =
"Execute client command. Examples: cc say something; cc god; cc name newnickname; cc kill;";
396 desc =
"Perform simple conditional execution.\n"
398 " sv_cmd .. if \"condition\"\n"
399 " sv_cmd .. <instruction if true>\n"
400 " sv_cmd .. <instruction if true>\n"
402 " sv_cmd .. <instruction if false>\n"
403 " sv_cmd .. <instruction if false>\n"
405 "Conditions: a=b, a>b, a<b, a\t\t(spaces not allowed)\n"
406 " Values in conditions can be numbers, cvars in the form cvar.cvar_string or special fields\n"
407 "Fields: health, speed, flagcarrier\n"
408 "Examples: if health>50; if health>cvar.g_balance_laser_primary_damage; if flagcarrier;";
411 desc =
"Points the aim to the coordinates x,y 0,0";
414 desc =
"Move the aim x/y (horizontal/vertical) degrees relatives to the bot\n"
415 "There is a 3rd optional parameter telling in how many seconds the aim has to reach the new position\n"
416 "Examples: aim \"90 0\" // Turn 90 degrees inmediately (positive numbers move to the left/up)\n"
417 " aim \"0 90 2\" // Will gradually look to the sky in the next two seconds";
420 desc =
"Points the aim to given target";
423 desc =
"Press one of the following keys: forward, backward, left, right, jump, crouch, attack1, attack2, use"
424 "Multiple keys can be pressed at time (with many presskey calls) and it will remain pressed until the command \"releasekey\" is called"
425 "Note: The script will not return the control to the bot ai until all keys are released";
428 desc =
"Release previoulsy used keys. Use the parameter \"all\" to release all keys";
431 desc =
"play sound file at bot location";
434 desc =
"verify the state of the weapon entity";
437 desc =
"This command has no description yet.";
476 LOG_HELP(
"For help about a specific command, type bot_cmd help <command>");
490 CS(
this).impulse =
bot_cmd.bot_cmd_parm_float;
545 if(it.bot_cmdqueuebuf_allocated)
546 if(it.bot_barrier != 1)
547 return CMD_STATUS_EXECUTING;
575 float id =
bot_cmd.bot_cmd_parm_float;
580 bool success =
false;
585 if(this.(weaponentity).
m_weapon == WEP_Null && slot != 0)
631 LOG_INFO(
"ERROR: Unable to convert the expression '", expr,
"' into a numeric value");
637 string expr, val_a, val_b;
643 LOG_INFO(
"ERROR: Only one conditional block can be processed at time");
651 expr =
bot_cmd.bot_cmd_parm_string;
753 parms =
bot_cmd.bot_cmd_parm_string;
757 if(tokens<2||tokens>3)
760 step = (tokens == 3) ?
stof(
argv(2)) : 0;
773 this.bot_cmd_aim_end_z = 0;
793 parms =
bot_cmd.bot_cmd_parm_string;
801 v = e.origin + (e.mins + e.maxs) * 0.5;
806 this.v_angle_x = -this.
v_angle.x;
810 if(tokens<1||tokens>2)
842 CS(
this).movement =
'0 0 0';
987 key =
bot_cmd.bot_cmd_parm_string;
998 key =
bot_cmd.bot_cmd_parm_string;
1019 CS(
this).movement =
'0 0 0';
1029 return this.cmd_moveto(
this,
bot_cmd.bot_cmd_parm_vector);
1038 return this.cmd_moveto(
this, e.origin + (e.mins + e.maxs) * 0.5);
1043 return this.cmd_resetgoal(
this);
1050 f =
bot_cmd.bot_cmd_parm_string;
1060 sample =
argv(n - 1);
1077 float f =
bot_cmd.bot_cmd_parm_float;
1086 LOG_INFO(
"Bot ", this.
netname,
" using ", this.(weaponentity).
weaponname,
" wants to fire, inhibited by weaponentity state");
1102 LOG_INFO(
"Bot ", this.
netname,
" using ", this.(weaponentity).
weaponname,
" wants to fire, bot still has an active tuba note");
1141 if(
bot_cmd.bot_cmd_index !=
this.bot_cmd_execution_index ||
this.bot_cmd_execution_index == 0)
1168 it.bot_cmd_execution_index = 0;
1172 for(int i = 0; i < it.bot_places_count; ++i)
1174 strfree(it.(bot_placenames[i]));
1176 it.bot_places_count = 0;
1186 float status, ispressingkey;
1206 LOG_INFO(
"WARNING: Commands are ignored while the bot is paused. Use the command 'continue' instead.");
1231 return ispressingkey;
1328 parms =
bot_cmd.bot_cmd_parm_string;
void bot_relinkplayerlist()
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
#define PHYS_INPUT_BUTTON_CROUCH(s)
#define PHYS_INPUT_BUTTON_JUMP(s)
#define PHYS_INPUT_BUTTON_HOOK(s)
#define PHYS_INPUT_BUTTON_CHAT(s)
float autocvar_sv_maxspeed
#define PHYS_INPUT_BUTTON_USE(s)
#define PHYS_INPUT_BUTTON_ATCK(s)
#define PHYS_INPUT_BUTTON_ATCK2(s)
#define PHYS_INPUT_BUTTON_DRAG(s)
bool autocvar_g_debug_bot_commands
#define tokenizebyseparator
#define SV_ParseClientCommand
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1points s1 s2
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define new_pure(class)
purely logical entities (not linked to the area grid)
#define REGISTRY_GET(id, i)
float bot_cmd_eval(entity this, string expr)
const int BOT_CMD_KEY_ATTACK2
float bot_cmd_keypress_handler(entity this, string key, float enabled)
float bot_cmd_sound(entity this)
entity find_bot_by_number(float number)
void bot_setcurrentcommand(entity this)
float bot_cmd_fi(entity this)
float bot_cmd_resetaim(entity this)
float bot_cmd_barrier(entity this)
const int BOT_CMD_KEY_RIGHT
float bot_cmd_turn(entity this)
entity find_bot_by_name(string name)
float bot_cmdqueuebuf_start
float bot_cmd_wait(entity this)
const int BOT_CMD_KEY_ATTACK1
const int BOT_CMD_KEY_BACKWARD
void bot_queuecommand(entity bot, string cmdstring)
bool bot_havecommand(entity this, int idx)
float bot_cmd_aim(entity this)
float bot_cmd_movetotarget(entity this)
float bot_cmd_aimtarget(entity this)
const int CMD_CONDITION_true_BLOCK
void bot_cmdhelp(string scmd)
const int CMD_CONDITION_true
void bot_clearqueue(entity bot)
const int CMD_CONDITION_false_BLOCK
const int CMD_CONDITION_false
float bot_cmd_presskey(entity this)
entity bot_getplace(entity this, string placename)
float bot_cmd_resetgoal(entity this)
entity bot_places[MAX_BOT_PLACES]
float bot_cmd_wait_until(entity this)
const int BOT_CMD_KEY_CROUCH
float bot_cmd_continue(entity this)
float bot_cmdqueuebuf_end
const int BOT_CMD_KEY_FORWARD
float bot_cmd_moveto(entity this)
float bot_cmd_select_weapon(entity this)
float bot_cmd_debug_assert_canfire(entity this)
string bot_placenames[MAX_BOT_PLACES]
float bot_cmd_cc(entity this)
string bot_readcommand(entity bot, float idx)
float bot_cmd_if(entity this)
float bot_execute_commands_once(entity this)
const int BOT_CMD_KEY_HOOK
const int CMD_CONDITION_NONE
const int BOT_CMD_KEY_CHAT
bool bot_presskeys(entity this)
float bot_cmd_releasekey(entity this)
bool bot_ispaused(entity this)
const int BOT_CMD_KEY_JUMP
const int BOT_CMD_KEY_NONE
float bot_cmd_else(entity this)
int bot_execute_commands(entity this)
float bot_cmd_pause(entity this)
int bot_cmd_condition_status
const int BOT_CMD_KEY_LEFT
const int BOT_CMD_KEY_USE
float bot_decodecommand(string cmdstring)
void bot_command_executed(entity this, bool rm)
float bot_cmd_aim_endtime
float bot_cmd_impulse(entity this)
float bot_cmd_aim_begintime
void bot_dequeuecommand(entity bot, float idx)
float bot_cmdqueuebuf_allocated
const int BOT_CMD_AIMTARGET
const int BOT_CMD_PARAMETER_FLOAT
const int BOT_CMD_PARAMETER_NONE
const int BOT_CMD_PRESSKEY
#define BOT_EXEC_STATUS_PAUSED
const int BOT_CMD_WAIT_UNTIL
#define BOT_EXEC_STATUS_WAITING
const int BOT_CMD_CONSOLE
const int BOT_CMD_DEBUG_ASSERT_CANFIRE
#define CMD_STATUS_FINISHED
string bot_cmd_string[BOT_CMD_COUNTER]
#define CMD_STATUS_EXECUTING
const int BOT_CMD_RELEASEKEY
const int BOT_CMD_MOVETOTARGET
const int BOT_CMD_CONTINUE
const int BOT_CMD_SELECTWEAPON
const int BOT_CMD_PARAMETER_VECTOR
const int BOT_CMD_COUNTER
const int BOT_CMD_PARAMETER_STRING
const int BOT_CMD_IMPULSE
const int BOT_CMD_BARRIER
int bot_cmd_parm_type[BOT_CMD_COUNTER]
const int BOT_CMD_RESETGOAL
const int BOT_CMD_RESETAIM
float bot_cmds_initialized
float bot_cmd_execution_index
bool client_hasweapon(entity this, Weapon wpn,.entity weaponentity, float andammo, bool complain)
#define _sound(e, c, s, v, a)
ClientState CS(Client this)
#define FOREACH_CLIENT(cond, body)
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
const int MAX_WEAPONSLOTS
const int WS_READY
idle frame
entity weaponentities[MAX_WEAPONSLOTS]
#define ATTACK_FINISHED(ent, w)