#include "havocbot.qh"
-#include "role_onslaught.qc"
-#include "role_keyhunt.qc"
-#include "roles.qc"
+#include "../../_all.qh"
+
+#include "../aim.qh"
+#include "../bot.qh"
+#include "../navigation.qh"
+#include "../scripting.qh"
+#include "../waypoints.qh"
+
+#include "../../../common/constants.qh"
+
+#include "../../../common/triggers/trigger/jumppads.qh"
+
+#include "../../../warpzonelib/common.qh"
void havocbot_ai()
-{
+{SELFPARAM();
if(self.draggedby)
return;
//dprint(vtos(now), ":", vtos(next), "=", vtos(v), " (blend ", ftos(blend), ")\n");
//v = now * (distanceblend) + next * (1-distanceblend);
if (self.waterlevel < WATERLEVEL_SWIMMING)
- v_z = 0;
+ v.z = 0;
//dprint("walk at:", vtos(v), "\n");
//te_lightning2(world, self.origin, self.goalcurrent.origin);
bot_aimdir(v, -1);
// if the bot is not attacking, consider reloading weapons
if (!(self.aistatus & AI_STATUS_ATTACKING))
{
- float i;
- entity e;
-
// we are currently holding a weapon that's not fully loaded, reload it
if(skill >= 2) // bots can only reload the held weapon on purpose past this skill
if(self.clip_load < self.clip_size)
if(skill >= 5) // bots can only look for unloaded weapons past this skill
if(self.clip_load >= 0) // only if we're not reloading a weapon already
{
- for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ for (int i = WEP_FIRST; i <= WEP_LAST; ++i)
{
- e = get_weaponinfo(i);
+ entity e = get_weaponinfo(i);
if ((self.weapons & WepSet_FromWeapon(i)) && (e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < e.reloading_ammo))
self.switchweapon = i;
}
}
void havocbot_keyboard_movement(vector destorg)
-{
+{SELFPARAM();
vector keyboard;
float blend, maxspeed;
float sk;
// at skill >= 4.5, all cases allowed
if (keyboard.x > trigger)
{
- keyboard_x = 1;
+ keyboard.x = 1;
if (sk < 2.5)
- keyboard_y = 0;
+ keyboard.y = 0;
}
else if (keyboard.x < trigger1 && sk > 1.5)
{
- keyboard_x = -1;
+ keyboard.x = -1;
if (sk < 4.5)
- keyboard_y = 0;
+ keyboard.y = 0;
}
else
{
- keyboard_x = 0;
+ keyboard.x = 0;
if (sk < 1.5)
- keyboard_y = 0;
+ keyboard.y = 0;
}
if (sk < 4.5)
- keyboard_z = 0;
+ keyboard.z = 0;
if (keyboard.y > trigger)
- keyboard_y = 1;
+ keyboard.y = 1;
else if (keyboard.y < trigger1)
- keyboard_y = -1;
+ keyboard.y = -1;
else
- keyboard_y = 0;
+ keyboard.y = 0;
if (keyboard.z > trigger)
- keyboard_z = 1;
+ keyboard.z = 1;
else if (keyboard.z < trigger1)
- keyboard_z = -1;
+ keyboard.z = -1;
else
- keyboard_z = 0;
+ keyboard.z = 0;
self.havocbot_keyboard = keyboard * maxspeed;
if (self.havocbot_ducktime>time) self.BUTTON_CROUCH=true;
}
void havocbot_bunnyhop(vector dir)
-{
+{SELFPARAM();
float bunnyhopdistance;
vector deviation;
float maxspeed;
{
gno = (self.goalstack01.absmin + self.goalstack01.absmax) * 0.5;
deviation = vectoangles(gno - self.origin) - vectoangles(gco - self.origin);
- while (deviation.y < -180) deviation_y = deviation.y + 360;
- while (deviation.y > 180) deviation_y = deviation.y - 360;
+ while (deviation.y < -180) deviation.y = deviation.y + 360;
+ while (deviation.y > 180) deviation.y = deviation.y - 360;
if(fabs(deviation.y) < 20)
if(bunnyhopdistance < vlen(self.origin - gno))
if(vlen(self.velocity)>maxspeed)
{
deviation = vectoangles(dir) - vectoangles(self.velocity);
- while (deviation.y < -180) deviation_y = deviation.y + 360;
- while (deviation.y > 180) deviation_y = deviation.y - 360;
+ while (deviation.y < -180) deviation.y = deviation.y + 360;
+ while (deviation.y > 180) deviation.y = deviation.y - 360;
if(fabs(deviation.y)>10)
self.movement_x = 0;
}
void havocbot_movetogoal()
-{
+{SELFPARAM();
vector destorg;
vector diff;
vector dir;
float db, v, d;
vector dxy;
- dxy = self.origin - ( ( self.goalcurrent.absmin + self.goalcurrent.absmax ) * 0.5 ); dxy_z = 0;
+ dxy = self.origin - ( ( self.goalcurrent.absmin + self.goalcurrent.absmax ) * 0.5 ); dxy.z = 0;
d = vlen(dxy);
v = vlen(self.velocity - self.velocity.z * '0 0 1');
db = (pow(v,2) / (autocvar_g_jetpack_acceleration_side * 2)) + 100;
// Flying
self.BUTTON_HOOK = true;
- if(self.navigation_jetpack_point.z - PL_MAX_z + PL_MIN_z < self.origin.z)
+ if(self.navigation_jetpack_point.z - PL_MAX.z + PL_MIN.z < self.origin.z)
{
self.movement_x = dir * v_forward * maxspeed;
self.movement_y = dir * v_right * maxspeed;
threshold = maxspeed * 0.2;
if(sxy < threshold)
{
- dprint("Warning: ", self.netname, " got stuck on a jumppad (velocity in xy is ", ftos(sxy), "), trying to get out of it now\n");
+ LOG_TRACE("Warning: ", self.netname, " got stuck on a jumppad (velocity in xy is ", ftos(sxy), "), trying to get out of it now\n");
self.aistatus |= AI_STATUS_OUT_JUMPPAD;
}
return;
else if(self.health>WEP_CVAR(devastator, damage)*0.5)
{
if(self.velocity.z < 0)
- if(client_hasweapon(self, WEP_DEVASTATOR, true, false))
+ if(client_hasweapon(self, WEP_DEVASTATOR.m_id, true, false))
{
self.movement_x = maxspeed;
return;
}
- self.switchweapon = WEP_DEVASTATOR;
+ self.switchweapon = WEP_DEVASTATOR.m_id;
self.v_angle_x = 90;
self.BUTTON_ATCK = true;
self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
{
dir = '0 0 0';
if(self.waterlevel>WATERLEVEL_SWIMMING)
- dir_z = 1;
+ dir.z = 1;
else if(self.velocity.z >= 0 && !(self.waterlevel == WATERLEVEL_WETFEET && self.watertype == CONTENT_WATER))
self.BUTTON_JUMP = true;
else
m1 = self.goalcurrent.origin + self.goalcurrent.mins;
m2 = self.goalcurrent.origin + self.goalcurrent.maxs;
destorg = self.origin;
- destorg_x = bound(m1_x, destorg.x, m2_x);
- destorg_y = bound(m1_y, destorg.y, m2_y);
- destorg_z = bound(m1_z, destorg.z, m2_z);
+ destorg.x = bound(m1_x, destorg.x, m2_x);
+ destorg.y = bound(m1_y, destorg.y, m2_y);
+ destorg.z = bound(m1_z, destorg.z, m2_z);
diff = destorg - self.origin;
//dist = vlen(diff);
dir = normalize(diff);
- flatdir = diff;flatdir_z = 0;
+ flatdir = diff;flatdir.z = 0;
flatdir = normalize(flatdir);
gco = (self.goalcurrent.absmin + self.goalcurrent.absmax) * 0.5;
if(tracebox_hits_trigger_hurt(dst_ahead, self.mins, self.maxs, trace_endpos))
{
// Remove dangerous dynamic goals from stack
- dprint("bot ", self.netname, " avoided the goal ", self.goalcurrent.classname, " ", etos(self.goalcurrent), " because it led to a dangerous path; goal stack cleared\n");
+ LOG_TRACE("bot ", self.netname, " avoided the goal ", self.goalcurrent.classname, " ", etos(self.goalcurrent), " because it led to a dangerous path; goal stack cleared\n");
navigation_clearroute();
return;
}
}
dir = flatdir;
- evadeobstacle_z = 0;
- evadelava_z = 0;
+ evadeobstacle.z = 0;
+ evadelava.z = 0;
makevectors(self.v_angle.y * '0 1 0');
if(evadeobstacle!='0 0 0'||evadelava!='0 0 0')
if(self.goalcurrent.origin.z + self.goalcurrent.mins.z > self.origin.z + self.mins.z)
{
if(self.origin.z + self.mins.z < self.ladder_entity.origin.z + self.ladder_entity.maxs.z)
- dir_z = 1;
+ dir.z = 1;
}
else
{
if(self.origin.z + self.mins.z > self.ladder_entity.origin.z + self.ladder_entity.mins.z)
- dir_z = -1;
+ dir.z = -1;
}
}
}
void havocbot_chooseenemy()
-{
+{SELFPARAM();
entity head, best, head2;
float rating, bestrating, i, hf;
vector eye, v;
// I want to do a second scan if no enemy was found or I don't have weapons
// TODO: Perform the scan when using the rifle (requires changes on the rifle code)
- if(best || self.weapons) // || self.weapon == WEP_RIFLE
+ if(best || self.weapons) // || self.weapon == WEP_RIFLE.m_id
break;
if(i)
break;
self.havocbot_stickenemy = true;
}
-float havocbot_chooseweapon_checkreload(float new_weapon)
-{
+float havocbot_chooseweapon_checkreload(int new_weapon)
+{SELFPARAM();
// bots under this skill cannot find unloaded weapons to reload idly when not in combat,
// so skip this for them, or they'll never get to reload their weapons at all.
// this also allows bots under this skill to be more stupid, and reload more often during combat :)
}
void havocbot_chooseweapon()
-{
- float i;
+{SELFPARAM();
+ int i;
// ;)
if(g_weaponarena_weapons == WEPSET_TUBA)
{
- self.switchweapon = WEP_TUBA;
+ self.switchweapon = WEP_TUBA.m_id;
return;
}
{
// If no weapon was chosen get the first available weapon
if(self.weapon==0)
- for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER)
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER.m_id)
{
if(client_hasweapon(self, i, true, false))
{
}
// Do not change weapon during the next second after a combo
- i = time - self.lastcombotime;
- if(i < 1)
+ float f = time - self.lastcombotime;
+ if(f < 1)
return;
float w;
}
void havocbot_aim()
-{
+{SELFPARAM();
vector selfvel, enemyvel;
// if(self.flags & FL_INWATER)
// return;
self.nextaim = time + 0.1;
selfvel = self.velocity;
if (!self.waterlevel)
- selfvel_z = 0;
+ selfvel.z = 0;
if (self.enemy)
{
enemyvel = self.enemy.velocity;
if (!self.enemy.waterlevel)
- enemyvel_z = 0;
+ enemyvel.z = 0;
lag_additem(time + self.ping, 0, 0, self.enemy, self.origin, selfvel, (self.enemy.absmin + self.enemy.absmax) * 0.5, enemyvel);
}
else
}
float havocbot_moveto_refresh_route()
-{
+{SELFPARAM();
// Refresh path to goal if necessary
entity wp;
wp = self.havocbot_personal_waypoint;
}
float havocbot_moveto(vector pos)
-{
+{SELFPARAM();
entity wp;
if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
// Step 4: Move to waypoint
if(self.havocbot_personal_waypoint==world)
{
- dprint("Error: ", self.netname, " trying to walk to a non existent personal waypoint\n");
+ LOG_TRACE("Error: ", self.netname, " trying to walk to a non existent personal waypoint\n");
self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
return CMD_STATUS_ERROR;
}
bot_strategytoken_taken = true;
if(havocbot_moveto_refresh_route())
{
- dprint(self.netname, " walking to its personal waypoint (after ", ftos(self.havocbot_personal_waypoint_failcounter), " failed attempts)\n");
+ LOG_TRACE(self.netname, " walking to its personal waypoint (after ", ftos(self.havocbot_personal_waypoint_failcounter), " failed attempts)\n");
self.havocbot_personal_waypoint_searchtime = time + 10;
self.havocbot_personal_waypoint_failcounter = 0;
}
self.havocbot_personal_waypoint_searchtime = time + 2;
if(self.havocbot_personal_waypoint_failcounter >= 30)
{
- dprint("Warning: can't walk to the personal waypoint located at ", vtos(self.havocbot_personal_waypoint.origin),"\n");
+ LOG_TRACE("Warning: can't walk to the personal waypoint located at ", vtos(self.havocbot_personal_waypoint.origin),"\n");
self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_LINKING;
remove(self.havocbot_personal_waypoint);
return CMD_STATUS_ERROR;
}
else
- dprint(self.netname, " can't walk to its personal waypoint (after ", ftos(self.havocbot_personal_waypoint_failcounter), " failed attempts), trying later\n");
+ LOG_TRACE(self.netname, " can't walk to its personal waypoint (after ", ftos(self.havocbot_personal_waypoint_failcounter), " failed attempts), trying later\n");
}
}
// Heading
vector dir = ( ( self.goalcurrent.absmin + self.goalcurrent.absmax ) * 0.5 ) - (self.origin + self.view_ofs);
- dir_z = 0;
+ dir.z = 0;
bot_aimdir(dir, -1);
// Go!
if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_REACHED)
{
// Step 5: Waypoint reached
- dprint(self.netname, "'s personal waypoint reached\n");
+ LOG_TRACE(self.netname, "'s personal waypoint reached\n");
remove(self.havocbot_personal_waypoint);
self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_REACHED;
return CMD_STATUS_FINISHED;
// Wait until it is linked
if(!self.havocbot_personal_waypoint.wplinked)
{
- dprint(self.netname, " waiting for personal waypoint to be linked\n");
+ LOG_TRACE(self.netname, " waiting for personal waypoint to be linked\n");
return CMD_STATUS_EXECUTING;
}
self.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_GOING;
// Step 3: Route to waypoint
- dprint(self.netname, " walking to its personal waypoint\n");
+ LOG_TRACE(self.netname, " walking to its personal waypoint\n");
return CMD_STATUS_EXECUTING;
}
wp = waypoint_spawnpersonal(pos);
if(wp==world)
{
- dprint("Error: Can't spawn personal waypoint at ",vtos(pos),"\n");
+ LOG_TRACE("Error: Can't spawn personal waypoint at ",vtos(pos),"\n");
return CMD_STATUS_ERROR;
}
}
void havocbot_setupbot()
-{
+{SELFPARAM();
self.bot_ai = havocbot_ai;
self.cmd_moveto = havocbot_moveto;
self.cmd_resetgoal = havocbot_resetgoal;
}
vector havocbot_dodge()
-{
+{SELFPARAM();
// LordHavoc: disabled because this is too expensive
return '0 0 0';
#if 0