From cdcdcf9dfdaea11bd43312ceca679a6bfc9b7bf3 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 5 Oct 2016 16:38:35 +1000 Subject: [PATCH] Purge hardcoded slot 0 weapon entity use from most of the bot AI --- qcsrc/common/mutators/mutator/overkill/hmg.qc | 2 +- qcsrc/common/mutators/mutator/overkill/rpc.qc | 2 +- qcsrc/common/weapons/weapon.qh | 2 +- qcsrc/common/weapons/weapon/arc.qc | 2 +- qcsrc/common/weapons/weapon/blaster.qc | 2 +- qcsrc/common/weapons/weapon/crylink.qc | 2 +- qcsrc/common/weapons/weapon/devastator.qc | 2 +- qcsrc/common/weapons/weapon/electro.qc | 2 +- qcsrc/common/weapons/weapon/fireball.qc | 2 +- qcsrc/common/weapons/weapon/hagar.qc | 2 +- qcsrc/common/weapons/weapon/hlac.qc | 2 +- qcsrc/common/weapons/weapon/machinegun.qc | 2 +- qcsrc/common/weapons/weapon/minelayer.qc | 3 +- qcsrc/common/weapons/weapon/mortar.qc | 2 +- qcsrc/common/weapons/weapon/porto.qc | 2 +- qcsrc/common/weapons/weapon/rifle.qc | 2 +- qcsrc/common/weapons/weapon/seeker.qc | 3 +- qcsrc/common/weapons/weapon/shockwave.qc | 2 +- qcsrc/common/weapons/weapon/shotgun.qc | 2 +- qcsrc/common/weapons/weapon/tuba.qc | 2 +- qcsrc/common/weapons/weapon/vaporizer.qc | 2 +- qcsrc/common/weapons/weapon/vortex.qc | 2 +- qcsrc/server/bot/default/havocbot/havocbot.qc | 116 +++++++++++------- qcsrc/server/bot/default/havocbot/havocbot.qh | 2 +- 24 files changed, 92 insertions(+), 72 deletions(-) diff --git a/qcsrc/common/mutators/mutator/overkill/hmg.qc b/qcsrc/common/mutators/mutator/overkill/hmg.qc index 30e6174ad..e454f0dcc 100644 --- a/qcsrc/common/mutators/mutator/overkill/hmg.qc +++ b/qcsrc/common/mutators/mutator/overkill/hmg.qc @@ -58,7 +58,7 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weapone weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto); } -METHOD(HeavyMachineGun, wr_aim, void(entity thiswep, entity actor)) +METHOD(HeavyMachineGun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 0.001, false); diff --git a/qcsrc/common/mutators/mutator/overkill/rpc.qc b/qcsrc/common/mutators/mutator/overkill/rpc.qc index b4dec4626..54ae9d67e 100644 --- a/qcsrc/common/mutators/mutator/overkill/rpc.qc +++ b/qcsrc/common/mutators/mutator/overkill/rpc.qc @@ -110,7 +110,7 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep, entity actor, .entity wea MUTATOR_CALLHOOK(EditProjectile, actor, missile); } -METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep, entity actor)) +METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false); } diff --git a/qcsrc/common/weapons/weapon.qh b/qcsrc/common/weapons/weapon.qh index 9629b175d..782f3c5ce 100644 --- a/qcsrc/common/weapons/weapon.qh +++ b/qcsrc/common/weapons/weapon.qh @@ -95,7 +95,7 @@ CLASS(Weapon, Object) /** (SERVER) checks ammo for weapon second */ METHOD(Weapon, wr_checkammo2, bool(Weapon this, entity actor, .entity weaponentity)) {return false;} /** (SERVER) runs bot aiming code for this weapon */ - METHOD(Weapon, wr_aim, void(Weapon this, entity actor)) {} + METHOD(Weapon, wr_aim, void(Weapon this, entity actor, .entity weaponentity)) {} /** (BOTH) precaches models/sounds used by this weapon, also sets up weapon properties */ METHOD(Weapon, wr_init, void(Weapon this)) {} /** (SERVER) notification number for suicide message (may inspect w_deathtype for details) */ diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 889222d4c..7a703d3d0 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -736,7 +736,7 @@ void Arc_Smoke(entity actor, .entity weaponentity) } } -METHOD(Arc, wr_aim, void(entity thiswep, entity actor)) +METHOD(Arc, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(WEP_CVAR(arc, beam_botaimspeed)) { diff --git a/qcsrc/common/weapons/weapon/blaster.qc b/qcsrc/common/weapons/weapon/blaster.qc index 29e9c2a57..a4a6699a3 100644 --- a/qcsrc/common/weapons/weapon/blaster.qc +++ b/qcsrc/common/weapons/weapon/blaster.qc @@ -154,7 +154,7 @@ void W_Blaster_Attack( } } -METHOD(Blaster, wr_aim, void(entity thiswep, entity actor)) +METHOD(Blaster, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(WEP_CVAR(blaster, secondary)) { diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index b820e9452..2ef356e35 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -579,7 +579,7 @@ void W_Crylink_Attack2(Weapon thiswep, entity actor, .entity weaponentity) } } -METHOD(Crylink, wr_aim, void(entity thiswep, entity actor)) +METHOD(Crylink, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(random() < 0.10) PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false); diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index 31038fc4f..b75ca6f02 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -415,7 +415,7 @@ void W_Devastator_Attack(Weapon thiswep, entity actor, .entity weaponentity) MUTATOR_CALLHOOK(EditProjectile, actor, missile); } -METHOD(Devastator, wr_aim, void(entity thiswep, entity actor)) +METHOD(Devastator, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { // aim and decide to fire if appropriate PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false); diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index 15387a905..80314d5e6 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -488,7 +488,7 @@ void W_Electro_CheckAttack(Weapon thiswep, entity actor, .entity weaponentity, i .float bot_secondary_electromooth; -METHOD(Electro, wr_aim, void(entity thiswep, entity actor)) +METHOD(Electro, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { PHYS_INPUT_BUTTON_ATCK(actor) = PHYS_INPUT_BUTTON_ATCK2(actor) = false; if(vdist(actor.origin - actor.enemy.origin, >, 1000)) { actor.bot_secondary_electromooth = 0; } diff --git a/qcsrc/common/weapons/weapon/fireball.qc b/qcsrc/common/weapons/weapon/fireball.qc index 54fbb0949..a7dca49bf 100644 --- a/qcsrc/common/weapons/weapon/fireball.qc +++ b/qcsrc/common/weapons/weapon/fireball.qc @@ -364,7 +364,7 @@ void W_Fireball_Attack2(entity actor, .entity weaponentity) MUTATOR_CALLHOOK(EditProjectile, actor, proj); } -METHOD(Fireball, wr_aim, void(entity thiswep, entity actor)) +METHOD(Fireball, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { PHYS_INPUT_BUTTON_ATCK(actor) = false; PHYS_INPUT_BUTTON_ATCK2(actor) = false; diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index b00b181cf..a8620e50b 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -449,7 +449,7 @@ void W_Hagar_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int weapon_thinkf(actor, weaponentity, theframe, WEP_CVAR_PRI(hagar, refire), W_Hagar_Attack_Auto); } -METHOD(Hagar, wr_aim, void(entity thiswep, entity actor)) +METHOD(Hagar, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(random()>0.15) PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false); diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index ba2b7f351..d1b4286a2 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -212,7 +212,7 @@ void W_HLAC_Attack2_Frame(Weapon thiswep, entity actor, .entity weaponentity) } } -METHOD(HLAC, wr_aim, void(entity thiswep, entity actor)) +METHOD(HLAC, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false); } diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index 009285b8c..1d5ddeecc 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -254,7 +254,7 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit } -METHOD(MachineGun, wr_aim, void(entity thiswep, entity actor)) +METHOD(MachineGun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 0.001, false); diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index 0234cd157..b33ce2b19 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -420,10 +420,9 @@ bool W_MineLayer_PlacedMines(entity this, .entity weaponentity, bool detonate) return minfound; } -METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor)) +METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { // aim and decide to fire if appropriate - .entity weaponentity = weaponentities[0]; // TODO: unhardcode if(actor.(weaponentity).minelayer_mines >= WEP_CVAR(minelayer, limit)) PHYS_INPUT_BUTTON_ATCK(actor) = false; else diff --git a/qcsrc/common/weapons/weapon/mortar.qc b/qcsrc/common/weapons/weapon/mortar.qc index 43119d45a..9f1b4a749 100644 --- a/qcsrc/common/weapons/weapon/mortar.qc +++ b/qcsrc/common/weapons/weapon/mortar.qc @@ -309,7 +309,7 @@ void W_Mortar_Attack2(Weapon thiswep, entity actor, .entity weaponentity) .float bot_secondary_grenademooth; -METHOD(Mortar, wr_aim, void(entity thiswep, entity actor)) +METHOD(Mortar, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { PHYS_INPUT_BUTTON_ATCK(actor) = false; PHYS_INPUT_BUTTON_ATCK2(actor) = false; diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index 782cb0e3e..ba972bc55 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -298,7 +298,7 @@ void W_Porto_Attack(entity actor, .entity weaponentity, float type) MUTATOR_CALLHOOK(EditProjectile, actor, gren); } -METHOD(PortoLaunch, wr_aim, void(entity thiswep, entity actor)) +METHOD(PortoLaunch, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { PHYS_INPUT_BUTTON_ATCK(actor) = false; PHYS_INPUT_BUTTON_ATCK2(actor) = false; diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index c1835f100..a2122451e 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -143,7 +143,7 @@ void W_Rifle_BulletHail(entity actor, .entity weaponentity, float mode, void(ent .float bot_secondary_riflemooth; -METHOD(Rifle, wr_aim, void(entity thiswep, entity actor)) +METHOD(Rifle, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { PHYS_INPUT_BUTTON_ATCK(actor) = false; PHYS_INPUT_BUTTON_ATCK2(actor) = false; diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index 93eba4396..bf60907e1 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -614,9 +614,8 @@ void W_Seeker_Fire_Tag(Weapon thiswep, entity actor, .entity weaponentity) // Begin: Genereal weapon functions // ============================ -METHOD(Seeker, wr_aim, void(entity thiswep, entity actor)) +METHOD(Seeker, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { - .entity weaponentity = weaponentities[0]; // TODO: unhardcode if(WEP_CVAR(seeker, type) == 1) if(W_Seeker_Tagged_Info(actor, weaponentity, actor.enemy) != NULL) PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false); diff --git a/qcsrc/common/weapons/weapon/shockwave.qc b/qcsrc/common/weapons/weapon/shockwave.qc index 8dd56d940..a57f15731 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@ -695,7 +695,7 @@ void W_Shockwave_Attack(entity actor, .entity weaponentity) } } -METHOD(Shockwave, wr_aim, void(entity thiswep, entity actor)) +METHOD(Shockwave, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR(shockwave, melee_range))) { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, 1000000, 0, 0.001, false); } diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index b33f5890f..1fcc3336b 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -227,7 +227,7 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity .float shotgun_primarytime; -METHOD(Shotgun, wr_aim, void(entity thiswep, entity actor)) +METHOD(Shotgun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR_SEC(shotgun, melee_range))) PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, 1000000, 0, 0.001, false); diff --git a/qcsrc/common/weapons/weapon/tuba.qc b/qcsrc/common/weapons/weapon/tuba.qc index 48469864c..bd6edcef0 100644 --- a/qcsrc/common/weapons/weapon/tuba.qc +++ b/qcsrc/common/weapons/weapon/tuba.qc @@ -363,7 +363,7 @@ void W_Tuba_NoteOn(entity actor, .entity weaponentity, float hittype) #endif #ifdef SVQC -METHOD(Tuba, wr_aim, void(Tuba this, entity actor)) +METHOD(Tuba, wr_aim, void(Tuba this, entity actor, .entity weaponentity)) { // bots cannot play the Tuba well yet // I think they should start with the recorder first diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index cb55c5dda..5d17d62dc 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -352,7 +352,7 @@ void W_RocketMinsta_Attack3 (entity actor, .entity weaponentity) } } -METHOD(Vaporizer, wr_aim, void(entity thiswep, entity actor)) +METHOD(Vaporizer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(actor.(thiswep.ammo_field) > 0) PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, 1000000, 0, 1, false); diff --git a/qcsrc/common/weapons/weapon/vortex.qc b/qcsrc/common/weapons/weapon/vortex.qc index 7a30516ed..1c98a7d5e 100644 --- a/qcsrc/common/weapons/weapon/vortex.qc +++ b/qcsrc/common/weapons/weapon/vortex.qc @@ -215,7 +215,7 @@ void W_Vortex_Attack(Weapon thiswep, entity actor, .entity weaponentity, float i .float vortex_chargepool_pauseregen_finished; -METHOD(Vortex, wr_aim, void(entity thiswep, entity actor)) +METHOD(Vortex, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { if(bot_aim(actor, 1000000, 0, 1, false)) PHYS_INPUT_BUTTON_ATCK(actor) = true; diff --git a/qcsrc/server/bot/default/havocbot/havocbot.qc b/qcsrc/server/bot/default/havocbot/havocbot.qc index 159cd6e72..db395b9c3 100644 --- a/qcsrc/server/bot/default/havocbot/havocbot.qc +++ b/qcsrc/server/bot/default/havocbot/havocbot.qc @@ -84,10 +84,16 @@ void havocbot_ai(entity this) return; havocbot_chooseenemy(this); - if (this.bot_chooseweapontime < time ) + + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { - this.bot_chooseweapontime = time + autocvar_bot_ai_chooseweaponinterval; - havocbot_chooseweapon(this); + .entity weaponentity = weaponentities[slot]; + if(this.(weaponentity).m_weapon != WEP_Null || slot == 0) + if(this.(weaponentity).bot_chooseweapontime < time) + { + this.(weaponentity).bot_chooseweapontime = time + autocvar_bot_ai_chooseweaponinterval; + havocbot_chooseweapon(this, weaponentity); + } } havocbot_aim(this); lag_update(this); @@ -98,9 +104,6 @@ void havocbot_ai(entity this) if(this.weapons) { - .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)) { PHYS_INPUT_BUTTON_ATCK(this) = false; @@ -108,8 +111,16 @@ void havocbot_ai(entity this) } else { - if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this)) - this.lastfiredweapon = this.(weaponentity).m_weapon.m_id; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + Weapon w = this.(weaponentity).m_weapon; + if(w == WEP_Null && slot != 0) + continue; + w.wr_aim(w, this, weaponentity); + if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this)) // TODO: what if we didn't fire this weapon, but the previous? + this.(weaponentity).lastfiredweapon = this.(weaponentity).m_weapon.m_id; + } } } else @@ -156,22 +167,28 @@ void havocbot_ai(entity this) // if the bot is not attacking, consider reloading weapons if (!(this.aistatus & AI_STATUS_ATTACKING)) { - .entity weaponentity = weaponentities[0]; // TODO: unhardcode + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; - // 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(this.(weaponentity).clip_load < this.(weaponentity).clip_size) - this.impulse = 20; // "press" the reload button, not sure if this is done right + if(this.(weaponentity).m_weapon == WEP_Null && slot != 0) + continue; - // if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next - // the code above executes next frame, starting the reloading then - if(skill >= 5) // bots can only look for unloaded weapons past this skill - if(this.(weaponentity).clip_load >= 0) // only if we're not reloading a weapon already - { - FOREACH(Weapons, it != WEP_Null, LAMBDA( - if((this.weapons & (it.m_wepset)) && (it.spawnflags & WEP_FLAG_RELOADABLE) && (this.(weaponentity).weapon_load[it.m_id] < it.reloading_ammo)) - this.(weaponentity).m_switchweapon = it; - )); + // 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(this.(weaponentity).clip_load < this.(weaponentity).clip_size) + this.impulse = 20; // "press" the reload button, not sure if this is done right + + // if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next + // the code above executes next frame, starting the reloading then + if(skill >= 5) // bots can only look for unloaded weapons past this skill + if(this.(weaponentity).clip_load >= 0) // only if we're not reloading a weapon already + { + FOREACH(Weapons, it != WEP_Null, LAMBDA( + if((this.weapons & (it.m_wepset)) && (it.spawnflags & WEP_FLAG_RELOADABLE) && (this.(weaponentity).weapon_load[it.m_id] < it.reloading_ammo)) + this.(weaponentity).m_switchweapon = it; + )); + } } } } @@ -586,28 +603,36 @@ void havocbot_movetogoal(entity this) } else if(this.health>WEP_CVAR(devastator, damage)*0.5) { - .entity weaponentity = weaponentities[0]; // TODO: unhardcode - if(this.velocity.z < 0) - if(client_hasweapon(this, WEP_DEVASTATOR, weaponentity, true, false)) { - this.movement_x = maxspeed; - - if(this.rocketjumptime) + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { - if(time > this.rocketjumptime) + .entity weaponentity = weaponentities[slot]; + + if(this.(weaponentity).m_weapon == WEP_Null && slot != 0) + continue; + + if(client_hasweapon(this, WEP_DEVASTATOR, weaponentity, true, false)) { - PHYS_INPUT_BUTTON_ATCK2(this) = true; - this.rocketjumptime = 0; + this.movement_x = maxspeed; + + if(this.rocketjumptime) + { + if(time > this.rocketjumptime) + { + PHYS_INPUT_BUTTON_ATCK2(this) = true; + this.rocketjumptime = 0; + } + return; + } + + this.(weaponentity).m_switchweapon = WEP_DEVASTATOR; + this.v_angle_x = 90; + PHYS_INPUT_BUTTON_ATCK(this) = true; + this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay); + return; } - return; } - - this.(weaponentity).m_switchweapon = WEP_DEVASTATOR; - this.v_angle_x = 90; - PHYS_INPUT_BUTTON_ATCK(this) = true; - this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay); - return; } } else @@ -987,7 +1012,7 @@ LABEL(scan_targets) this.havocbot_stickenemy = false; } -float havocbot_chooseweapon_checkreload(entity this, int new_weapon) +float havocbot_chooseweapon_checkreload(entity this, .entity weaponentity, int new_weapon) { // 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. @@ -996,7 +1021,6 @@ float havocbot_chooseweapon_checkreload(entity this, int new_weapon) return false; // if this weapon is scheduled for reloading, don't switch to it during combat - .entity weaponentity = weaponentities[0]; // TODO: unhardcode if (this.(weaponentity).weapon_load[new_weapon] < 0) { bool other_weapon_available = false; @@ -1011,12 +1035,10 @@ float havocbot_chooseweapon_checkreload(entity this, int new_weapon) return false; } -void havocbot_chooseweapon(entity this) +void havocbot_chooseweapon(entity this, .entity weaponentity) { int i; - .entity weaponentity = weaponentities[0]; // TODO: unhardcode - // ;) if(g_weaponarena_weapons == WEPSET(TUBA)) { @@ -1060,7 +1082,7 @@ void havocbot_chooseweapon(entity this) combo = false; if(autocvar_bot_ai_weapon_combo) - if(this.(weaponentity).m_weapon.m_id == this.lastfiredweapon) + if(this.(weaponentity).m_weapon.m_id == this.(weaponentity).lastfiredweapon) if(af > combo_time) { combo = true; @@ -1078,7 +1100,7 @@ void havocbot_chooseweapon(entity this) w = bot_weapons_far[i]; if ( client_hasweapon(this, Weapons_from(w), weaponentity, true, false) ) { - if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) + if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, weaponentity, w)) continue; this.(weaponentity).m_switchweapon = Weapons_from(w); return; @@ -1092,7 +1114,7 @@ void havocbot_chooseweapon(entity this) w = bot_weapons_mid[i]; if ( client_hasweapon(this, Weapons_from(w), weaponentity, true, false) ) { - if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) + if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, weaponentity, w)) continue; this.(weaponentity).m_switchweapon = Weapons_from(w); return; @@ -1105,7 +1127,7 @@ void havocbot_chooseweapon(entity this) w = bot_weapons_close[i]; if ( client_hasweapon(this, Weapons_from(w), weaponentity, true, false) ) { - if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w)) + if ((this.(weaponentity).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, weaponentity, w)) continue; this.(weaponentity).m_switchweapon = Weapons_from(w); return; diff --git a/qcsrc/server/bot/default/havocbot/havocbot.qh b/qcsrc/server/bot/default/havocbot/havocbot.qh index 4a391b6e7..8ab4cba6e 100644 --- a/qcsrc/server/bot/default/havocbot/havocbot.qh +++ b/qcsrc/server/bot/default/havocbot/havocbot.qh @@ -39,7 +39,7 @@ void havocbot_setupbot(entity this); void havocbot_movetogoal(entity this); void havocbot_chooserole(entity this); void havocbot_chooseenemy(entity this); -void havocbot_chooseweapon(entity this); +void havocbot_chooseweapon(entity this, .entity weaponentity); void havocbot_bunnyhop(entity this, vector dir); void havocbot_keyboard_movement(entity this, vector destorg); -- 2.39.2