#include "../waypoints.qh"
#include <common/constants.qh>
+#include <common/net_linked.qh>
#include <common/physics/player.qh>
#include <common/state.qh>
#include <common/items/_mod.qh>
if(bot_execute_commands(this))
return;
+ while(this.goalcurrent && wasfreed(this.goalcurrent))
+ {
+ navigation_poproute(this);
+ if(!this.goalcurrent)
+ this.bot_strategytime = 0;
+ }
+
if (bot_strategytoken == this)
if (!bot_strategytoken_taken)
{
// TODO: tracewalk() should take care of this job (better path finding under water)
// if we don't have a goal and we're under water look for a waypoint near the "shore" and push it
- if(IS_DEAD(this))
+ if(!(IS_DEAD(this)))
if(!this.goalcurrent)
if(this.waterlevel == WATERLEVEL_SWIMMING || (this.aistatus & AI_STATUS_OUT_WATER))
{
//heading = this.velocity;
//dprint(this.goalstack01.classname,etos(this.goalstack01),"\n");
if(
- this.goalstack01 != this && this.goalstack01 != NULL && ((this.aistatus & AI_STATUS_RUNNING) == 0) &&
+ this.goalstack01 != this && this.goalstack01 && !wasfreed(this.goalstack01) && ((this.aistatus & AI_STATUS_RUNNING) == 0) &&
!(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
)
next = ((this.goalstack01.absmin + this.goalstack01.absmax) * 0.5) - (this.origin + this.view_ofs);
if(this.goalcurrent.classname=="waypoint")
if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
if(fabs(gco.z - this.origin.z) < this.maxs.z - this.mins.z)
- if(this.goalstack01!=NULL)
+ if(this.goalstack01 && !wasfreed(this.goalstack01))
{
gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
deviation = vectoangles(gno - this.origin) - vectoangles(gco - this.origin);
if (time < this.havocbot_chooseenemy_finished)
return;
this.havocbot_chooseenemy_finished = time + autocvar_bot_ai_enemydetectioninterval;
+ vector eye = this.origin + this.view_ofs;
+ entity best = NULL;
+ float bestrating = 100000000;
+
+ // Backup hit flags
+ int hf = this.dphitcontentsmask;
// Search for enemies, if no enemy can be seen directly try to look through transparent objects
- int myhit = this.dphitcontentsmask;
this.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
- entity best = havocbot_gettarget(this, false); // first try primary targets
- if(!best)
- best = havocbot_gettarget(this, true); // now try secondary targets
- if(!best && this.weapons)
+ bool scan_transparent = false;
+ bool scan_secondary_targets = false;
+ bool have_secondary_targets = false;
+ while(true)
{
+ scan_secondary_targets = false;
+LABEL(scan_targets)
+ IL_EACH(g_bot_targets, it.bot_attack,
+ {
+ if(!scan_secondary_targets)
+ {
+ if(it.classname == "misc_breakablemodel")
+ {
+ have_secondary_targets = true;
+ continue;
+ }
+ }
+ else if(it.classname != "misc_breakablemodel")
+ continue;
+
+ vector v = (it.absmin + it.absmax) * 0.5;
+ float rating = vlen2(v - eye);
+ if (vdist(v - eye, <, autocvar_bot_ai_enemydetectionradius))
+ if (bestrating > rating)
+ if (bot_shouldattack(this, it))
+ {
+ traceline(eye, v, true, this);
+ if (trace_ent == it || trace_fraction >= 1)
+ {
+ best = it;
+ bestrating = rating;
+ }
+ }
+ });
+
+ if(!best && have_secondary_targets && !scan_secondary_targets)
+ {
+ scan_secondary_targets = true;
+ // restart the loop
+ bestrating = 100000000;
+ goto scan_targets;
+ }
+
+ // 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 || this.weapons) // || this.weapon == WEP_RIFLE.m_id
+ break;
+ if(scan_transparent)
+ break;
+
+ // Set flags to see through transparent objects
this.dphitcontentsmask |= DPCONTENTS_OPAQUE;
- best = havocbot_gettarget(this, false);
- if(!best)
- best = havocbot_gettarget(this, true);
+
+ scan_transparent = true;
}
- this.dphitcontentsmask = myhit;
+ // Restore hit flags
+ this.dphitcontentsmask = hf;
this.enemy = best;
this.havocbot_stickenemy = true;