]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/terencehill/bot_waypoints' into terencehill...
authorterencehill <piuntn@gmail.com>
Sun, 24 Dec 2017 17:47:43 +0000 (18:47 +0100)
committerterencehill <piuntn@gmail.com>
Sun, 24 Dec 2017 17:47:43 +0000 (18:47 +0100)
# Conflicts:
# qcsrc/common/triggers/trigger/jumppads.qc

1  2 
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/trigger/jumppads.qh
qcsrc/server/bot/default/bot.qc

index ded21c377e291b3584dbb77be51abf8c707d478a,d10a1e33037d69ae81b22943c8ab26ed8e5ffe63..5bb6d39877ac610803f0a9fb029db9d36420554b
@@@ -25,19 -25,20 +25,20 @@@ REGISTER_NET_LINKED(ENT_CLIENT_TARGET_P
          tgt - target entity (can be either a point or a model entity; if it is
                the latter, its midpoint is used)
          ht  - jump height, measured from the higher one of org and tgt's midpoint
+         pushed_entity - object that is to be pushed
  
        Returns: velocity for the jump
   */
- vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
+ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity)
  {
        float grav, sdist, zdist, vs, vz, jumpheight;
        vector sdir, torg;
  
        torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
  
-       grav = PHYS_GRAVITY(tgt);
-       if(PHYS_ENTGRAVITY(tgt))
-               grav *= PHYS_ENTGRAVITY(tgt);
+       grav = PHYS_GRAVITY(NULL);
+       if(pushed_entity && PHYS_ENTGRAVITY(pushed_entity))
+               grav *= PHYS_ENTGRAVITY(pushed_entity);
  
        zdist = torg.z - org.z;
        sdist = vlen(torg - org - zdist * '0 0 1');
@@@ -135,7 -136,7 +136,7 @@@ bool jumppad_push(entity this, entity t
  
        if(this.enemy)
        {
-               targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height);
+               targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height, targ);
        }
        else if(this.target && this.target != "")
        {
                        else
                                RandomSelection_AddEnt(e, 1, 1);
                }
-               targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height);
+               targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height, targ);
        }
        else
        {
                                animdecide_setaction(targ, ANIMACTION_JUMP, true);
                }
                else
 -                      targ.jumppadcount = true;
 +                      targ.jumppadcount = 1;
  
                // reset tracking of who pushed you into a hazard (for kill credit)
                targ.pushltime = 0;
@@@ -302,10 -303,7 +303,10 @@@ bool trigger_push_testorigin(entity tra
        return true;
  }
  #endif
 -void trigger_push_findtarget(entity this)
 +
 +/// if (item != NULL) returns true if the item can be reached by using this jumppad, false otherwise
 +/// if (item == NULL) tests jumppad's trajectory and eventually spawns waypoints for it (return value doesn't matter)
 +bool trigger_push_test(entity this, entity item)
  {
        // first calculate a typical start point for the jump
        vector org = (this.absmin + this.absmax) * 0.5;
                        entity e = spawn();
                        setsize(e, PL_MIN_CONST, PL_MAX_CONST);
                        e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
-                       e.velocity = trigger_push_calculatevelocity(org, t, this.height);
+                       e.velocity = trigger_push_calculatevelocity(org, t, this.height, e);
 +
 +                      if(item)
 +                      {
 +                              setorigin(e, org);
 +                              tracetoss(e, e);
 +                              bool r = (trace_ent == item);
 +                              delete(e);
 +                              return r;
 +                      }
 +
                        vel = e.velocity;
                        vector best_target = '0 0 0';
                        vector best_org = '0 0 0';
                                vector flatdir = normalize(dist - eZ * dist.z);
                                vector ofs = flatdir * 0.5 * min(fabs(this.absmax.x - this.absmin.x), fabs(this.absmax.y - this.absmin.y));
                                new_org = org + ofs;
-                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height);
+                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height, e);
                                vel = e.velocity;
                                if (vdist(vec2(e.velocity), <, autocvar_sv_maxspeed))
                                        e.velocity = autocvar_sv_maxspeed * flatdir;
                                        valid_best_target = true;
                                }
                                new_org = org - ofs;
