Xonotic
navigation.qh File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define navigation_item_add_link(from_wp, to_item, walkable)   waypoint_addlink_customcost(to_item, from_wp, (walkable ? waypoint_getlinkcost(from_wp, to_item) : 999))
 
#define navigation_item_getlinknum(to_item, from_wp)   waypoint_getlinknum(to_item, from_wp)
 
#define navigation_item_initlinks_ifneeded(e)   MACRO_BEGIN if (!e.wp00) waypoint_clearlinks(e); MACRO_END
 
#define navigation_item_iswalkablelink(to_item, from_wp)   (waypoint_get_assigned_link_cost(to_item, from_wp) < 999)
 
#define SUBMERGED_NO   1
 
#define SUBMERGED_UNDEFINED   0
 
#define SUBMERGED_YES   2
 
#define TELEPORT_USED(pl, tele_wp)   boxesoverlap(tele_wp.absmin, tele_wp.absmax, pl.lastteleport_origin + STAT(PL_MIN, pl), pl.lastteleport_origin + STAT(PL_MAX, pl))
 

Functions

void botframe_updatedangerousobjects (float maxupdate)
 
void debuggoalstack (entity this)
 
void debugnode (entity this, vector node)
 
void debugnodestatus (vector position, float status)
 
void debugresetnodes ()
 
bool navigation_check_submerged_state (entity ent, vector pos)
 
void navigation_clearroute (entity this)
 
void navigation_dynamicgoal_init (entity this, bool initially_static)
 
void navigation_dynamicgoal_set (entity this, entity dropper)
 
void navigation_dynamicgoal_unset (entity this)
 
entity navigation_findnearestwaypoint (entity ent, float walkfromwp)
 
void navigation_goalrating_end (entity this)
 
void navigation_goalrating_start (entity this)
 
bool navigation_goalrating_timeout (entity this)
 
void navigation_goalrating_timeout_force (entity this)
 
void navigation_goalrating_timeout_set (entity this)
 
void navigation_markroutes (entity this, entity fixed_source_waypoint)
 
void navigation_markroutes_checkwaypoint (entity w, entity wp, float cost2, vector p)
 
void navigation_markroutes_inverted (entity fixed_source_waypoint)
 
float navigation_markroutes_nearestwaypoints (entity this, float maxdist)
 
void navigation_poproute (entity this)
 
int navigation_poptouchedgoals (entity this)
 
void navigation_pushroute (entity this, entity e)
 
void navigation_routerating (entity this, entity e, float f, float rangebias)
 
float navigation_routetogoal (entity this, entity e, vector startposition)
 
bool navigation_shortenpath (entity this)
 
void navigation_unstuck (entity this)
 
float navigation_waypoint_will_link (vector v, vector org, entity ent, vector v2, float v2_height, vector o2, float o2_height, float walkfromwp, float bestdist)
 
float tracewalk (entity e, vector start, vector m1, vector m2, vector end, float end_height, float movemode)
 

Variables

float blacklisted
 
entity bot_basewaypoint
 
const float BOT_BUNNYHOP_WP_DETECTION_RANGE = 100
 
float bot_navigation_movemode
 
entity bot_waypoint_queue_bestgoal
 
float bot_waypoint_queue_bestgoalrating
 
entity bot_waypoint_queue_goal
 
entity bot_waypoint_queue_nextgoal
 
entity bot_waypoint_queue_owner
 
const float DEBUG_NODE_FAIL = 3
 
const float DEBUG_NODE_SUCCESS = 1
 
const float DEBUG_NODE_WARNING = 2
 
vector debuglastnode
 
entity goalcurrent
 
float goalcurrent_distance_2d
 
float goalcurrent_distance_time
 
float goalcurrent_distance_z
 
entity goalcurrent_prev
 
entity goalentity
 
float goalentity_lock_timeout
 
bool goalentity_shouldbefrozen
 
entity goalstack01
 
entity goalstack02
 
entity goalstack03
 
entity goalstack04
 
entity goalstack05
 
entity goalstack06
 
entity goalstack07
 
entity goalstack08
 
entity goalstack09
 
entity goalstack10
 
entity goalstack11
 
entity goalstack12
 
entity goalstack13
 
entity goalstack14
 
entity goalstack15
 
entity goalstack16
 
entity goalstack17
 
entity goalstack18
 
entity goalstack19
 
entity goalstack20
 
entity goalstack21
 
entity goalstack22
 
entity goalstack23
 
entity goalstack24
 
entity goalstack25
 
entity goalstack26
 
entity goalstack27
 
entity goalstack28
 
entity goalstack29
 
entity goalstack30
 
entity goalstack31
 
float jumpheight_time
 
vector jumpheight_vec
 
vector jumpstepheightvec
 
vector lastteleport_origin
 
float lastteleporttime
 
int nav_submerged_state
 
entity navigation_bestgoal
 
float navigation_bestrating
 
bool navigation_dynamicgoal
 
entity navigation_jetpack_goal
 
vector navigation_jetpack_point
 
float navigation_testtracewalk
 
entity nearestwaypoint
 
float nearestwaypointtimeout
 
vector stepheightvec
 
vector tracewalk_dest
 
float tracewalk_dest_height
 
entity wp_goal_prev0
 
entity wp_goal_prev1
 

Macro Definition Documentation

◆ navigation_item_add_link

#define navigation_item_add_link (   from_wp,
  to_item,
  walkable 
)    waypoint_addlink_customcost(to_item, from_wp, (walkable ? waypoint_getlinkcost(from_wp, to_item) : 999))

Definition at line 60 of file navigation.qh.

Referenced by navigation_routetogoal().

◆ navigation_item_getlinknum

#define navigation_item_getlinknum (   to_item,
  from_wp 
)    waypoint_getlinknum(to_item, from_wp)

Definition at line 57 of file navigation.qh.

Referenced by navigation_routetogoal().

◆ navigation_item_initlinks_ifneeded

#define navigation_item_initlinks_ifneeded (   e)    MACRO_BEGIN if (!e.wp00) waypoint_clearlinks(e); MACRO_END

Definition at line 56 of file navigation.qh.

Referenced by navigation_routetogoal().

◆ navigation_item_iswalkablelink

#define navigation_item_iswalkablelink (   to_item,
  from_wp 
)    (waypoint_get_assigned_link_cost(to_item, from_wp) < 999)

Definition at line 58 of file navigation.qh.

Referenced by navigation_routetogoal().

◆ SUBMERGED_NO

#define SUBMERGED_NO   1

Definition at line 101 of file navigation.qh.

Referenced by navigation_check_submerged_state().

◆ SUBMERGED_UNDEFINED

#define SUBMERGED_UNDEFINED   0

Definition at line 100 of file navigation.qh.

Referenced by navigation_check_submerged_state().

◆ SUBMERGED_YES

#define SUBMERGED_YES   2

Definition at line 102 of file navigation.qh.

Referenced by navigation_check_submerged_state().

◆ TELEPORT_USED

#define TELEPORT_USED (   pl,
  tele_wp 
)    boxesoverlap(tele_wp.absmin, tele_wp.absmax, pl.lastteleport_origin + STAT(PL_MIN, pl), pl.lastteleport_origin + STAT(PL_MAX, pl))

Definition at line 63 of file navigation.qh.

Referenced by navigation_poptouchedgoals().

Function Documentation

◆ botframe_updatedangerousobjects()

void botframe_updatedangerousobjects ( float  maxupdate)

Definition at line 1873 of file navigation.qc.

References entity(), g_bot_dodge, g_waypoints, IL_EACH, v, and vector().

Referenced by bot_serverframe().

1874 {
1875  vector m1, m2, v, o;
1876  float c, d, danger;
1877  c = 0;
1878  entity wp_cur;
1879  IL_EACH(g_waypoints, true,
1880  {
1881  danger = 0;
1882  m1 = it.absmin;
1883  m2 = it.absmax;
1884  wp_cur = it;
1885  IL_EACH(g_bot_dodge, it.bot_dodge,
1886  {
1887  v = it.origin;
1888  v.x = bound(m1_x, v.x, m2_x);
1889  v.y = bound(m1_y, v.y, m2_y);
1890  v.z = bound(m1_z, v.z, m2_z);
1891  o = (it.absmin + it.absmax) * 0.5;
1892  d = waypoint_getlinearcost(it.bot_dodgerating) - waypoint_gettravelcost(o, v, it, wp_cur);
1893  if (d > 0)
1894  {
1895  traceline(o, v, true, NULL);
1896  if (trace_fraction == 1)
1897  danger = danger + d;
1898  }
1899  });
1900  it.dmg = danger;
1901  c = c + 1;
1902  if (c >= maxupdate)
1903  break;
1904  });
1905 }
#define IL_EACH(this, cond, body)
entity() spawn
IntrusiveList g_bot_dodge
Definition: api.qh:150
IntrusiveList g_waypoints
Definition: api.qh:148
vector(float skel, float bonenum) _skel_get_boneabs_hidden
vector v
Definition: ent_cs.qc:116
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ debuggoalstack()

void debuggoalstack ( entity  this)

Definition at line 2061 of file navigation.qc.

References entity(), goalcounter, goalcurrent, goalstack01, goalstack02, goalstack03, goalstack04, goalstack05, goalstack06, goalstack07, goalstack08, goalstack09, goalstack10, goalstack11, goalstack12, goalstack13, goalstack14, goalstack15, goalstack16, goalstack17, goalstack18, goalstack19, goalstack20, goalstack21, goalstack22, goalstack23, goalstack24, goalstack25, goalstack26, goalstack27, goalstack28, goalstack29, goalstack30, goalstack31, lastposition, NULL, origin, and vector().

Referenced by havocbot_moveto(), and havocbot_movetogoal().

2062 {
2063  entity goal;
2064  vector org, go;
2065 
2066  if(this.goalcounter==0)goal=this.goalcurrent;
2067  else if(this.goalcounter==1)goal=this.goalstack01;
2068  else if(this.goalcounter==2)goal=this.goalstack02;
2069  else if(this.goalcounter==3)goal=this.goalstack03;
2070  else if(this.goalcounter==4)goal=this.goalstack04;
2071  else if(this.goalcounter==5)goal=this.goalstack05;
2072  else if(this.goalcounter==6)goal=this.goalstack06;
2073  else if(this.goalcounter==7)goal=this.goalstack07;
2074  else if(this.goalcounter==8)goal=this.goalstack08;
2075  else if(this.goalcounter==9)goal=this.goalstack09;
2076  else if(this.goalcounter==10)goal=this.goalstack10;
2077  else if(this.goalcounter==11)goal=this.goalstack11;
2078  else if(this.goalcounter==12)goal=this.goalstack12;
2079  else if(this.goalcounter==13)goal=this.goalstack13;
2080  else if(this.goalcounter==14)goal=this.goalstack14;
2081  else if(this.goalcounter==15)goal=this.goalstack15;
2082  else if(this.goalcounter==16)goal=this.goalstack16;
2083  else if(this.goalcounter==17)goal=this.goalstack17;
2084  else if(this.goalcounter==18)goal=this.goalstack18;
2085  else if(this.goalcounter==19)goal=this.goalstack19;
2086  else if(this.goalcounter==20)goal=this.goalstack20;
2087  else if(this.goalcounter==21)goal=this.goalstack21;
2088  else if(this.goalcounter==22)goal=this.goalstack22;
2089  else if(this.goalcounter==23)goal=this.goalstack23;
2090  else if(this.goalcounter==24)goal=this.goalstack24;
2091  else if(this.goalcounter==25)goal=this.goalstack25;
2092  else if(this.goalcounter==26)goal=this.goalstack26;
2093  else if(this.goalcounter==27)goal=this.goalstack27;
2094  else if(this.goalcounter==28)goal=this.goalstack28;
2095  else if(this.goalcounter==29)goal=this.goalstack29;
2096  else if(this.goalcounter==30)goal=this.goalstack30;
2097  else if(this.goalcounter==31)goal=this.goalstack31;
2098  else goal=NULL;
2099 
2100  if(goal==NULL)
2101  {
2102  this.goalcounter = 0;
2103  this.lastposition='0 0 0';
2104  return;
2105  }
2106 
2107  if(this.lastposition=='0 0 0')
2108  org = this.origin;
2109  else
2110  org = this.lastposition;
2111 
2112 
2113  go = ( goal.absmin + goal.absmax ) * 0.5;
2114  te_lightning2(NULL, org, go);
2115  this.lastposition = go;
2116 
2117  this.goalcounter++;
2118 }
entity() spawn
origin
Definition: ent_cs.qc:114
#define NULL
Definition: post.qh:17
vector(float skel, float bonenum) _skel_get_boneabs_hidden
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ debugnode()

