if(this.weapons)
{
- Weapon w = PS(this).m_weapon;
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+ Weapon w = this.(weaponentity).m_weapon;
w.wr_aim(w, this);
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this))
{
else
{
if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this))
- this.lastfiredweapon = PS(this).m_weapon.m_id;
+ this.lastfiredweapon = this.(weaponentity).m_weapon.m_id;
}
}
else
if(skill >= 5) // bots can only look for unloaded weapons past this skill
if(this.clip_load >= 0) // only if we're not reloading a weapon already
{
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
FOREACH(Weapons, it != WEP_Null, LAMBDA(
if((this.weapons & (it.m_wepset)) && (it.spawnflags & WEP_FLAG_RELOADABLE) && (this.weapon_load[it.m_id] < it.reloading_ammo))
- PS(this).m_switchweapon = it;
+ this.(weaponentity).m_switchweapon = it;
));
}
}
return;
}
- PS(this).m_switchweapon = WEP_DEVASTATOR;
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+ this.(weaponentity).m_switchweapon = WEP_DEVASTATOR;
this.v_angle_x = 90;
PHYS_INPUT_BUTTON_ATCK(this) = true;
this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
void havocbot_chooseenemy(entity this)
{
+ entity head, best, head2;
+ float rating, bestrating, hf;
+ vector eye, v;
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this))
{
this.enemy = NULL;
if (time < this.havocbot_chooseenemy_finished)
return;
this.havocbot_chooseenemy_finished = time + autocvar_bot_ai_enemydetectioninterval;
+ eye = this.origin + this.view_ofs;
+ best = NULL;
+ bestrating = 100000000;
+ head = head2 = findchainfloat(bot_attack, true);
+
+ // Backup hit flags
+ 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)
+ for( ; head; head = head.chain)
+ {
+ if(!scan_secondary_targets)
+ {
+ if(head.classname == "misc_breakablemodel")
+ {
+ have_secondary_targets = true;
+ continue;
+ }
+ }
+ else
+ {
+ if(head.classname != "misc_breakablemodel")
+ continue;
+ }
+
+ v = (head.absmin + head.absmax) * 0.5;
+ rating = vlen(v - eye);
+ if (rating<autocvar_bot_ai_enemydetectionradius)
+ if (bestrating > rating)
+ if (bot_shouldattack(this, head))
+ {
+ traceline(eye, v, true, this);
+ if (trace_ent == head || trace_fraction >= 1)
+ {
+ best = head;
+ bestrating = rating;
+ }
+ }
+ }
+
+ if(!best && have_secondary_targets && !scan_secondary_targets)
+ {
+ scan_secondary_targets = true;
+ // restart the loop
+ head = head2;
+ 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);
+
+ head = head2;
+ scan_transparent = true;
}
- this.dphitcontentsmask = myhit;
+ // Restore hit flags
+ this.dphitcontentsmask = hf;
this.enemy = best;
this.havocbot_stickenemy = true;
{
int i;
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+
// ;)
if(g_weaponarena_weapons == WEPSET(TUBA))
{
- PS(this).m_switchweapon = WEP_TUBA;
+ this.(weaponentity).m_switchweapon = WEP_TUBA;
return;
}
if(this.enemy==NULL)
{
// If no weapon was chosen get the first available weapon
- if(PS(this).m_weapon==WEP_Null)
+ if(this.(weaponentity).m_weapon==WEP_Null)
FOREACH(Weapons, it != WEP_Null, LAMBDA(
if(client_hasweapon(this, it, true, false))
{
- PS(this).m_switchweapon = it;
+ this.(weaponentity).m_switchweapon = it;
return;
}
));
combo = false;
if(autocvar_bot_ai_weapon_combo)
- if(PS(this).m_weapon.m_id == this.lastfiredweapon)
+ if(this.(weaponentity).m_weapon.m_id == this.lastfiredweapon)
if(af > combo_time)
{
combo = true;
w = bot_weapons_far[i];
if ( client_hasweapon(this, Weapons_from(w), true, false) )
{
- if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
+ if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
continue;
- PS(this).m_switchweapon = Weapons_from(w);
+ this.(weaponentity).m_switchweapon = Weapons_from(w);
return;
}
}
w = bot_weapons_mid[i];
if ( client_hasweapon(this, Weapons_from(w), true, false) )
{
- if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
+ if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
continue;
- PS(this).m_switchweapon = Weapons_from(w);
+ this.(weaponentity).m_switchweapon = Weapons_from(w);
return;
}
}
w = bot_weapons_close[i];
if ( client_hasweapon(this, Weapons_from(w), true, false) )
{
- if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
+ if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
continue;
- PS(this).m_switchweapon = Weapons_from(w);
+ this.(weaponentity).m_switchweapon = Weapons_from(w);
return;
}
}