-                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height);
+                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height, e);
                                vel = e.velocity;
                                if (vdist(vec2(e.velocity), <, autocvar_sv_maxspeed))
                                        e.velocity = autocvar_sv_maxspeed * flatdir;
  #endif
                }
  
 +              if(item)
 +                      return false;
 +
                if(!n)
                {
                        // no dest!
  #ifdef SVQC
                        objerror (this, "Jumppad with nonexistant target");
  #endif
 -                      return;
 +                      return false;
                }
                else if(n == 1)
                {
                setorigin(e, org);
                e.velocity = this.movedir;
                tracetoss(e, e);
 +              if(item)
 +              {
 +                      bool r = (trace_ent == item);
 +                      delete(e);
 +                      return r;
 +              }
                if (!(boxesoverlap(this.absmin, this.absmax + eZ * 50, trace_endpos + PL_MIN_CONST, trace_endpos + PL_MAX_CONST)))
                        waypoint_spawnforteleporter(this, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity), e);
                delete(e);
  
        defer(this, 0.1, trigger_push_updatelink);
  #endif
 +      return true;
 +}
 +
 +void trigger_push_findtarget(entity this)
 +{
 +      trigger_push_test(this, NULL);
  }
  
  #ifdef SVQC
@@@ -516,8 -489,6 +517,8 @@@ spawnfunc(trigger_push
  
        trigger_push_link(this); // link it now
  
 +      IL_PUSH(g_jumppads, this);
 +
        // this must be called to spawn the teleport waypoints for bots
        InitializeEntity(this, trigger_push_findtarget, INITPRIO_FINDTARGET);
  }
index 819b90995c0e9363184a64a67424d818db0074a8,c3b0b339def6c2f0f7b8e5c35f6773c91bcb4aea..50ed0a343c8c86b7cc53e12274ddac7261bead75
@@@ -1,8 -1,5 +1,8 @@@
  #pragma once
  
 +IntrusiveList g_jumppads;
 +STATIC_INIT(g_jumppads) { g_jumppads = IL_NEW(); }
 +
  const float PUSH_ONCE         = 1;
  const float PUSH_SILENT               = 2;
  
@@@ -17,7 -14,6 +17,7 @@@ const int NUM_JUMPPADSUSED = 3
  #ifdef SVQC
  void SUB_UseTargets(entity this, entity actor, entity trigger);
  void trigger_push_use(entity this, entity actor, entity trigger);
 +bool trigger_push_testorigin(entity tracetest_ent, entity targ, entity jp, vector org);
  #endif
  
  /*
          tgt - target entity (can be either a point or a model entity; if it is
                the latter, its midpoint is used)
          ht  - jump height, measured from the higher one of org and tgt's midpoint
+         pushed_entity - object that is to be pushed
  
        Returns: velocity for the jump
   */
- vector trigger_push_calculatevelocity(vector org, entity tgt, float ht);
+ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity);
  
  void trigger_push_touch(entity this, entity toucher);
  
  .vector dest;
 +bool trigger_push_test(entity this, entity item);
  void trigger_push_findtarget(entity this);
  
  /*
index 23a58dca8feecbcc53a80ed4247ec615483d5ba3,20af7e71984dfdac24a5895ec91b7bf128f03b8b..276d5b53158e50deb6583521e74a034908fd979b
@@@ -133,7 -133,7 +133,7 @@@ void bot_think(entity this
                if (this.deadflag == DEAD_DEAD)
                {
                        PHYS_INPUT_BUTTON_JUMP(this) = true; // press jump to respawn
 -                      this.bot_strategytime = 0;
 +                      navigation_goalrating_timeout_force(this);
                }
        }
        else if(this.aistatus & AI_STATUS_STUCK)
@@@ -438,7 -438,7 +438,7 @@@ void bot_clientconnect(entity this
        else if(this.bot_forced_team==4)
                this.team = NUM_TEAM_4;
        else
-               JoinBestTeam(this, false, true);
+               JoinBestTeam(this, true);
  
        havocbot_setupbot(this);
  }
@@@ -770,26 -770,11 +770,26 @@@ void bot_serverframe(
                //  frame, which causes choppy framerates)
                if (bot_strategytoken_taken)
                {
 +                      // give goal token to the first bot without goals; if all bots don't have
 +                      // any goal (or are dead/frozen) simply give it to the next one
                        bot_strategytoken_taken = false;
 -                      if (bot_strategytoken)
 -                              bot_strategytoken = bot_strategytoken.nextbot;
 -                      if (!bot_strategytoken)
 -                              bot_strategytoken = bot_list;
 +                      entity bot_strategytoken_save = bot_strategytoken;
 +                      while (true)
 +                      {
 +                              if (bot_strategytoken)
 +                                      bot_strategytoken = bot_strategytoken.nextbot;
 +                              if (!bot_strategytoken)
 +                                      bot_strategytoken = bot_list;
 +
 +                              if (!(IS_DEAD(bot_strategytoken) || STAT(FROZEN, bot_strategytoken))
 +                                      && !bot_strategytoken.goalcurrent)
 +                                      break;
 +
 +                              if (!bot_strategytoken_save) // break loop if all the bots are dead or frozen
 +                                      break;
 +                              if (bot_strategytoken == bot_strategytoken_save)
 +                                      bot_strategytoken_save = NULL; // looped through all the bots
 +                      }
                }
  
                if (botframe_nextdangertime < time)