void debugnode ( entity  this,
vector  node 
)

Definition at line 2018 of file navigation.qc.

References debuglastnode, IS_PLAYER, and NULL.

Referenced by tracewalk().

2019 {
2020  if (!IS_PLAYER(this))
2021  return;
2022 
2023  if(debuglastnode=='0 0 0')
2024  {
2025  debuglastnode = node;
2026  return;
2027  }
2028 
2029  te_lightning2(NULL, node, debuglastnode);
2030  debuglastnode = node;
2031 }
#define NULL
Definition: post.qh:17
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the caller graph for this function:

◆ debugnodestatus()

void debugnodestatus ( vector  position,
float  status 
)

Definition at line 2033 of file navigation.qc.

References DEBUG_NODE_FAIL, DEBUG_NODE_SUCCESS, DEBUG_NODE_WARNING, and vector().

Referenced by tracewalk().

2034 {
2035  vector c;
2036 
2037  switch (status)
2038  {
2039  case DEBUG_NODE_SUCCESS:
2040  c = '0 15 0';
2041  break;
2042  case DEBUG_NODE_WARNING:
2043  c = '15 15 0';
2044  break;
2045  case DEBUG_NODE_FAIL:
2046  c = '15 0 0';
2047  break;
2048  default:
2049  c = '15 15 15';
2050  }
2051 
2052  te_customflash(position, 40, 2, c);
2053 }
vector(float skel, float bonenum) _skel_get_boneabs_hidden
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ debugresetnodes()

void debugresetnodes ( )

Definition at line 2013 of file navigation.qc.

References debuglastnode.

Referenced by tracewalk().

2014 {
2015  debuglastnode = '0 0 0';
2016 }
+ Here is the caller graph for this function:

◆ navigation_check_submerged_state()

bool navigation_check_submerged_state ( entity  ent,
vector  pos 
)

Definition at line 203 of file navigation.qc.

References IS_PLAYER, SUBMERGED, SUBMERGED_NO, SUBMERGED_UNDEFINED, SUBMERGED_YES, and WATERLEVEL_SUBMERGED.

Referenced by waypoint_gettravelcost().

204 {
205  bool submerged;
206  if(IS_PLAYER(ent))
207  submerged = (ent.waterlevel == WATERLEVEL_SUBMERGED);
208  else if(ent.nav_submerged_state != SUBMERGED_UNDEFINED)
209  submerged = (ent.nav_submerged_state == SUBMERGED_YES);
210  else
211  {
212  submerged = SUBMERGED(pos);
213  // NOTE: SUBMERGED check of box waypoint origin may fail even if origin
214  // is actually submerged because often they are inside some solid.
215  // That's why submerged state is saved now that we know current pos is
216  // not stuck in solid (previous tracewalk call to this pos was successfully)
217  if(!ent.navigation_dynamicgoal)
218  ent.nav_submerged_state = (submerged) ? SUBMERGED_YES : SUBMERGED_NO;
219  }
220  return submerged;
221 }
const int WATERLEVEL_SUBMERGED
Definition: movetypes.qh:14
#define SUBMERGED(pos)
Definition: bot.qh:85
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the caller graph for this function:

◆ navigation_clearroute()

void navigation_clearroute ( entity  this)

Definition at line 750 of file navigation.qc.

References FLOAT_MAX, goalcurrent, goalcurrent_distance_2d, goalcurrent_distance_time, goalcurrent_distance_z, goalcurrent_prev, goalentity, goalentity_lock_timeout, goalentity_shouldbefrozen, goalstack01, goalstack02, goalstack03, goalstack04, goalstack05, goalstack06, goalstack07, goalstack08, goalstack09, goalstack10, goalstack11, goalstack12, goalstack13, goalstack14, goalstack15, goalstack16, goalstack17, goalstack18, goalstack19, goalstack20, goalstack21, goalstack22, goalstack23, goalstack24, goalstack25, goalstack26, goalstack27, goalstack28, goalstack29, goalstack30, goalstack31, lastteleporttime, and NULL.

Referenced by havocbot_ai(), havocbot_movetogoal(), havocbot_resetgoal(), navigation_goalrating_start(), and navigation_unstuck().

751 {
752  this.lastteleporttime = 0;
753  this.goalcurrent_prev = this.goalcurrent;
756  this.goalcurrent_distance_time = 0;
757  this.goalentity_lock_timeout = 0;
758  this.goalentity_shouldbefrozen = false;
759  this.goalentity = NULL;
760  this.goalcurrent = NULL;
761  this.goalstack01 = NULL;
762  this.goalstack02 = NULL;
763  this.goalstack03 = NULL;
764  this.goalstack04 = NULL;
765  this.goalstack05 = NULL;
766  this.goalstack06 = NULL;
767  this.goalstack07 = NULL;
768  this.goalstack08 = NULL;
769  this.goalstack09 = NULL;
770  this.goalstack10 = NULL;
771  this.goalstack11 = NULL;
772  this.goalstack12 = NULL;
773  this.goalstack13 = NULL;
774  this.goalstack14 = NULL;
775  this.goalstack15 = NULL;
776  this.goalstack16 = NULL;
777  this.goalstack17 = NULL;
778  this.goalstack18 = NULL;
779  this.goalstack19 = NULL;
780  this.goalstack20 = NULL;
781  this.goalstack21 = NULL;
782  this.goalstack22 = NULL;
783  this.goalstack23 = NULL;
784  this.goalstack24 = NULL;
785  this.goalstack25 = NULL;
786  this.goalstack26 = NULL;
787  this.goalstack27 = NULL;
788  this.goalstack28 = NULL;
789  this.goalstack29 = NULL;
790  this.goalstack30 = NULL;
791  this.goalstack31 = NULL;
792 }
float goalentity_lock_timeout
Definition: api.qh:97
entity goalentity
Definition: progsdefs.qc:189
#define NULL
Definition: post.qh:17
float lastteleporttime
Definition: api.qh:50
const float FLOAT_MAX
Definition: float.qh:3
+ Here is the caller graph for this function:

◆ navigation_dynamicgoal_init()

void navigation_dynamicgoal_init ( entity  this,
bool  initially_static 
)

Definition at line 76 of file navigation.qc.

References bot_basewaypoint, navigation_dynamicgoal, nearestwaypoint, nearestwaypointtimeout, and time.

77 {
78  this.navigation_dynamicgoal = true;
80  if(initially_static)
81  this.nearestwaypointtimeout = -1;
82  else
84 }
float nearestwaypointtimeout
Definition: api.qh:53
bool navigation_dynamicgoal
Definition: api.qh:107
entity bot_basewaypoint
Definition: api.qh:106
entity nearestwaypoint
Definition: api.qh:54
float time
Definition: csprogsdefs.qc:16

◆ navigation_dynamicgoal_set()

void navigation_dynamicgoal_set ( entity  this,
entity  dropper 
)

Definition at line 86 of file navigation.qc.

References nearestwaypoint, nearestwaypointtimeout, and time.

87 {
89  if (dropper && dropper.nearestwaypointtimeout && dropper.nearestwaypointtimeout < time + 2)
90  this.nearestwaypoint = dropper.nearestwaypoint;
91  if (this.nearestwaypoint)
92  this.nearestwaypointtimeout += 2;
93 }
float nearestwaypointtimeout
Definition: api.qh:53
entity nearestwaypoint
Definition: api.qh:54
float time
Definition: csprogsdefs.qc:16

◆ navigation_dynamicgoal_unset()

void navigation_dynamicgoal_unset ( entity  this)

Definition at line 95 of file navigation.qc.

References bot_basewaypoint, nearestwaypoint, and nearestwaypointtimeout.

96 {
97  if(this.bot_basewaypoint)
99  this.nearestwaypointtimeout = -1;
100 }
float nearestwaypointtimeout
Definition: api.qh:53
entity bot_basewaypoint
Definition: api.qh:106
entity nearestwaypoint
Definition: api.qh:54

◆ navigation_findnearestwaypoint()

entity navigation_findnearestwaypoint ( entity  ent,
float  walkfromwp 
)

Definition at line 1011 of file navigation.qc.

References autocvar_g_waypointeditor_auto, entity(), navigation_findnearestwaypoint_withdist_except(), NULL, and WAYPOINTFLAG_PROTECTED.

Referenced by navigation_routerating().

1012 {
1013  entity wp = navigation_findnearestwaypoint_withdist_except(ent, walkfromwp, 1050, NULL);
1015  {
1016  entity wp2 = navigation_findnearestwaypoint_withdist_except(ent, walkfromwp, 1050, wp);
1017  if (wp && !wp2)
1018  wp.wpflags |= WAYPOINTFLAG_PROTECTED;
1019  }
1020  return wp;
1021 }
const int WAYPOINTFLAG_PROTECTED
Definition: api.qh:16
entity() spawn
int autocvar_g_waypointeditor_auto
Definition: cvars.qh:63
#define NULL
Definition: post.qh:17
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ navigation_goalrating_end()

void navigation_goalrating_end ( entity  this)

Definition at line 1845 of file navigation.qc.

References AI_STATUS_STUCK, aistatus, autocvar_bot_wander_enable, boolean, entity(), goalcurrent, goalentity, goalentity_shouldbefrozen, goalstack31, LOG_DEBUG, navigation_bestgoal, navigation_poproute(), navigation_routetogoal(), netname, NULL, and origin.

1846 {
1847  if(this.aistatus & AI_STATUS_STUCK)
1848  return;
1849 
1850  entity wp = this.goalstack31; // save to wp as this.goalstack31 is set by navigation_routetogoal
1851  this.goalstack31 = NULL;
1852 
1854  LOG_DEBUG("best goal ", navigation_bestgoal.classname);
1855 
1856  if (wp && this.goalcurrent == wp)
1857  navigation_poproute(this);
1858 
1859  // If the bot got stuck then try to reach the farthest waypoint
1860  if (!this.goalentity)
1861  {
1862  if (autocvar_bot_wander_enable && !(this.aistatus & AI_STATUS_STUCK))
1863  {
1864  LOG_DEBUG(this.netname, " cannot walk to any goal");
1865  this.aistatus |= AI_STATUS_STUCK;
1866  }
1867  this.goalentity_shouldbefrozen = false;
1868  }
1869  else
1870  this.goalentity_shouldbefrozen = boolean(STAT(FROZEN, this.goalentity));
1871 }
int aistatus
Definition: bot.qh:20
entity() spawn
string netname
Definition: powerups.qc:20
origin
Definition: ent_cs.qc:114
entity goalentity
Definition: progsdefs.qc:189
#define NULL
Definition: post.qh:17
bool autocvar_bot_wander_enable
Definition: cvars.qh:60
const int AI_STATUS_STUCK
Definition: bot.qh:17
#define boolean(value)
Definition: bool.qh:9
#define LOG_DEBUG(...)
Definition: log.qh:85
+ Here is the call graph for this function:

◆ navigation_goalrating_start()

void navigation_goalrating_start ( entity  this)

Definition at line 1830 of file navigation.qc.

References AI_STATUS_STUCK, aistatus, entity(), goalstack31, navigation_bestgoal, navigation_bestrating, navigation_clearroute(), navigation_get_really_close_waypoint(), navigation_jetpack_goal, navigation_markroutes(), and NULL.

1831 {
1832  if(this.aistatus & AI_STATUS_STUCK)
1833  return;
1834 
1836  navigation_bestrating = -1;
1838  navigation_clearroute(this);
1840  navigation_markroutes(this, wp);
1841  this.goalstack31 = wp; // temporarly save the really close waypoint
1842 }
int aistatus
Definition: bot.qh:20
entity() spawn
#define NULL
Definition: post.qh:17
const int AI_STATUS_STUCK
Definition: bot.qh:17
+ Here is the call graph for this function:

