]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'terencehill/bot_waypoints' into terencehill/bot_ai
authorterencehill <piuntn@gmail.com>
Mon, 11 Sep 2017 16:45:17 +0000 (18:45 +0200)
committerterencehill <piuntn@gmail.com>
Mon, 11 Sep 2017 16:45:17 +0000 (18:45 +0200)
1  2 
qcsrc/server/bot/default/navigation.qc

index 61d2d530de10762ff997229d44e3c9a66b701c77,86f2feebdf718b4c36e4fcb0d578ebb8279fe4f9..9a3f65255921e3ffb860c86acab4b0fe0b016c3d
  
  .float speed;
  
 +void navigation_goalrating_timeout_set(entity this)
 +{
 +      if(IS_MOVABLE(this.goalentity))
 +              this.bot_strategytime = time + autocvar_bot_ai_strategyinterval_movingtarget;
 +      else
 +              this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
 +}
 +
 +void navigation_goalrating_timeout_force(entity this)
 +{
 +      this.bot_strategytime = 0;
 +}
 +
 +bool navigation_goalrating_timeout(entity this)
 +{
 +      return this.bot_strategytime < time;
 +}
 +
  void navigation_dynamicgoal_init(entity this, bool initially_static)
  {
        this.navigation_dynamicgoal = true;
@@@ -773,14 -755,7 +773,14 @@@ entity navigation_findnearestwaypoint_w
        IL_EACH(g_waypoints, it != ent && it != except,
        {
                if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
 +              {
 +                      if(!autocvar_g_waypointeditor && walkfromwp && !ent.navigation_dynamicgoal)
 +                      {
 +                              waypoint_clearlinks(ent); // initialize wpXXmincost fields
 +                              navigation_item_addlink(it, ent);
 +                      }
                        return it;
 +              }
        });
  
        vector org = ent.origin;
@@@ -1331,7 -1306,7 +1331,7 @@@ bool navigation_routetogoal(entity this
                {
                        if (this.goalentity.navigation_dynamicgoal || autocvar_g_waypointeditor)
                        {
-                               SET_TRACEWALK_DESTCOORDS(e, nearest_wp.enemy.origin, dest, dest_height);
+                               SET_TRACEWALK_DESTCOORDS(this.goalentity, nearest_wp.enemy.origin, dest, dest_height);
                                if(vdist(dest - nearest_wp.enemy.origin, <, 1050))
                                if(tracewalk(this, nearest_wp.enemy.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), dest, dest_height, bot_navigation_movemode))
                                        e = nearest_wp.enemy;
  
  // removes any currently touching waypoints from the goal stack
  // (this is how bots detect if they reached a goal)
 -void navigation_poptouchedgoals(entity this)
 +int navigation_poptouchedgoals(entity this)
  {
 +      int removed_goals = 0;
        if(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
        {
                // make sure jumppad is really hit, don't rely on distance based checks
                                this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
                        }
                        navigation_poproute(this);
 +                      ++removed_goals;
                }
                else
 -                      return;
 +                      return removed_goals;
        }
  
        // If for some reason the bot is closer to the next goal, pop the current one
        if(vlen2(this.goalcurrent.origin - this.origin) > vlen2(this.goalstack01.origin - this.origin))
        if(checkpvs(this.origin + this.view_ofs, this.goalstack01))
        {
 -              vector dest = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
 -              dest.z = this.goalstack01.absmin.z;
 -              float dest_height = this.goalstack01.absmax.z - this.goalstack01.absmin.z;
 +              vector dest = '0 0 0';
 +              float dest_height = 0;
 +              SET_TRACEWALK_DESTCOORDS(this.goalstack01, this.origin, dest, dest_height);
                if(tracewalk(this, this.origin, this.mins, this.maxs, dest, dest_height, bot_navigation_movemode))
                {
                        LOG_DEBUG("path optimized for ", this.netname, ", removed a goal from the queue");
                        navigation_poproute(this);
 +                      ++removed_goals;
                        if(this.goalcurrent && this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
 -                              return;
 +                              return removed_goals;
                        // TODO this may also be a nice idea to do "early" (e.g. by
                        // manipulating the vlen() comparisons) to shorten paths in
                        // general - this would make bots walk more "on rails" than
                                }
  
                                navigation_poproute(this);
 +                              ++removed_goals;
                                if(this.goalcurrent && this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
 -                                      return;
 +                                      return removed_goals;
                        }
                }
        }
                }
  
                navigation_poproute(this);
 +              ++removed_goals;
                if(this.goalcurrent && this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
 -                      return;
 +                      return removed_goals;
        }
 +      return removed_goals;
 +}
 +
 +entity navigation_get_really_close_waypoint(entity this)
 +{
 +      entity wp = this.goalcurrent;
 +      if(!wp || vdist(wp.origin - this.origin, >, 50))
 +              wp = this.goalcurrent_prev;
 +      if(!wp)
 +              return NULL;
 +      if(wp.classname != "waypoint")
 +      {
 +              wp = wp.nearestwaypoint;
 +              if(!wp)
 +                      return NULL;
 +      }
 +      if(vdist(wp.origin - this.origin, >, 50))
 +      {
 +              IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_TELEPORT),
 +              {
 +                      if(vdist(it.origin - this.origin, <, 50))
 +                      {
 +                              wp = it;
 +                              break;
 +                      }
 +              });
 +      }
 +      if(wp.wpflags & WAYPOINTFLAG_TELEPORT)
 +              return NULL;
 +
 +      vector dest = '0 0 0';
 +      float dest_height = 0;
 +      SET_TRACEWALK_DESTCOORDS(wp, this.origin, dest, dest_height);
 +      if (!tracewalk(this, this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), dest, dest_height, bot_navigation_movemode))
 +              return NULL;
 +      return wp;
  }
  
  // begin a goal selection session (queries spawnfunc_waypoint network)
