]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/wepent_experimental
authorMario <mario@smbclan.net>
Fri, 16 Dec 2016 03:45:00 +0000 (13:45 +1000)
committerMario <mario@smbclan.net>
Fri, 16 Dec 2016 03:45:00 +0000 (13:45 +1000)
1  2 
qcsrc/server/bot/default/havocbot/havocbot.qc

index 9f3e075f1d6fbbbd7290d0e361c6df2e9601e418,b23c15bcafdeccbfb0b4874f0d8cfe77f18c5aaa..0047a26283ba485710c5cb3630fc4af7b16a20da
@@@ -13,7 -13,6 +13,7 @@@
  #include <common/physics/player.qh>
  #include <common/state.qh>
  #include <common/items/_mod.qh>
 +#include <common/wepent.qh>
  
  #include <common/triggers/teleporters.qh>
  #include <common/triggers/trigger/jumppads.qh>
@@@ -30,9 -29,12 +30,12 @@@ void havocbot_ai(entity this
        if(bot_execute_commands(this))
                return;
  
-       if(this.goalcurrent)
-       if(wasfreed(this.goalcurrent))
+       while(this.goalcurrent && wasfreed(this.goalcurrent))
+       {
                navigation_poproute(this);
+               if(!this.goalcurrent)
+                       this.bot_strategytime = 0;
+       }
  
        if (bot_strategytoken == this)
        if (!bot_strategytoken_taken)
                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);
  
                if(this.weapons)
                {
 -                      Weapon w = PS(this).m_weapon;
 -                      w.wr_aim(w, this);
                        if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this))
                        {
                                PHYS_INPUT_BUTTON_ATCK(this) = false;
                        }
                        else
                        {
 -                              if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this))
 -                                      this.lastfiredweapon = PS(this).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
                //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 the bot is not attacking, consider reloading weapons
        if (!(this.aistatus & AI_STATUS_ATTACKING))
        {
 -              // 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.clip_load < this.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.clip_load >= 0) // only if we're not reloading a weapon already
 +              for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
 -                      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;
 -                      ));
 +                      .entity weaponentity = weaponentities[slot];
 +
 +                      if(this.(weaponentity).m_weapon == WEP_Null && slot != 0)
 +                              continue;
 +
 +                      // 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;
 +                              ));
 +                      }
                }
        }
  }
@@@ -346,7 -328,7 +349,7 @@@ void havocbot_bunnyhop(entity this, vec
                                        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);
@@@ -610,35 -592,25 +613,35 @@@ void havocbot_movetogoal(entity this
                else if(this.health>WEP_CVAR(devastator, damage)*0.5)
                {
                        if(this.velocity.z < 0)
 -                      if(client_hasweapon(this, WEP_DEVASTATOR, 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;
                                }
 -
 -                              PS(this).m_switchweapon = WEP_DEVASTATOR;
 -                              this.v_angle_x = 90;
 -                              PHYS_INPUT_BUTTON_ATCK(this) = true;
 -                              this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
 -                              return;
                        }
                }
                else
@@@ -1009,7 -981,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.
                return false;
  
        // if this weapon is scheduled for reloading, don't switch to it during combat
 -      if (this.weapon_load[new_weapon] < 0)
 +      if (this.(weaponentity).weapon_load[new_weapon] < 0)
        {
                bool other_weapon_available = false;
                FOREACH(Weapons, it != WEP_Null, LAMBDA(
 -                      if(it.wr_checkammo1(it, this) + it.wr_checkammo2(it, this))
 +                      if(it.wr_checkammo1(it, this, weaponentity) + it.wr_checkammo2(it, this, weaponentity))
                                other_weapon_available = true;
                ));
                if(other_weapon_available)
        return false;
  }
  
 -void havocbot_chooseweapon(entity this)
 +void havocbot_chooseweapon(entity this, .entity weaponentity)
  {
        int i;
  
        // ;)
        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))
 +                      if(client_hasweapon(this, it, weaponentity, 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.(weaponentity).lastfiredweapon)
        if(af > combo_time)
        {
                combo = true;
                if ( distance > bot_distance_far ) {
                        for(i=0; i < Weapons_COUNT && bot_weapons_far[i] != -1 ; ++i){
                                w = bot_weapons_far[i];
 -                              if ( client_hasweapon(this, Weapons_from(w), true, false) )
 +                              if ( client_hasweapon(this, Weapons_from(w), weaponentity, 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, weaponentity, w))
                                                continue;
 -                                      PS(this).m_switchweapon = Weapons_from(w);
 +                                      this.(weaponentity).m_switchweapon = Weapons_from(w);
                                        return;
                                }
                        }
                if ( distance > bot_distance_close) {
                        for(i=0; i < Weapons_COUNT && bot_weapons_mid[i] != -1 ; ++i){
                                w = bot_weapons_mid[i];
 -                              if ( client_hasweapon(this, Weapons_from(w), true, false) )
 +                              if ( client_hasweapon(this, Weapons_from(w), weaponentity, 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, weaponentity, w))
                                                continue;
 -                                      PS(this).m_switchweapon = Weapons_from(w);
 +                                      this.(weaponentity).m_switchweapon = Weapons_from(w);
                                        return;
                                }
                        }
                // Choose weapons for close distance
                for(i=0; i < Weapons_COUNT && bot_weapons_close[i] != -1 ; ++i){
                        w = bot_weapons_close[i];
 -                      if ( client_hasweapon(this, Weapons_from(w), true, false) )
 +                      if ( client_hasweapon(this, Weapons_from(w), weaponentity, 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, weaponentity, w))
                                        continue;
 -                              PS(this).m_switchweapon = Weapons_from(w);
 +                              this.(weaponentity).m_switchweapon = Weapons_from(w);
                                return;
                        }
                }