◆ navigation_goalrating_timeout()

bool navigation_goalrating_timeout ( entity  this)

Definition at line 43 of file navigation.qc.

References bot_strategytime, ERASEABLE, and time.

44 {
45  return this.bot_strategytime < time;
46 }
float bot_strategytime
Definition: bot.qh:69
float time
Definition: csprogsdefs.qc:16

◆ navigation_goalrating_timeout_force()

void navigation_goalrating_timeout_force ( entity  this)

Definition at line 28 of file navigation.qc.

References navigation_goalrating_timeout_expire().

29 {
31 }
+ Here is the call graph for this function:

◆ navigation_goalrating_timeout_set()

void navigation_goalrating_timeout_set ( entity  this)

Definition at line 19 of file navigation.qc.

References autocvar_bot_ai_strategyinterval, autocvar_bot_ai_strategyinterval_movingtarget, bot_strategytime, goalentity, IS_MOVABLE, and time.

Referenced by navigation_unstuck().

20 {
21  if(IS_MOVABLE(this.goalentity))
23  else
25 }
float autocvar_bot_ai_strategyinterval
Definition: cvars.qh:68
#define IS_MOVABLE(v)
Definition: utils.qh:25
float autocvar_bot_ai_strategyinterval_movingtarget
Definition: cvars.qh:69
entity goalentity
Definition: progsdefs.qc:189
float bot_strategytime
Definition: bot.qh:69
float time
Definition: csprogsdefs.qc:16
+ Here is the caller graph for this function:

◆ navigation_markroutes()

void navigation_markroutes ( entity  this,
entity  fixed_source_waypoint 
)

Definition at line 1081 of file navigation.qc.

References g_waypoints, IL_EACH, IS_ONGROUND, navigation_markroutes_nearestwaypoints(), NULL, and vector().

Referenced by navigation_goalrating_start().

1082 {
1083  float cost, cost2;
1084  vector p;
1085 
1086  IL_EACH(g_waypoints, true,
1087  {
1088  it.wpconsidered = false;
1089  it.wpnearestpoint = '0 0 0';
1090  it.wpcost = 10000000;
1091  it.wpfire = 0;
1092  it.enemy = NULL;
1093  });
1094 
1095  if(fixed_source_waypoint)
1096  {
1097  fixed_source_waypoint.wpconsidered = true;
1098  fixed_source_waypoint.wpnearestpoint = fixed_source_waypoint.origin + 0.5 * (fixed_source_waypoint.mins + fixed_source_waypoint.maxs);
1099  fixed_source_waypoint.wpcost = fixed_source_waypoint.dmg;
1100  fixed_source_waypoint.wpfire = 1;
1101  fixed_source_waypoint.enemy = NULL;
1102  }
1103  else
1104  {
1105  // try a short range search for the nearest waypoints, and expand the search repeatedly if none are found
1106  // as this search is expensive we will use lower values if the bot is on the air
1107  float increment, maxdistance;
1108  if(IS_ONGROUND(this))
1109  {
1110  increment = 750;
1111  maxdistance = 50000;
1112  }
1113  else
1114  {
1115  increment = 500;
1116  maxdistance = 1500;
1117  }
1118 
1119  for(int j = increment; !navigation_markroutes_nearestwaypoints(this, j) && j < maxdistance; j += increment);
1120  }
1121 
1122  bool searching = true;
1123  while (searching)
1124  {
1125  searching = false;
1126  IL_EACH(g_waypoints, it.wpfire,
1127  {
1128  searching = true;
1129  it.wpfire = 0;
1130  cost = it.wpcost;
1131  p = it.wpnearestpoint;
1132  entity wp;
1133  wp = it.wp00;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp00mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1134  wp = it.wp01;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp01mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1135  wp = it.wp02;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp02mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1136  wp = it.wp03;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp03mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1137  wp = it.wp04;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp04mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1138  wp = it.wp05;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp05mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1139  wp = it.wp06;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp06mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1140  wp = it.wp07;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp07mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1141  wp = it.wp08;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp08mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1142  wp = it.wp09;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp09mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1143  wp = it.wp10;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp10mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1144  wp = it.wp11;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp11mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1145  wp = it.wp12;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp12mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1146  wp = it.wp13;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp13mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1147  wp = it.wp14;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp14mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1148  wp = it.wp15;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp15mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1149  wp = it.wp16;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp16mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1150  wp = it.wp17;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp17mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1151  wp = it.wp18;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp18mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1152  wp = it.wp19;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp19mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1153  wp = it.wp20;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp20mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1154  wp = it.wp21;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp21mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1155  wp = it.wp22;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp22mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1156  wp = it.wp23;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp23mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1157  wp = it.wp24;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp24mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1158  wp = it.wp25;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp25mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1159  wp = it.wp26;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp26mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1160  wp = it.wp27;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp27mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1161  wp = it.wp28;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp28mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1162  wp = it.wp29;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp29mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1163  wp = it.wp30;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp30mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1164  wp = it.wp31;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp31mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
1165  }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
1166  });
1167  }
1168 }
#define IL_EACH(this, cond, body)
#define IS_ONGROUND(s)
Definition: movetypes.qh:16
#define NULL
Definition: post.qh:17
IntrusiveList g_waypoints
Definition: api.qh:148
vector(float skel, float bonenum) _skel_get_boneabs_hidden
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ navigation_markroutes_checkwaypoint()

void navigation_markroutes_checkwaypoint ( entity  w,
entity  wp,
float  cost2,
vector  p 
)

Definition at line 1053 of file navigation.qc.

References bound(), v, vector(), waypoint_gettravelcost(), and WAYPOINTFLAG_TELEPORT.

1054 {
1055  vector m1, m2;
1056  vector v;
1057  if (wp.wpisbox)
1058  {
1059  m1 = wp.origin + wp.mins;
1060  m2 = wp.origin + wp.maxs;
1061  v.x = bound(m1_x, p.x, m2_x);
1062  v.y = bound(m1_y, p.y, m2_y);
1063  v.z = bound(m1_z, p.z, m2_z);
1064  }
1065  else
1066  v = wp.origin;
1067  if (w.wpflags & WAYPOINTFLAG_TELEPORT)
1068  cost += w.wp00mincost; // assuming teleport has exactly one destination
1069  else
1070  cost += waypoint_gettravelcost(p, v, w, wp);
1071  if (wp.wpcost > cost)
1072  {
1073  wp.wpcost = cost;
1074  wp.enemy = w;
1075  wp.wpfire = 1;
1076  wp.wpnearestpoint = v;
1077  }
1078 }
float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent)
Definition: waypoints.qc:1030
const int WAYPOINTFLAG_TELEPORT
Definition: api.qh:13
vector(float skel, float bonenum) _skel_get_boneabs_hidden
vector v
Definition: ent_cs.qc:116
+ Here is the call graph for this function:

◆ navigation_markroutes_inverted()

void navigation_markroutes_inverted ( entity  fixed_source_waypoint)

Definition at line 1171 of file navigation.qc.

References error(), g_waypoints, IL_EACH, NULL, and vector().

1172 {
1173  float cost, cost2;
1174  vector p;
1175  IL_EACH(g_waypoints, true,
1176  {
1177  it.wpconsidered = false;
1178  it.wpnearestpoint = '0 0 0';
1179  it.wpcost = 10000000;
1180  it.wpfire = 0;
1181  it.enemy = NULL;
1182  });
1183 
1184  if(fixed_source_waypoint)
1185  {
1186  fixed_source_waypoint.wpconsidered = true;
1187  fixed_source_waypoint.wpnearestpoint = fixed_source_waypoint.origin + 0.5 * (fixed_source_waypoint.mins + fixed_source_waypoint.maxs);
1188  fixed_source_waypoint.wpcost = fixed_source_waypoint.dmg; // the cost to get from X to fixed_source_waypoint
1189  fixed_source_waypoint.wpfire = 1;
1190  fixed_source_waypoint.enemy = NULL;
1191  }
1192  else
1193  {
1194  error("need to start with a waypoint\n");
1195  }
1196 
1197  bool searching = true;
1198  while (searching)
1199  {
1200  searching = false;
1201  IL_EACH(g_waypoints, it.wpfire,
1202  {
1203  searching = true;
1204  it.wpfire = 0;
1205  cost = it.wpcost; // cost to walk from it to home
1206  p = it.wpnearestpoint;
1207  entity wp = it;
1208  IL_EACH(g_waypoints, it != wp,
1209  {
1210  if(!waypoint_islinked(it, wp))
1211  continue;
1212  cost2 = cost + it.dmg;
1213  navigation_markroutes_checkwaypoint(wp, it, cost2, p);
1214  });
1215  });
1216  }
1217 }
#define IL_EACH(this, cond, body)
#define NULL
Definition: post.qh:17
IntrusiveList g_waypoints
Definition: api.qh:148
vector(float skel, float bonenum) _skel_get_boneabs_hidden
+ Here is the call graph for this function:

◆ navigation_markroutes_nearestwaypoints()

float navigation_markroutes_nearestwaypoints ( entity  this,
float  maxdist 
)

Definition at line 1024 of file navigation.qc.

References g_waypoints, and IL_EACH.

Referenced by navigation_markroutes().

1025 {
1026  //navigation_testtracewalk = true;
1027  int c = 0;
1028  IL_EACH(g_waypoints, !it.wpconsidered,
1029  {
1030  set_tracewalk_dest(it, this.origin, false);
1031 
1032  vector diff = tracewalk_dest - this.origin;
1033  diff.z = max(0, diff.z);
1034  if(vdist(diff, <, maxdist))
1035  {
1036  it.wpconsidered = true;
1037  if (tracewalk(this, this.origin, this.mins, this.maxs,
1038  tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode))
1039  {
1040  it.wpnearestpoint = tracewalk_dest;
1041  it.wpcost = waypoint_gettravelcost(this.origin, tracewalk_dest, this, it) + it.dmg;
1042  it.wpfire = 1;
1043  it.enemy = NULL;
1044  c = c + 1;
1045  }
1046  }
1047  });
1048  //navigation_testtracewalk = false;
1049  return c;
1050 }
#define IL_EACH(this, cond, body)
IntrusiveList g_waypoints
Definition: api.qh:148
+ Here is the caller graph for this function:

◆ navigation_poproute()

void navigation_poproute ( entity  this)

Definition at line 846 of file navigation.qc.

References FLOAT_MAX, goalcurrent, goalcurrent_distance_2d, goalcurrent_distance_time, goalcurrent_distance_z, goalcurrent_prev, goalentity, goalentity_lock_timeout, goalstack01, goalstack02, goalstack03, goalstack04, goalstack05, goalstack06, goalstack07, goalstack08, goalstack09, goalstack10, goalstack11, goalstack12, goalstack13, goalstack14, goalstack15, goalstack16, goalstack17, goalstack18, goalstack19, goalstack20, goalstack21, goalstack22, goalstack23, goalstack24, goalstack25, goalstack26, goalstack27, goalstack28, goalstack29, goalstack30, goalstack31, and NULL.

Referenced by navigation_goalrating_end(), navigation_poptouchedgoals(), and navigation_shortenpath().

