MCPcopy Create free account
hub / github.com/crawl/crawl / try_pathfind

Function try_pathfind

crawl-ref/source/mon-movetarget.cc:87–219  ·  view source on GitHub ↗

Check whether there's an unobstructed path to our foe, either by using an existing travel_path or calculating a new one. Returns true if no further handling necessary, else false.

Source from the content-addressed store, hash-verified

85// either by using an existing travel_path or calculating a new one.
86// Returns true if no further handling necessary, else false.
87bool try_pathfind(monster* mon)
88{
89 // Just because we can *see* our target, that doesn't mean
90 // we can actually get there.
91 // If no path is found (too far away, perhaps) set a
92 // flag, so we don't directly calculate the whole thing again
93 // next turn, and even extend that flag to neighbouring
94 // monsters of similar movement restrictions.
95
96 const actor* foe = (mon->friendly() && mon->foe == MHITYOU ? &you
97 : mon->get_foe());
98
99 // Trying to pathfind towards nothing in particular; bail out.
100 if (!foe)
101 return false;
102
103 const coord_def targpos = foe->pos();
104
105 bool need_pathfind = !can_go_straight(mon, mon->pos(), targpos);
106
107 const int threat_range_lof = mon->threat_range(true, false);
108 const int threat_range_no_lof = mon->threat_range(false, true);
109 const int dist = grid_distance(mon->pos(), targpos);
110
111 // Monsters that are already in range to do something threatening to their
112 // target don't need pathfinding.
113 if (need_pathfind
114 && !mon->friendly()
115 && ((dist <= threat_range_lof
116 && cell_see_cell(mon->pos(), targpos, LOS_SOLID_SEE))
117 || (dist <= threat_range_no_lof
118 && cell_see_cell(mon->pos(), targpos, LOS_NO_TRANS))))
119 {
120 need_pathfind = false;
121 }
122
123 if (!need_pathfind)
124 {
125 // The target is easily reachable (or we're close enough already).
126 // Clear travel path and target, if necessary.
127 if (mon->travel_target != MTRAV_PATROL
128 && mon->travel_target != MTRAV_NONE)
129 {
130 if (mon->is_travelling())
131 mon->travel_path.clear();
132 mon->travel_target = MTRAV_NONE;
133 }
134 return false;
135 }
136
137 // If the target is "unreachable" (the monster already tried,
138 // and failed, to find a path), there's a chance of trying again.
139 // Retreating monsters retry every turn.
140 if (target_is_unreachable(mon) && !one_chance_in(12))
141 return false;
142
143#ifdef DEBUG_PATHFIND
144 mprf("%s: Target out of reach! What now?",

Callers 3

handle_behaviourFunction · 0.85
behaviour_eventFunction · 0.85

Calls 15

can_go_straightFunction · 0.85
grid_distanceFunction · 0.85
cell_see_cellFunction · 0.85
target_is_unreachableFunction · 0.85
one_chance_inFunction · 0.85
mprfFunction · 0.85
mons_tracking_rangeFunction · 0.85
_set_no_path_foundFunction · 0.85
friendlyMethod · 0.80
get_foeMethod · 0.80
threat_rangeMethod · 0.80
is_travellingMethod · 0.80

Tested by

no test coverage detected