]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/default/navigation.qc
Merge branch 'master' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / navigation.qc
index 250b7cb09c639e45680e699514958d769b97a686..9dc1e47aa37e326a626501b9e90d24fb51c63e49 100644 (file)
@@ -742,6 +742,7 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e
 // completely empty the goal stack, used when deciding where to go
 void navigation_clearroute(entity this)
 {
+       this.lastteleporttime = 0;
        this.goalcurrent_prev = this.goalcurrent;
        this.goalcurrent_distance_2d = FLOAT_MAX;
        this.goalcurrent_distance_z = FLOAT_MAX;
@@ -1331,10 +1332,10 @@ void navigation_routerating(entity this, entity e, float f, float rangebias)
                        t += xydistance / autocvar_g_jetpack_maxspeed_side;
                        fuel = t * autocvar_g_jetpack_fuel * 0.8;
 
-                       LOG_DEBUG("jetpack ai: required fuel ", ftos(fuel), ", have ", ftos(GetResourceAmount(this, RESOURCE_FUEL)));
+                       LOG_DEBUG("jetpack ai: required fuel ", ftos(fuel), ", have ", ftos(GetResource(this, RES_FUEL)));
 
                        // enough fuel ?
-                       if(GetResourceAmount(this, RESOURCE_FUEL) > fuel || (this.items & IT_UNLIMITED_WEAPON_AMMO))
+                       if(GetResource(this, RES_FUEL) > fuel || (this.items & IT_UNLIMITED_WEAPON_AMMO))
                        {
                                // Estimate cost
                                // (as onground costs calculation is mostly based on distances, here we do the same establishing some relationship
@@ -1608,6 +1609,17 @@ int navigation_poptouchedgoals(entity this)
 
        if(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
        {
+               if (!this.goalcurrent.wpisbox // warpzone
+                       && vlen2(this.origin - this.goalstack01.origin) < vlen2(this.origin - this.goalcurrent.origin))
+               {
+                       // immediately remove origin and destination waypoints
+                       navigation_poproute(this);
+                       ++removed_goals;
+                       navigation_poproute(this);
+                       ++removed_goals;
+                       this.lastteleporttime = 0;
+               }
+
                // make sure jumppad is really hit, don't rely on distance based checks
                // as they may report a touch even if it didn't really happen
                if(this.lastteleporttime > 0 && TELEPORT_USED(this, this.goalcurrent))
@@ -1628,12 +1640,17 @@ int navigation_poptouchedgoals(entity this)
                                if (time - this.lastteleporttime < random() * max_delay)
                                        return removed_goals;
                        }
+                       else if (this.goalcurrent.wpisbox) // teleport
+                       {
+                               // immediately remove origin and destination waypoints
+                               navigation_poproute(this);
+                               ++removed_goals;
+                       }
                        navigation_poproute(this);
                        this.lastteleporttime = 0;
                        ++removed_goals;
                }
-               else
-                       return removed_goals;
+               return removed_goals;
        }
        else if (this.lastteleporttime > 0)
        {
@@ -1665,6 +1682,9 @@ int navigation_poptouchedgoals(entity this)
                        ++removed_goals;
                        return removed_goals;
                }
+               // reset of lastteleporttime can be overriden by a jumppad when it's set
+               // in more than one frame: make sure it's reset
+               this.lastteleporttime = 0;
        }
 
        // Loose goal touching check when running
@@ -1786,6 +1806,7 @@ void navigation_goalrating_start(entity this)
        navigation_clearroute(this);
        navigation_bestgoal = NULL;
        navigation_markroutes(this, wp);
+       this.goalstack31 = wp; // temporarly save the really close waypoint
 }
 
 // ends a goal selection session (updates goal stack to the best goal)
@@ -1794,19 +1815,27 @@ void navigation_goalrating_end(entity this)
        if(this.aistatus & AI_STATUS_STUCK)
                return;
 
+       entity wp = this.goalstack31; // save to wp as this.goalstack31 is set by navigation_routetogoal
+       this.goalstack31 = NULL;
+
        navigation_routetogoal(this, navigation_bestgoal, this.origin);
        LOG_DEBUG("best goal ", this.goalcurrent.classname);
 
+       if (wp && this.goalcurrent == wp)
+               navigation_poproute(this);
+
        // If the bot got stuck then try to reach the farthest waypoint
-       if (!this.goalentity && autocvar_bot_wander_enable)
+       if (!this.goalentity)
        {
-               if (!(this.aistatus & AI_STATUS_STUCK))
+               if (autocvar_bot_wander_enable && !(this.aistatus & AI_STATUS_STUCK))
                {
                        LOG_DEBUG(this.netname, " cannot walk to any goal");
                        this.aistatus |= AI_STATUS_STUCK;
                }
+               this.goalentity_shouldbefrozen = false;
        }
-       this.goalentity_shouldbefrozen = boolean(STAT(FROZEN, this.goalentity));
+       else
+               this.goalentity_shouldbefrozen = boolean(STAT(FROZEN, this.goalentity));
 }
 
 void botframe_updatedangerousobjects(float maxupdate)