847 {
848  this.goalcurrent_prev = this.goalcurrent;
851  this.goalcurrent_distance_time = 0;
852  //print("bot ", etos(this), " pop\n");
853  if(this.goalcurrent == this.goalentity)
854  {
855  this.goalentity = NULL;
856  this.goalentity_lock_timeout = 0;
857  }
858  this.goalcurrent = this.goalstack01;
859  this.goalstack01 = this.goalstack02;
860  this.goalstack02 = this.goalstack03;
861  this.goalstack03 = this.goalstack04;
862  this.goalstack04 = this.goalstack05;
863  this.goalstack05 = this.goalstack06;
864  this.goalstack06 = this.goalstack07;
865  this.goalstack07 = this.goalstack08;
866  this.goalstack08 = this.goalstack09;
867  this.goalstack09 = this.goalstack10;
868  this.goalstack10 = this.goalstack11;
869  this.goalstack11 = this.goalstack12;
870  this.goalstack12 = this.goalstack13;
871  this.goalstack13 = this.goalstack14;
872  this.goalstack14 = this.goalstack15;
873  this.goalstack15 = this.goalstack16;
874  this.goalstack16 = this.goalstack17;
875  this.goalstack17 = this.goalstack18;
876  this.goalstack18 = this.goalstack19;
877  this.goalstack19 = this.goalstack20;
878  this.goalstack20 = this.goalstack21;
879  this.goalstack21 = this.goalstack22;
880  this.goalstack22 = this.goalstack23;
881  this.goalstack23 = this.goalstack24;
882  this.goalstack24 = this.goalstack25;
883  this.goalstack25 = this.goalstack26;
884  this.goalstack26 = this.goalstack27;
885  this.goalstack27 = this.goalstack28;
886  this.goalstack28 = this.goalstack29;
887  this.goalstack29 = this.goalstack30;
888  this.goalstack30 = this.goalstack31;
889  this.goalstack31 = NULL;
890 }
float goalentity_lock_timeout
Definition: api.qh:97
entity goalentity
Definition: progsdefs.qc:189
#define NULL
Definition: post.qh:17
const float FLOAT_MAX
Definition: float.qh:3
+ Here is the caller graph for this function:

◆ navigation_poptouchedgoals()

int navigation_poptouchedgoals ( entity  this)

Definition at line 1629 of file navigation.qc.

References absmax, absmin, AI_STATUS_RUNNING, AI_STATUS_WAYPOINT_PERSONAL_GOING, AI_STATUS_WAYPOINT_PERSONAL_REACHED, aistatus, BOT_BUNNYHOP_WP_DETECTION_RANGE, boxesoverlap(), entity(), eZ, goalcurrent, goalstack01, goalstack02, goalstack03, IS_PLAYER, jumpheight_vec, jumppadcount, ladder_entity, lastteleporttime, navigation_poproute(), NULL, origin, random(), TELEPORT_USED, time, trace_fraction, vdist, vec2, vector(), velocity, view_ofs, vlen2, WAYPOINTFLAG_JUMP, WAYPOINTFLAG_PERSONAL, and WAYPOINTFLAG_TELEPORT.

Referenced by havocbot_movetogoal().