@@@ -1500,10 -1434,9 +1500,10 @@@ void navigation_goalrating_start(entit
  
        this.navigation_jetpack_goal = NULL;
        navigation_bestrating = -1;
 +      entity wp = navigation_get_really_close_waypoint(this);
        navigation_clearroute(this);
        navigation_bestgoal = NULL;
 -      navigation_markroutes(this, NULL);
 +      navigation_markroutes(this, wp);
  }
  
  // ends a goal selection session (updates goal stack to the best goal)
@@@ -1583,9 -1516,9 +1583,9 @@@ void navigation_unstuck(entity this
                // evaluate the next goal on the queue
                float d = vlen2(this.origin - bot_waypoint_queue_goal.origin);
                LOG_DEBUG(this.netname, " evaluating ", bot_waypoint_queue_goal.classname, " with distance ", ftos(d));
 -              vector dest = (bot_waypoint_queue_goal.absmin + bot_waypoint_queue_goal.absmax) * 0.5;
 -              dest.z = bot_waypoint_queue_goal.absmin.z;
 -              float dest_height = bot_waypoint_queue_goal.absmax.z - bot_waypoint_queue_goal.absmin.z;
 +              vector dest = '0 0 0';
 +              float dest_height = 0;
 +              SET_TRACEWALK_DESTCOORDS(bot_waypoint_queue_goal, this.origin, dest, dest_height);
                if(tracewalk(bot_waypoint_queue_goal, this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), dest, dest_height, bot_navigation_movemode))
                {
                        if( d > bot_waypoint_queue_bestgoalrating)
                        {
                                LOG_DEBUG(this.netname, " stuck, reachable waypoint found, heading to it");
                                navigation_routetogoal(this, bot_waypoint_queue_bestgoal, this.origin);
 -                              this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
 +                              navigation_goalrating_timeout_set(this);
                                this.aistatus &= ~AI_STATUS_STUCK;
                        }
                        else