1630 {
1631  int removed_goals = 0;
1632 
1633  if(!this.goalcurrent)
1634  return removed_goals;
1635 
1636  if(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
1637  {
1638  if (!this.goalcurrent.wpisbox // warpzone
1639  && vlen2(this.origin - this.goalstack01.origin) < vlen2(this.origin - this.goalcurrent.origin))
1640  {
1641  // immediately remove origin and destination waypoints
1642  navigation_poproute(this);
1643  ++removed_goals;
1644  navigation_poproute(this);
1645  ++removed_goals;
1646  this.lastteleporttime = 0;
1647  }
1648 
1649  // make sure jumppad is really hit, don't rely on distance based checks
1650  // as they may report a touch even if it didn't really happen
1651  if(this.lastteleporttime > 0 && TELEPORT_USED(this, this.goalcurrent))
1652  {
1654  if((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) && this.goalcurrent.owner==this)
1655  {
1656  this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
1658  }
1659  if(this.jumppadcount)
1660  {
1661  // remove jumppad waypoint after a random delay to prevent bots getting
1662  // stuck on certain jumppads that require an extra initial horizontal speed
1663  float max_delay = 0.1;
1664  if (vdist(vec2(this.velocity), >, 2 * autocvar_sv_maxspeed))
1665  max_delay = 0.05;
1666  if (time - this.lastteleporttime < random() * max_delay)
1667  return removed_goals;
1668  }
1669  else if (this.goalcurrent.wpisbox) // teleport
1670  {
1671  // immediately remove origin and destination waypoints
1672  navigation_poproute(this);
1673  ++removed_goals;
1674  }
1675  navigation_poproute(this);
1676  this.lastteleporttime = 0;
1677  ++removed_goals;
1678  }
1679  return removed_goals;
1680  }
1681  else if (this.lastteleporttime > 0)
1682  {
1683  // sometimes bot is pushed so hard (by a jumppad or a shot) that ends up touching the next
1684  // teleport / jumppad / warpzone present in its path skipping check of one or more goals
1685  // if so immediately fix bot path by removing skipped goals
1686  entity tele_ent = NULL;
1687  if (this.goalstack01 && (this.goalstack01.wpflags & WAYPOINTFLAG_TELEPORT))
1688  tele_ent = this.goalstack01;
1689  else if (this.goalstack02 && (this.goalstack02.wpflags & WAYPOINTFLAG_TELEPORT))
1690  tele_ent = this.goalstack02;
1691  else if (this.goalstack03 && (this.goalstack03.wpflags & WAYPOINTFLAG_TELEPORT))
1692  tele_ent = this.goalstack03;
1693  if (tele_ent && TELEPORT_USED(this, tele_ent))
1694  {
1695  if (this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
1696  if ((tele_ent.wpflags & WAYPOINTFLAG_PERSONAL) && tele_ent.owner == this)
1697  {
1698  this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
1700  }
1701  while (this.goalcurrent != tele_ent)
1702  {
1703  navigation_poproute(this);
1704  ++removed_goals;
1705  }
1706  navigation_poproute(this);
1707  this.lastteleporttime = 0;
1708  ++removed_goals;
1709  return removed_goals;
1710  }
1711  // reset of lastteleporttime can be overriden by a jumppad when it's set
1712  // in more than one frame: make sure it's reset
1713  this.lastteleporttime = 0;
1714  }
1715 
1716  // Loose goal touching check when running
1717  // check goalstack01 to make sure waypoint isn't the final goal
1718  if((this.aistatus & AI_STATUS_RUNNING) && this.goalcurrent.classname == "waypoint" && !(this.goalcurrent.wpflags & WAYPOINTFLAG_JUMP)
1719  && this.goalstack01 && !wasfreed(this.goalstack01) && vdist(vec2(this.velocity), >=, autocvar_sv_maxspeed))
1720  {
1721  vector gco = this.goalcurrent.origin;
1722  float min_dist = BOT_BUNNYHOP_WP_DETECTION_RANGE;
1723  // also detect waypoints when bot is way above them but with a narrower horizontal range
1724  // so to increase chances bot ends up in the standard range (optimizes nearest waypoint finding)
1725  if(vdist(this.origin - gco, <, min_dist)
1726  || (vdist(vec2(this.origin - gco), <, min_dist * 0.5) && vdist(this.origin - eZ * 1.5 * min_dist - gco, <, min_dist)))
1727  {
1728  traceline(this.origin + this.view_ofs , this.goalcurrent.origin, true, NULL);
1729  if(trace_fraction==1)
1730  {
1731  // Detect personal waypoints
1732  if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
1733  if((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) && this.goalcurrent.owner==this)
1734  {
1735  this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
1737  }
1738 
1739  navigation_poproute(this);
1740  ++removed_goals;
1741  if(this.goalcurrent && this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
1742  return removed_goals;
1743  }
1744  }
1745  }
1746 
1747  while (this.goalcurrent && !IS_PLAYER(this.goalcurrent))
1748  {
1749  vector gc_min = this.goalcurrent.absmin;
1750  vector gc_max = this.goalcurrent.absmax;
1751  if(this.goalcurrent.classname == "waypoint" && !this.goalcurrent.wpisbox)
1752  {
1753  gc_min = this.goalcurrent.origin - '1 1 1' * 12;
1754  gc_max = this.goalcurrent.origin + '1 1 1' * 12 + eZ * (jumpheight_vec.z + STAT(PL_MIN, this).z);
1755  }
1756  if (this.ladder_entity)
1757  {
1758  if (!boxesoverlap(this.absmin, this.absmax - eZ * STAT(PL_MAX, this).z, gc_min, gc_max))
1759  break;
1760  }
1761  else
1762  {
1763  if (!boxesoverlap(this.absmin, this.absmax, gc_min, gc_max))
1764  break;
1765  }
1766 
1767  // Detect personal waypoints
1768  if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
1769  if((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) && this.goalcurrent.owner==this)
1770  {
1771  this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
1773  }
1774 
1775  navigation_poproute(this);
1776  ++removed_goals;
1777  if(this.goalcurrent && this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
1778  return removed_goals;
1779  }
1780  return removed_goals;
1781 }
vector view_ofs
Definition: progsdefs.qc:151
int aistatus
Definition: bot.qh:20
entity() spawn
const int WAYPOINTFLAG_JUMP
Definition: api.qh:20
const int AI_STATUS_WAYPOINT_PERSONAL_GOING
Definition: bot.qh:13
float jumppadcount
Definition: jumppads.qh:15
origin
Definition: ent_cs.qc:114
vector absmax
Definition: csprogsdefs.qc:92
#define vlen2(v)
Definition: vector.qh:4
const int WAYPOINTFLAG_TELEPORT
Definition: api.qh:13
ERASEABLE float boxesoverlap(vector m1, vector m2, vector m3, vector m4)
requires that m2>m1 in all coordinates, and that m4>m3
Definition: vector.qh:73
#define NULL
Definition: post.qh:17
float lastteleporttime
Definition: api.qh:50
const int AI_STATUS_WAYPOINT_PERSONAL_REACHED
Definition: bot.qh:14
entity ladder_entity
Definition: ladder.qh:11
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
const vector eZ
Definition: vector.qh:46
#define vec2(...)
Definition: vector.qh:90
const int WAYPOINTFLAG_PERSONAL
Definition: api.qh:15
vector absmin
Definition: csprogsdefs.qc:92
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
float trace_fraction
Definition: csprogsdefs.qc:36
const int AI_STATUS_RUNNING
Definition: bot.qh:8
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ navigation_pushroute()

void navigation_pushroute ( entity  this,
entity  e 
)

Definition at line 800 of file navigation.qc.

References FLOAT_MAX, goalcurrent, goalcurrent_distance_2d, goalcurrent_distance_time, goalcurrent_distance_z, goalcurrent_prev, goalentity, goalstack01, goalstack02, goalstack03, goalstack04, goalstack05, goalstack06, goalstack07, goalstack08, goalstack09, goalstack10, goalstack11, goalstack12, goalstack13, goalstack14, goalstack15, goalstack16, goalstack17, goalstack18, goalstack19, goalstack20, goalstack21, goalstack22, goalstack23, goalstack24, goalstack25, goalstack26, goalstack27, goalstack28, goalstack29, goalstack30, goalstack31, and NULL.

Referenced by havocbot_ai(), havocbot_movetogoal(), and navigation_routetogoal().

801 {
802  this.goalcurrent_prev = this.goalcurrent;
805  this.goalcurrent_distance_time = 0;
806  //print("bot ", etos(this), " push ", etos(e), "\n");
807  if(this.goalstack31 == this.goalentity)
808  this.goalentity = NULL;
809  this.goalstack31 = this.goalstack30;
810  this.goalstack30 = this.goalstack29;
811  this.goalstack29 = this.goalstack28;
812  this.goalstack28 = this.goalstack27;
813  this.goalstack27 = this.goalstack26;
814  this.goalstack26 = this.goalstack25;
815  this.goalstack25 = this.goalstack24;
816  this.goalstack24 = this.goalstack23;
817  this.goalstack23 = this.goalstack22;
818  this.goalstack22 = this.goalstack21;
819  this.goalstack21 = this.goalstack20;
820  this.goalstack20 = this.goalstack19;
821  this.goalstack19 = this.goalstack18;
822  this.goalstack18 = this.goalstack17;
823  this.goalstack17 = this.goalstack16;
824  this.goalstack16 = this.goalstack15;
825  this.goalstack15 = this.goalstack14;
826  this.goalstack14 = this.goalstack13;
827  this.goalstack13 = this.goalstack12;
828  this.goalstack12 = this.goalstack11;
829  this.goalstack11 = this.goalstack10;
830  this.goalstack10 = this.goalstack09;
831  this.goalstack09 = this.goalstack08;
832  this.goalstack08 = this.goalstack07;
833  this.goalstack07 = this.goalstack06;
834  this.goalstack06 = this.goalstack05;
835  this.goalstack05 = this.goalstack04;
836  this.goalstack04 = this.goalstack03;
837  this.goalstack03 = this.goalstack02;
838  this.goalstack02 = this.goalstack01;
839  this.goalstack01 = this.goalcurrent;
840  this.goalcurrent = e;
841 }
entity goalentity
Definition: progsdefs.qc:189
#define NULL
Definition: post.qh:17
const float FLOAT_MAX
Definition: float.qh:3
+ Here is the caller graph for this function:

◆ navigation_routerating()

void navigation_routerating ( entity  this,
entity  e,
float  f,
float  rangebias 
)

Definition at line 1220 of file navigation.qc.

References autocvar_bot_ai_navigation_jetpack, autocvar_bot_ai_navigation_jetpack_mindistance, CONTENT_LAVA, CONTENT_SLIME, CONTENT_SOLID, CONTENT_WATER, entity(), etos(), fabs(), FL_PARTIALGROUND, FLOAT_MAX, ftos(), g_waypoints, GetResource(), IL_EACH, IS_BOT_CLIENT, IS_ONGROUND, IS_PLAYER, items, LOG_DEBUG, MOVE_NORMAL, navigation_bestgoal, navigation_bestrating, navigation_findnearestwaypoint(), navigation_jetpack_goal, navigation_jetpack_point, NULL, origin, random(), time, trace_endpos, trace_fraction, vdist, vector(), vlen(), WATERLEVEL_WETFEET, waypoint_getlinearcost(), waypoint_gettravelcost(), waypointeditor_enabled, WAYPOINTFLAG_PERSONAL, and WAYPOINTFLAG_TELEPORT.

1221 {
1222  if (!e || e.blacklisted) { return; }
1223 
1224  rangebias = waypoint_getlinearcost(rangebias);
1225  f = waypoint_getlinearcost(f);
1226 
1227  if (IS_PLAYER(e))
1228  {
1229  bool rate_wps = false;
1230  if (e.watertype < CONTENT_WATER || (e.waterlevel > WATERLEVEL_WETFEET && !STAT(FROZEN, e))
1231  || (e.flags & FL_PARTIALGROUND))
1232  {
1233  rate_wps = true;
1234  }
1235 
1236  if(!IS_ONGROUND(e))
1237  {
1238  traceline(e.origin, e.origin + '0 0 -1500', true, NULL);
1239  int t = pointcontents(trace_endpos + '0 0 1');
1240  if(t != CONTENT_SOLID )
1241  {
1242  if(t == CONTENT_WATER || t == CONTENT_SLIME || t == CONTENT_LAVA)
1243  rate_wps = true;
1244  else if(tracebox_hits_trigger_hurt(e.origin, e.mins, e.maxs, trace_endpos))
1245  return;
1246  }
1247  }
1248 
1249  if(rate_wps)
1250  {
1251  entity theEnemy = e;
1252  entity best_wp = NULL;
1253  float best_dist = FLOAT_MAX;
1254  IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_TELEPORT)
1255  && vdist(it.origin - theEnemy.origin, <, 500)
1256  && vdist(it.origin - this.origin, >, 100)
1257  && vdist(it.origin - this.origin, <, 10000),
1258  {
1259  float dist = vlen2(it.origin - theEnemy.origin);
1260  if (dist < best_dist)
1261  {
1262  best_wp = it;
1263  best_dist = dist;
1264  }
1265  });
1266  if (!best_wp)
1267  return;
1268  e = best_wp;
1269  }
1270  }
1271 
1272  vector goal_org = (e.absmin + e.absmax) * 0.5;
1273 
1274  //print("routerating ", etos(e), " = ", ftos(f), " - ", ftos(rangebias), "\n");
1275 
1276  // Evaluate path using jetpack
1277  if(this.items & IT_JETPACK)
1280  {
1281  vector pointa, pointb;
1282 
1283  LOG_DEBUG("jetpack ai: evaluating path for ", e.classname);
1284 
1285  // Point A
1286  traceline(this.origin, this.origin + '0 0 65535', MOVE_NORMAL, this);
1287  pointa = trace_endpos - '0 0 1';
1288 
1289  // Point B
1290  traceline(goal_org, goal_org + '0 0 65535', MOVE_NORMAL, e);
1291  pointb = trace_endpos - '0 0 1';
1292 
1293  // Can I see these two points from the sky?
1294  traceline(pointa, pointb, MOVE_NORMAL, this);
1295 
1296  if(trace_fraction==1)
1297  {
1298  LOG_DEBUG("jetpack ai: can bridge these two points");
1299 
1300  // Lower the altitude of these points as much as possible
1301  float zdistance, xydistance, cost, t, fuel;
1302  vector down, npa, npb;
1303 
1304  down = '0 0 -1' * (STAT(PL_MAX, this).z - STAT(PL_MIN, this).z) * 10;
1305 
1306  do{
1307  npa = pointa + down;
1308  npb = pointb + down;
1309 
1310  if(npa.z<=this.absmax.z)
1311  break;
1312 
1313  if(npb.z<=e.absmax.z)
1314  break;
1315 
1316  traceline(npa, npb, MOVE_NORMAL, this);
1317  if(trace_fraction==1)
1318  {
1319  pointa = npa;
1320  pointb = npb;
1321  }
1322  }
1323  while(trace_fraction == 1);
1324 
1325 
1326  // Rough estimation of fuel consumption
1327  // (ignores acceleration and current xyz velocity)
1328  xydistance = vlen(pointa - pointb);
1329  zdistance = fabs(pointa.z - this.origin.z);
1330 
1331  t = zdistance / autocvar_g_jetpack_maxspeed_up;
1332  t += xydistance / autocvar_g_jetpack_maxspeed_side;
1333  fuel = t * autocvar_g_jetpack_fuel * 0.8;
1334 
1335  LOG_DEBUG("jetpack ai: required fuel ", ftos(fuel), ", have ", ftos(GetResource(this, RES_FUEL)));
1336 
1337  // enough fuel ?
1338  if(GetResource(this, RES_FUEL) > fuel || (this.items & IT_UNLIMITED_AMMO))
1339  {
1340  // Estimate cost
1341  // (as onground costs calculation is mostly based on distances, here we do the same establishing some relationship
1342  // - between air and ground speeds)
1343 
1344  cost = xydistance / (autocvar_g_jetpack_maxspeed_side/autocvar_sv_maxspeed);
1345  cost += zdistance / (autocvar_g_jetpack_maxspeed_up/autocvar_sv_maxspeed);
1346  cost *= 1.5;
1347 
1348  // Compare against other goals
1349  f = f * rangebias / (rangebias + cost);
1350 
1351  if (navigation_bestrating < f)
1352  {
1353  LOG_DEBUG("jetpack path: added goal ", e.classname, " (with rating ", ftos(f), ")");
1355  navigation_bestgoal = e;
1356  this.navigation_jetpack_goal = e;
1357  this.navigation_jetpack_point = pointb;
1358  }
1359  return;
1360  }
1361  }
1362  }
1363 
1364  entity nwp;
1365  //te_wizspike(e.origin);
1366  //bprint(etos(e));
1367  //bprint("\n");
1368  // update the cached spawnfunc_waypoint link on a dynamic item entity
1369  if(e.classname == "waypoint" && !(e.wpflags & WAYPOINTFLAG_PERSONAL))
1370  {
1371  nwp = e;
1372  }
1373  else
1374  {
1375  if(waypointeditor_enabled && e.nearestwaypointtimeout >= 0 && time > e.nearestwaypointtimeout)
1376  e.nearestwaypoint = NULL;
1377 
1378  if ((!e.nearestwaypoint || e.navigation_dynamicgoal)
1379  && e.nearestwaypointtimeout >= 0 && time > e.nearestwaypointtimeout)
1380  {
1381  if(IS_BOT_CLIENT(e) && e.goalcurrent && e.goalcurrent.classname == "waypoint")
1382  e.nearestwaypoint = nwp = e.goalcurrent;
1383  else
1384  e.nearestwaypoint = nwp = navigation_findnearestwaypoint(e, true);
1385  if(!nwp)
1386  {
1387  LOG_DEBUG("FAILED to find a nearest waypoint to '", e.classname, "' #", etos(e));
1388 
1389  if(!e.navigation_dynamicgoal)
1390  e.blacklisted = true;
1391 
1392  if(e.blacklisted)
1393  {
1394  LOG_DEBUG("The entity '", e.classname, "' is going to be excluded from path finding during this match");
1395  return;
1396  }
1397  }
1398 
1399  if(e.navigation_dynamicgoal)
1400  e.nearestwaypointtimeout = time + 2;
1401  else if(waypointeditor_enabled)
1402  e.nearestwaypointtimeout = time + 3 + random() * 2;
1403  }
1404  nwp = e.nearestwaypoint;
1405  }
1406 
1407  if (nwp && nwp.wpcost < 10000000)
1408  {
1409  //te_wizspike(nwp.wpnearestpoint);
1410  float nwptoitem_cost = 0;
1411  if(nwp.wpflags & WAYPOINTFLAG_TELEPORT)
1412  nwptoitem_cost = nwp.wp00mincost;
1413  else
1414  nwptoitem_cost = waypoint_gettravelcost(nwp.wpnearestpoint, goal_org, nwp, e);
1415  float cost = nwp.wpcost + nwptoitem_cost;
1416  LOG_DEBUG("checking ^5", e.classname, "^7 with base rating ^xf04", ftos(f), "^7 and rangebias ^xf40", ftos(rangebias));
1417  f = f * rangebias / (rangebias + cost);
1418  LOG_DEBUG(" ^5", e.classname, "^7 with cost ^6", ftos(cost), "^7 and final rating ^2", ftos(f));
1419  if (navigation_bestrating < f)
1420  {
1421  LOG_DEBUG(" ground path: ^3added goal ^5", e.classname);
1423  navigation_bestgoal = e;
1424  }
1425  }
1426 }
#define IL_EACH(this, cond, body)
const float CONTENT_LAVA
Definition: csprogsdefs.qc:240
float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent)
Definition: waypoints.qc:1030
float autocvar_bot_ai_navigation_jetpack
Definition: cvars.qh:42
entity() spawn
const float MOVE_NORMAL
Definition: csprogsdefs.qc:252
#define IS_ONGROUND(s)
Definition: movetypes.qh:16
const float CONTENT_SOLID
Definition: csprogsdefs.qc:237
origin
Definition: ent_cs.qc:114
float FL_PARTIALGROUND
Definition: progsdefs.qc:241
bool waypointeditor_enabled
Definition: waypoints.qh:3
const float CONTENT_SLIME
Definition: csprogsdefs.qc:239
const int WAYPOINTFLAG_TELEPORT
Definition: api.qh:13
const float CONTENT_WATER
Definition: csprogsdefs.qc:238
#define NULL
Definition: post.qh:17
vector trace_endpos
Definition: csprogsdefs.qc:37
const int WATERLEVEL_WETFEET
Definition: movetypes.qh:12
float waypoint_getlinearcost(float dist)
Definition: waypoints.qc:1012
IntrusiveList g_waypoints
Definition: api.qh:148
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
float items
Definition: progsdefs.qc:145
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition: utils.qh:15
const int WAYPOINTFLAG_PERSONAL
Definition: api.qh:15
float autocvar_bot_ai_navigation_jetpack_mindistance
Definition: cvars.qh:43
float time
Definition: csprogsdefs.qc:16
float trace_fraction
Definition: csprogsdefs.qc:36
#define IS_PLAYER(v)
Definition: utils.qh:9
const float FLOAT_MAX
Definition: float.qh:3
#define LOG_DEBUG(...)
Definition: log.qh:85
+ Here is the call graph for this function:

◆ navigation_routetogoal()

float navigation_routetogoal ( entity  this,
entity  e,
vector  startposition 
)

Definition at line 1429 of file navigation.qc.

References autocvar_bot_ai_strategyinterval_movingtarget, bot_navigation_movemode, checkpvs(), entity(), goalcurrent, goalentity, IS_MOVABLE, items, MAX_CHASE_DISTANCE, navigation_item_add_link, navigation_item_getlinknum, navigation_item_initlinks_ifneeded, navigation_item_iswalkablelink, navigation_jetpack_goal, navigation_pushroute(), NULL, origin, set_tracewalk_dest(), trace_ent, tracewalk(), tracewalk_dest, tracewalk_dest_height, vdist, vec2, vlen2, waypointeditor_enabled, WAYPOINTFLAG_PERSONAL, WAYPOINTFLAG_TELEPORT, wp_goal_prev0, wp_goal_prev1, and WPFLAGMASK_NORELINK.

Referenced by havocbot_movetogoal(), navigation_goalrating_end(), and navigation_unstuck().

1430 {
1431  // if there is no goal, just exit
1432  if (!e)
1433  return false;
1434 
1435  entity teleport_goal = NULL;
1436 
1437  this.goalentity = e;
1438 
1439  if(e.wpflags & WAYPOINTFLAG_TELEPORT)
1440  {
1441  // force teleport destination as route destination
1442  teleport_goal = e;
1443  navigation_pushroute(this, e.wp00);
1444  this.goalentity = e.wp00;
1445  }
1446 
1447  // put the entity on the goal stack
1448  //print("routetogoal ", etos(e), "\n");
1449  navigation_pushroute(this, e);
1450 
1451  if(teleport_goal)
1452  e = this.goalentity;
1453 
1454  if(e.classname == "waypoint" && !(e.wpflags & WAYPOINTFLAG_PERSONAL))
1455  {
1456  this.wp_goal_prev1 = this.wp_goal_prev0;
1457  this.wp_goal_prev0 = e;
1458  }
1459 
1460  if((this.items & IT_JETPACK) && e == this.navigation_jetpack_goal)
1461  return true;
1462 
1463  // if it can reach the goal there is nothing more to do
1464  set_tracewalk_dest(e, startposition, true);
1466  && (trace_ent == this || tracewalk(this, startposition, STAT(PL_MIN, this), STAT(PL_MAX, this),
1468  {
1469  return true;
1470  }
1471 
1472  entity nearest_wp = NULL;
1473  // see if there are waypoints describing a path to the item
1474  if(e.classname != "waypoint" || (e.wpflags & WAYPOINTFLAG_PERSONAL))
1475  {
1476  e = e.nearestwaypoint;
1477  nearest_wp = e;
1478  }
1479  else if(teleport_goal)
1480  e = teleport_goal;
1481  else
1482  e = e.enemy; // we already have added it, so...
1483 
1484  if(e == NULL)
1485  return false;
1486 
1487  if(nearest_wp && nearest_wp.enemy && !(nearest_wp.enemy.wpflags & WPFLAGMASK_NORELINK))
1488  {
1489  // often path can be optimized by not adding the nearest waypoint
1490  if (this.goalentity.navigation_dynamicgoal || waypointeditor_enabled)
1491  {
1492  if (nearest_wp.enemy.wpcost < autocvar_bot_ai_strategyinterval_movingtarget)
1493  {
1494  if (vdist(vec2(this.goalentity.origin - nearest_wp.origin), <, 32))
1495  e = nearest_wp.enemy;
1496  else
1497  {
1498  set_tracewalk_dest(this.goalentity, nearest_wp.enemy.origin, true);
1499  if (trace_ent == this || (vdist(tracewalk_dest - nearest_wp.enemy.origin, <, 1050)
1500  && vlen2(tracewalk_dest - nearest_wp.enemy.origin) < vlen2(nearest_wp.origin - nearest_wp.enemy.origin)
1501  && tracewalk(this, nearest_wp.enemy.origin, STAT(PL_MIN, this), STAT(PL_MAX, this),
1503  {
1504  e = nearest_wp.enemy;
1505  }
1506  }
1507  }
1508  }
1509  else
1510  {
1511  // NOTE unlike waypoints, items hold incoming links
1513  int link_num = navigation_item_getlinknum(this.goalentity, nearest_wp.enemy);
1514  if (link_num >= 0)
1515  {
1516  if (navigation_item_iswalkablelink(this.goalentity, link_num))
1517  e = nearest_wp.enemy;
1518  }
1519  else // untested link
1520  {
1521  entity wp = nearest_wp.enemy;
1522  entity goal = this.goalentity;
1523  bool walkable = false;
1524  if (checkpvs(wp.origin, goal))
1525  {
1526  set_tracewalk_dest(goal, wp.origin, false);
1527  if (vdist(tracewalk_dest - wp.origin, <, 1050)
1528  && tracewalk(goal, wp.origin, PL_MIN_CONST, PL_MAX_CONST,
1530  {
1531  walkable = true;
1532  e = nearest_wp.enemy;
1533  }
1534  }
1535  navigation_item_add_link(wp, goal, walkable);
1536  }
1537  }
1538  }
1539 
1540  for (;;)
1541  {
1542  // add the spawnfunc_waypoint to the path
1543  navigation_pushroute(this, e);
1544  e = e.enemy;
1545 
1546  if(e==NULL)
1547  break;
1548  }
1549 
1550  return false;
1551 }
entity() spawn
float checkpvs(vector viewpos, entity viewee)
const int WPFLAGMASK_NORELINK
Definition: api.qh:29
#define IS_MOVABLE(v)
Definition: utils.qh:25
origin
Definition: ent_cs.qc:114
entity trace_ent
Definition: csprogsdefs.qc:40
bool waypointeditor_enabled
Definition: waypoints.qh:3
#define vlen2(v)
Definition: vector.qh:4
const int WAYPOINTFLAG_TELEPORT
Definition: api.qh:13
float autocvar_bot_ai_strategyinterval_movingtarget
Definition: cvars.qh:69
entity goalentity
Definition: progsdefs.qc:189
#define NULL
Definition: post.qh:17
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
float items
Definition: progsdefs.qc:145
#define vec2(...)
Definition: vector.qh:90
const int WAYPOINTFLAG_PERSONAL
Definition: api.qh:15
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ navigation_shortenpath()

bool navigation_shortenpath ( entity  this)

Definition at line 1554 of file navigation.qc.

References bot_navigation_movemode, bot_tracewalk_time, checkpvs(), entity(), fabs(), goalcurrent, goalentity, goalstack01, IS_MOVABLE, LOG_DEBUG, max(), MAX_CHASE_DISTANCE, maxs, mins, navigation_poproute(), netname, next, origin, set_tracewalk_dest(), time, trace_ent, tracewalk(), tracewalk_dest, tracewalk_dest_height, vdist, vectoangles(), vector(), view_ofs, vlen2, WAYPOINTFLAG_JUMP, and WAYPOINTFLAG_TELEPORT.

Referenced by havocbot_movetogoal().

1555 {
1556  if (!this.goalstack01 || wasfreed(this.goalstack01))
1557  return false;
1558  if (this.bot_tracewalk_time > time)
1559  return false;
1560  this.bot_tracewalk_time = max(time, this.bot_tracewalk_time) + 0.25;
1561 
1562  bool cut_allowed = false;
1563  entity next = this.goalentity;
1564  // evaluate whether bot can discard current route and chase directly a player, trying to
1565  // keep waypoint route as long as possible, as it is safer and faster (bot can bunnyhop)
1566  if (IS_MOVABLE(next))
1567  {
1568  set_tracewalk_dest(next, this.origin, true);
1569  if (vdist(this.origin - tracewalk_dest, <, 200))
1570  cut_allowed = true;
1571  else if (vdist(tracewalk_dest - this.origin, <, MAX_CHASE_DISTANCE)
1572  && vdist(tracewalk_dest - this.goalcurrent.origin, >, 200)
1573  && vdist(this.origin - this.goalcurrent.origin, >, 100)
1574  && checkpvs(this.origin + this.view_ofs, next))
1575  {
1576  if (vlen2(next.origin - this.origin) < vlen2(this.goalcurrent.origin - this.origin))
1577  cut_allowed = true;
1578  else
1579  {
1580  vector deviation = vectoangles(this.goalcurrent.origin - this.origin) - vectoangles(next.origin - this.origin);
1581  while (deviation.y < -180) deviation.y += 360;
1582  while (deviation.y > 180) deviation.y -= 360;
1583  if (fabs(deviation.y) > 25)
1584  cut_allowed = true;
1585  }
1586  }
1587  if (cut_allowed)
1588  {
1589  if (trace_ent == this || tracewalk(this, this.origin, this.mins, this.maxs,
1591  {
1592  LOG_DEBUG("path optimized for ", this.netname, ", route cleared");
1593  do
1594  {
1595  navigation_poproute(this);
1596  }
1597  while (this.goalcurrent != next);
1598  return true;
1599  }
1600  return false;
1601  }
1602  }
1603 
1604  next = this.goalstack01;
1605  // if for some reason the bot is closer to the next goal, pop the current one
1606  if (!IS_MOVABLE(next) && !(this.goalcurrent.wpflags & (WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_JUMP))
1607  && vlen2(this.goalcurrent.origin - next.origin) > vlen2(next.origin - this.origin)
1608  && checkpvs(this.origin + this.view_ofs, next))
1609  {
1610  set_tracewalk_dest(next, this.origin, true);
1611  cut_allowed = true;
1612  }
1613 
1614  if (cut_allowed)
1615  {
1616  if (trace_ent == this || tracewalk(this, this.origin, this.mins, this.maxs,
1618  {
1619  LOG_DEBUG("path optimized for ", this.netname, ", removed a goal from the queue");
1620  navigation_poproute(this);
1621  return true;
1622  }
1623  }
1624  return false;
1625 }
vector view_ofs
Definition: progsdefs.qc:151
entity() spawn
const int WAYPOINTFLAG_JUMP
Definition: api.qh:20
vector maxs
Definition: csprogsdefs.qc:113
float checkpvs(vector viewpos, entity viewee)
string netname
Definition: powerups.qc:20
#define IS_MOVABLE(v)
Definition: utils.qh:25
origin
Definition: ent_cs.qc:114
entity trace_ent
Definition: csprogsdefs.qc:40
float bot_tracewalk_time
Definition: api.qh:37
vector mins
Definition: csprogsdefs.qc:113
#define vlen2(v)
Definition: vector.qh:4
const int WAYPOINTFLAG_TELEPORT
Definition: api.qh:13
entity goalentity
Definition: progsdefs.qc:189
vector(float skel, float bonenum) _skel_get_boneabs_hidden
next
Definition: all.qh:88
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
float time
Definition: csprogsdefs.qc:16
#define LOG_DEBUG(...)
Definition: log.qh:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ navigation_unstuck()

void navigation_unstuck ( entity  this)

Definition at line 1907 of file navigation.qc.

References AI_STATUS_STUCK, aistatus, autocvar_bot_wander_enable, bot_navigation_movemode, bot_strategytoken, bot_waypoint_queue_bestgoal, bot_waypoint_queue_bestgoalrating, bot_waypoint_queue_goal, bot_waypoint_queue_owner, entity(), ftos(), g_waypoints, goalentity, IL_EACH, LOG_DEBUG, navigation_clearroute(), navigation_goalrating_timeout_expire(), navigation_goalrating_timeout_set(), navigation_routetogoal(), netname, NULL, origin, random(), set_tracewalk_dest(), tracewalk(), tracewalk_dest, tracewalk_dest_height, vlen2, and WAYPOINTFLAG_GENERATED.

Referenced by bot_think().

1908 {
1910  return;
1911 
1912  bool has_user_waypoints = false;
1913  IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_GENERATED),
1914  {
1915  has_user_waypoints = true;
1916  break;
1917  });
1918  if (!has_user_waypoints)
1919  return;
1920 
1921  float search_radius = 1000;
1922 
1924  {
1925  LOG_DEBUG(this.netname, " stuck, taking over the waypoints queue");
1926  bot_waypoint_queue_owner = this;
1929  }
1930 
1931  if(bot_waypoint_queue_owner!=this)
1932  return;
1933 
1935  {
1936  // evaluate the next goal on the queue
1937  float d = vlen2(this.origin - bot_waypoint_queue_goal.origin);
1938  LOG_DEBUG(this.netname, " evaluating ", bot_waypoint_queue_goal.classname, " with squared distance ", ftos(d));
1940  if (tracewalk(this, this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this),
1942  {
1944  {
1947  }
1948  }
1949 
1950  // move to a random waypoint while bot is searching for a walkable path;
1951  // this is usually sufficient to unstuck bots from bad spots or when other
1952  // bots of the same team block all their ways
1953  if (!bot_waypoint_queue_bestgoal && (!this.goalentity || random() < 0.1))
1954  {
1955  navigation_clearroute(this);
1958  }
1959 
1960  bot_waypoint_queue_goal = bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal;
1961 
1963  {
1965  {
1966  LOG_DEBUG(this.netname, " stuck, reachable waypoint found, heading to it");
1967  navigation_clearroute(this);
1970  this.aistatus &= ~AI_STATUS_STUCK;
1971  }
1972  else
1973  {
1974  LOG_DEBUG(this.netname, " stuck, cannot walk to any waypoint at all");
1975  }
1976 
1978  }
1979  }
1980  else
1981  {
1982  if(bot_strategytoken!=this)
1983  return;
1984 
1985  // build a new queue
1986  LOG_DEBUG(this.netname, " stuck, scanning reachable waypoints within ", ftos(search_radius)," qu");
1987 
1988  entity first = NULL;
1989 
1990  FOREACH_ENTITY_RADIUS(this.origin, search_radius, it.classname == "waypoint" && !(it.wpflags & WAYPOINTFLAG_GENERATED),
1991  {
1992  if(bot_waypoint_queue_goal)
1993  bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = it;
1994  else
1995  first = it;
1996 
1997  bot_waypoint_queue_goal = it;
1998  bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = NULL;
1999  });
2000 
2001  if (first)
2002  bot_waypoint_queue_goal = first;
2003  else
2004  {
2005  LOG_DEBUG(this.netname, " stuck, cannot walk to any waypoint at all");
2007  }
2008  }
2009 }
#define IL_EACH(this, cond, body)
int aistatus
Definition: bot.qh:20
entity() spawn
string netname
Definition: powerups.qc:20
origin
Definition: ent_cs.qc:114
#define vlen2(v)
Definition: vector.qh:4
entity goalentity
Definition: progsdefs.qc:189
#define NULL
Definition: post.qh:17
bool autocvar_bot_wander_enable
Definition: cvars.qh:60
IntrusiveList g_waypoints
Definition: api.qh:148
const int WAYPOINTFLAG_GENERATED
Definition: api.qh:11
const int AI_STATUS_STUCK
Definition: bot.qh:17
entity bot_strategytoken
Definition: bot.qh:76
#define LOG_DEBUG(...)
Definition: log.qh:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ navigation_waypoint_will_link()

float navigation_waypoint_will_link ( vector  v,
vector  org,
entity  ent,
vector  v2,
float  v2_height,
vector  o2,
float  o2_height,
float  walkfromwp,
float  bestdist 
)

Definition at line 895 of file navigation.qc.

References bot_navigation_movemode, trace_fraction, tracewalk(), and vdist.

Referenced by botframe_autowaypoints_fix_from(), and navigation_findnearestwaypoint_withdist_except().

896 {
897  if (vdist(v - org, <, bestdist))
898  {
899  traceline(v, org, true, ent);
900  if (trace_fraction == 1)
901  {
902  if (walkfromwp)
903  {
904  if (tracewalk(ent, v, PL_MIN_CONST, PL_MAX_CONST, v2, v2_height, bot_navigation_movemode))
905  return true;
906  }
907  else
908  {
909  if (tracewalk(ent, org, PL_MIN_CONST, PL_MAX_CONST, o2, o2_height, bot_navigation_movemode))
910  return true;
911  }
912  }
913  }
914  return false;
915 }
vector v
Definition: ent_cs.qc:116
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
float trace_fraction
Definition: csprogsdefs.qc:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ tracewalk()

float tracewalk ( entity  e,
vector  start,
vector  m1,
vector  m2,
vector  end,
float  end_height,
float  movemode 
)

Definition at line 273 of file navigation.qc.

References autocvar_bot_debug_tracewalk, bound(), DEBUG_NODE_FAIL, DEBUG_NODE_SUCCESS, DEBUG_NODE_WARNING, debugnode(), debugnodestatus(), debugresetnodes(), eZ, IN_LAVA, jumpheight_vec, jumpstepheightvec, MOVE_NOMONSTERS, NAV_SWIM_ONWATER, NAV_SWIM_UNDERWATER, NAV_WALK, navigation_checkladders(), normalize(), RESURFACE_LIMITED, stepheightvec, SUBMERGED, trace_endpos, trace_ent, trace_fraction, trace_startsolid, v, vec2, vector(), vlen(), and WETFEET.

Referenced by navigation_get_really_close_waypoint(), navigation_routetogoal(), navigation_shortenpath(), navigation_unstuck(), and navigation_waypoint_will_link().

274 {
276  {
277  debugresetnodes();
278  debugnode(e, start);
279  }
280 
281  vector org = start;
282  vector flatdir = end - start;
283  flatdir.z = 0;
284  float flatdist = vlen(flatdir);
285  flatdir = normalize(flatdir);
286  float stepdist = 32;
287  bool ignorehazards = false;
288  int nav_action;
289 
290  // Analyze starting point
291  if (IN_LAVA(start))
292  ignorehazards = true;
293 
294  tracebox(start, m1, m2, start, MOVE_NOMONSTERS, e);
295  if (trace_startsolid)
296  {
297  // Bad start
300 
301  //print("tracewalk: ", vtos(start), " is a bad start\n");
302  return false;
303  }
304 
305  vector end2 = end;
306  if(end_height)
307  end2.z += end_height;
308 
309  vector fixed_end = end;
310  vector move;
311 
312  if (flatdist > 0 && WETFEET(org))
313  {
314  if (SUBMERGED(org))
315  nav_action = NAV_SWIM_UNDERWATER;
316  else
317  {
318  // tracebox down by player's height
319  // useful to know if water level is so low that bot can still walk
320  tracebox(org, m1, m2, org - eZ * (m2.z - m1.z), movemode, e);
321  if (SUBMERGED(trace_endpos))
322  {
323  org = trace_endpos;
324  nav_action = NAV_SWIM_UNDERWATER;
325  }
326  else
327  nav_action = NAV_WALK;
328  }
329  }
330  else
331  nav_action = NAV_WALK;
332 
333  // Movement loop
334  while (true)
335  {
336  if (flatdist <= 0)
337  {
338  bool success = true;
339  if (org.z > end2.z + 1)
340  {
341  tracebox(org, m1, m2, end2, movemode, e);
342  org = trace_endpos;
343  if (org.z > end2.z + 1)
344  success = false;
345  }
346  else if (org.z < end.z - 1)
347  {
348  tracebox(org, m1, m2, org - jumpheight_vec, movemode, e);
349  if (SUBMERGED(trace_endpos))
350  {
352  tracebox(v, m1, m2, end, movemode, e);
353  if(trace_endpos.z >= end.z - 1)
354  {
356  trace_endpos = v;
357  }
358  }
359  else if (trace_endpos.z > org.z - jumpheight_vec.z)
360  tracebox(trace_endpos, m1, m2, trace_endpos + jumpheight_vec, movemode, e);
361  org = trace_endpos;
362  if (org.z < end.z - 1)
363  success = false;
364  }
365 
366  if (success)
367  {
368  // Succeeded
370  {
371  debugnode(e, org);
373  }
374 
375  //print("tracewalk: ", vtos(start), " can reach ", vtos(end), "\n");
376  return true;
377  }
378  }
379 
381  debugnode(e, org);
382 
383  if (flatdist <= 0)
384  break;
385 
386  if (stepdist > flatdist)
387  stepdist = flatdist;
388  if(nav_action == NAV_SWIM_UNDERWATER || (nav_action == NAV_SWIM_ONWATER && org.z > end2.z))
389  {
390  // can't use movement direction here to calculate move because of
391  // precision errors especially when direction has a high enough z value
392  //water_dir = normalize(water_end - org);
393  //move = org + water_dir * stepdist;
394  fixed_end.z = bound(end.z, org.z, end2.z);
395  if (stepdist == flatdist) {
396  move = fixed_end;
397  flatdist = 0;
398  } else {
399  move = org + (fixed_end - org) * (stepdist / flatdist);
400  flatdist = vlen(vec2(fixed_end - move));
401  }
402  }
403  else // horiz. direction
404  {
405  flatdist -= stepdist;
406  move = org + flatdir * stepdist;
407  }
408 
409  if(nav_action == NAV_SWIM_ONWATER)
410  {
411  tracebox(org, m1, m2, move, movemode, e); // swim
412 
413  // hit something
414  if (trace_fraction < 1)
415  {
416  // stepswim
417  tracebox(org + stepheightvec, m1, m2, move + stepheightvec, movemode, e);
418 
419  if (trace_fraction < 1 || trace_startsolid) // can't jump obstacle out of water
420  {
421  org = trace_endpos;
422  if(navigation_checkladders(e, org, m1, m2, end, end2, movemode))
423  {
425  {
426  debugnode(e, org);
428  }
429 
430  //print("tracewalk: ", vtos(start), " can reach ", vtos(end), "\n");
431  return true;
432  }
433 
436 
437  return false;
438  //print("tracewalk: ", vtos(start), " hit something when trying to reach ", vtos(end), "\n");
439  }
440 
441  //succesful stepswim
442 
443  if (flatdist <= 0)
444  {
445  org = trace_endpos;
446  continue;
447  }
448 
449  if (org.z <= move.z) // going horiz.
450  {
451  tracebox(trace_endpos, m1, m2, move, movemode, e);
452  org = trace_endpos;
453  nav_action = NAV_WALK;
454  continue;
455  }
456  }
457 
458  if (org.z <= move.z) // going horiz.
459  {
460  org = trace_endpos;
461  nav_action = NAV_SWIM_ONWATER;
462  }
463  else // going down
464  {
465  org = trace_endpos;
466  if (SUBMERGED(org))
467  nav_action = NAV_SWIM_UNDERWATER;
468  else
469  nav_action = NAV_SWIM_ONWATER;
470  }
471  }
472  else if(nav_action == NAV_SWIM_UNDERWATER)
473  {
474  if (move.z >= org.z) // swimming upwards or horiz.
475  {
476  tracebox(org, m1, m2, move, movemode, e); // swim
477 
478  bool stepswum = false;
479 
480  // hit something
481  if (trace_fraction < 1)
482  {
483  // stepswim
484  vector stepswim_move = move + stepheightvec;
485  if (flatdist > 0 && stepswim_move.z > end2.z + stepheightvec.z) // don't allow stepswim to go higher than destination
486  stepswim_move.z = end2.z;
487 
488  tracebox(org + stepheightvec, m1, m2, stepswim_move, movemode, e);
489 
490  // hit something
491  if (trace_startsolid)
492  {
495 
496  //print("tracewalk: ", vtos(start), " hit something when trying to reach ", vtos(end), "\n");
497  return false;
498  }
499 
500  if (trace_fraction < 1)
501  {
502  float org_z_prev = org.z;
503  RESURFACE_LIMITED(org, end2.z);
504  if(org.z == org_z_prev)
505  {
508 
509  //print("tracewalk: ", vtos(start), " can't reach ", vtos(end), "\n");
510  return false;
511  }
512  if(SUBMERGED(org))
513  nav_action = NAV_SWIM_UNDERWATER;
514  else
515  nav_action = NAV_SWIM_ONWATER;
516 
517  // we didn't advance horiz. in this step, flatdist decrease should be reverted
518  // but we can't do it properly right now... apply this workaround instead
519  if (flatdist <= 0)
520  flatdist = 1;
521 
522  continue;
523  }
524 
525  //succesful stepswim
526 
527  if (flatdist <= 0)
528  {
529  org = trace_endpos;
530  continue;
531  }
532 
533  stepswum = true;
534  }
535 
536  if (!WETFEET(trace_endpos))
537  {
538  tracebox(trace_endpos, m1, m2, trace_endpos - eZ * (stepdist + (m2.z - m1.z)), movemode, e);
539  // if stepswum we'll land on the obstacle, avoid the SUBMERGED check
540  if (!stepswum && SUBMERGED(trace_endpos))
541  {
543  org = trace_endpos;
544  nav_action = NAV_SWIM_ONWATER;
545  continue;
546  }
547 
548  // not submerged
549  org = trace_endpos;
550  nav_action = NAV_WALK;
551  continue;
552  }
553 
554  // wetfeet
555  org = trace_endpos;
556  nav_action = NAV_SWIM_UNDERWATER;
557  continue;
558  }
559  else //if (move.z < org.z) // swimming downwards
560  {
561  tracebox(org, m1, m2, move, movemode, e); // swim
562 
563  // hit something
564  if (trace_fraction < 1)
565  {
566  // stepswim
567  tracebox(org + stepheightvec, m1, m2, move + stepheightvec, movemode, e);
568 
569  // hit something
570  if (trace_fraction < 1 || trace_startsolid) // can't jump obstacle out of water
571  {
574 
575  //print("tracewalk: ", vtos(start), " hit something when trying to reach ", vtos(end), "\n");
576  return false;
577  }
578 
579  //succesful stepswim
580 
581  if (flatdist <= 0)
582  {
583  org = trace_endpos;
584  continue;
585  }
586 
587  if (trace_endpos.z > org.z && !SUBMERGED(trace_endpos))
588  {
589  // stepswim caused upwards direction
590  tracebox(trace_endpos, m1, m2, trace_endpos - stepheightvec, movemode, e);
591  if (!SUBMERGED(trace_endpos))
592  {
593  org = trace_endpos;
594  nav_action = NAV_WALK;
595  continue;
596  }
597  }
598  }
599 
600  org = trace_endpos;
601  nav_action = NAV_SWIM_UNDERWATER;
602  continue;
603  }
604  }
605  else if(nav_action == NAV_WALK)
606  {
607  // walk
608  tracebox(org, m1, m2, move, movemode, e);
609 
612 
613  // hit something
614  if (trace_fraction < 1)
615  {
616  // check if we can walk over this obstacle, possibly by jumpstepping
617  tracebox(org + stepheightvec, m1, m2, move + stepheightvec, movemode, e);
618  if (trace_fraction < 1 || trace_startsolid)
619  {
620  if (trace_startsolid) // hit ceiling above org
621  {
622  // reduce stepwalk height
623  tracebox(org, m1, m2, org + stepheightvec, movemode, e);
624  tracebox(trace_endpos, m1, m2, move + eZ * (trace_endpos.z - move.z), movemode, e);
625  }
626  else //if (trace_fraction < 1)
627  {
628  tracebox(org + jumpstepheightvec, m1, m2, move + jumpstepheightvec, movemode, e);
629  if (trace_startsolid) // hit ceiling above org
630  {
631  // reduce jumpstepwalk height
632  tracebox(org, m1, m2, org + jumpstepheightvec, movemode, e);
633  tracebox(trace_endpos, m1, m2, move + eZ * (trace_endpos.z - move.z), movemode, e);
634  }
635  }
636 
637  if (trace_fraction < 1)
638  {
639  vector v = trace_endpos;
640  v.z = org.z + jumpheight_vec.z;
641  if(navigation_checkladders(e, v, m1, m2, end, end2, movemode))
642  {
644  {
645  debugnode(e, v);
647  }
648 
649  //print("tracewalk: ", vtos(start), " can reach ", vtos(end), "\n");
650  return true;
651  }
652 
655 
656  traceline( org, move, movemode, e);
657 
658  if ( trace_ent.classname == "door_rotating" || trace_ent.classname == "door")
659  {
660  vector nextmove;
661  move = trace_endpos;
662  while(trace_ent.classname == "door_rotating" || trace_ent.classname == "door")
663  {
664  nextmove = move + (flatdir * stepdist);
665  traceline( move, nextmove, movemode, e);
666  move = nextmove;
667  }
668  flatdist = vlen(vec2(end - move));
669  }
670  else
671  {
674 
675  //print("tracewalk: ", vtos(start), " hit something when trying to reach ", vtos(end), "\n");
676  //te_explosion(trace_endpos);
677  //print(ftos(e.dphitcontentsmask), "\n");
678  return false; // failed
679  }
680  }
681  else
682  move = trace_endpos;
683  }
684  else
685  move = trace_endpos;
686  }
687  else
688  move = trace_endpos;
689 
690  // trace down from stepheight as far as possible and move there,
691  // if this starts in solid we try again without the stepup, and
692  // if that also fails we assume it is a wall
693  // (this is the same logic as the Quake walkmove function used)
694  tracebox(move, m1, m2, move + '0 0 -65536', movemode, e);
695 
696  org = trace_endpos;
697 
698  if (!ignorehazards)
699  {
700  if (IN_LAVA(org))
701  {
703  {
706  }
707 
708  //print("tracewalk: ", vtos(start), " hits a hazard when trying to reach ", vtos(end), "\n");
709  return false;
710  }
711  }
712 
713  if (flatdist <= 0)
714  {
715  if(move.z >= end2.z && org.z < end2.z)
716  org.z = end2.z;
717  continue;
718  }
719 
720  if(org.z > move.z - 1 || !SUBMERGED(org))
721  {
722  nav_action = NAV_WALK;
723  continue;
724  }
725 
726  // ended up submerged while walking
728  debugnode(e, org);
729 
730  RESURFACE_LIMITED(org, move.z);
731  nav_action = NAV_SWIM_ONWATER;
732  continue;
733  }
734  }
735 
736  //print("tracewalk: ", vtos(start), " did not arrive at ", vtos(end), " but at ", vtos(org), "\n");
737 
738  // moved but didn't arrive at the intended destination
741 
742  return false;
743 }
bool autocvar_bot_debug_tracewalk
Definition: cvars.qh:58
#define IN_LAVA(pos)
Definition: bot.qh:83
entity trace_ent
Definition: csprogsdefs.qc:40
const float MOVE_NOMONSTERS
Definition: csprogsdefs.qc:253
vector trace_endpos
Definition: csprogsdefs.qc:37
#define WETFEET(pos)
Definition: bot.qh:86
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define SUBMERGED(pos)
Definition: bot.qh:85
vector v
Definition: ent_cs.qc:116
const vector eZ
Definition: vector.qh:46
#define vec2(...)
Definition: vector.qh:90
float trace_startsolid
Definition: csprogsdefs.qc:35
float trace_fraction
Definition: csprogsdefs.qc:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ blacklisted

float blacklisted

Definition at line 75 of file navigation.qh.

◆ bot_basewaypoint

entity bot_basewaypoint

Definition at line 93 of file navigation.qh.

◆ BOT_BUNNYHOP_WP_DETECTION_RANGE

const float BOT_BUNNYHOP_WP_DETECTION_RANGE = 100

◆ bot_navigation_movemode

◆ bot_waypoint_queue_bestgoal

entity bot_waypoint_queue_bestgoal

Definition at line 88 of file navigation.qh.

Referenced by navigation_unstuck().

◆ bot_waypoint_queue_bestgoalrating

float bot_waypoint_queue_bestgoalrating

Definition at line 89 of file navigation.qh.

Referenced by navigation_unstuck().

◆ bot_waypoint_queue_goal

entity bot_waypoint_queue_goal

Definition at line 86 of file navigation.qh.

Referenced by navigation_unstuck().

◆ bot_waypoint_queue_nextgoal

entity bot_waypoint_queue_nextgoal

Definition at line 87 of file navigation.qh.

◆ bot_waypoint_queue_owner

entity bot_waypoint_queue_owner

Definition at line 85 of file navigation.qh.

Referenced by bot_clientdisconnect(), bot_think(), and navigation_unstuck().

◆ DEBUG_NODE_FAIL

const float DEBUG_NODE_FAIL = 3

Definition at line 82 of file navigation.qh.

Referenced by debugnodestatus(), and tracewalk().

◆ DEBUG_NODE_SUCCESS

const float DEBUG_NODE_SUCCESS = 1

Definition at line 80 of file navigation.qh.

Referenced by debugnodestatus(), and tracewalk().

◆ DEBUG_NODE_WARNING

const float DEBUG_NODE_WARNING = 2

Definition at line 81 of file navigation.qh.

Referenced by debugnodestatus(), and tracewalk().

◆ debuglastnode

vector debuglastnode

Definition at line 83 of file navigation.qh.

Referenced by debugnode(), and debugresetnodes().

◆ goalcurrent

◆ goalcurrent_distance_2d

◆ goalcurrent_distance_time

◆ goalcurrent_distance_z

◆ goalcurrent_prev

◆ goalentity

entity goalentity

Definition at line 34 of file navigation.qh.

◆ goalentity_lock_timeout

float goalentity_lock_timeout

Definition at line 35 of file navigation.qh.

◆ goalentity_shouldbefrozen

bool goalentity_shouldbefrozen

◆ goalstack01

◆ goalstack02

◆ goalstack03

◆ goalstack04

entity goalstack04

◆ goalstack05

entity goalstack05

◆ goalstack06

entity goalstack06

◆ goalstack07

entity goalstack07

◆ goalstack08

entity goalstack08

◆ goalstack09

entity goalstack09

◆ goalstack10

entity goalstack10

◆ goalstack11

entity goalstack11

◆ goalstack12

entity goalstack12

◆ goalstack13

entity goalstack13

◆ goalstack14

entity goalstack14

◆ goalstack15

entity goalstack15

◆ goalstack16

entity goalstack16

◆ goalstack17

entity goalstack17

◆ goalstack18

entity goalstack18

◆ goalstack19

entity goalstack19

◆ goalstack20

entity goalstack20

◆ goalstack21

entity goalstack21

◆ goalstack22

entity goalstack22

◆ goalstack23

entity goalstack23

◆ goalstack24

entity goalstack24

◆ goalstack25

entity goalstack25

◆ goalstack26

entity goalstack26

◆ goalstack27

entity goalstack27

◆ goalstack28

entity goalstack28

◆ goalstack29

entity goalstack29

◆ goalstack30

entity goalstack30

◆ goalstack31

◆ jumpheight_time

float jumpheight_time

Definition at line 13 of file navigation.qh.

Referenced by bot_calculate_stepheightvec(), and waypoint_gettravelcost().

◆ jumpheight_vec

◆ jumpstepheightvec

vector jumpstepheightvec

◆ lastteleport_origin

vector lastteleport_origin

Definition at line 73 of file navigation.qh.

◆ lastteleporttime

float lastteleporttime

Definition at line 72 of file navigation.qh.

◆ nav_submerged_state

int nav_submerged_state

Definition at line 99 of file navigation.qh.

◆ navigation_bestgoal

◆ navigation_bestrating

float navigation_bestrating

Definition at line 6 of file navigation.qh.

Referenced by navigation_goalrating_start(), and navigation_routerating().

◆ navigation_dynamicgoal

bool navigation_dynamicgoal

Definition at line 94 of file navigation.qh.

◆ navigation_jetpack_goal

entity navigation_jetpack_goal

◆ navigation_jetpack_point

vector navigation_jetpack_point

Definition at line 78 of file navigation.qh.

Referenced by havocbot_movetogoal(), and navigation_routerating().

◆ navigation_testtracewalk

float navigation_testtracewalk

Definition at line 8 of file navigation.qh.

Referenced by navigation_findnearestwaypoint_withdist_except(), and waypoint_think().

◆ nearestwaypoint

entity nearestwaypoint

Definition at line 38 of file navigation.qh.

◆ nearestwaypointtimeout

float nearestwaypointtimeout

Definition at line 39 of file navigation.qh.

◆ stepheightvec

◆ tracewalk_dest

◆ tracewalk_dest_height

◆ wp_goal_prev0

entity wp_goal_prev0

Definition at line 69 of file navigation.qh.

Referenced by navigation_routetogoal().

◆ wp_goal_prev1

entity wp_goal_prev1

Definition at line 70 of file navigation.qh.

Referenced by navigation_routetogoal().