1 | /* Copyright (C) 2021 Wildfire Games.
|
---|
2 | * This file is part of 0 A.D.
|
---|
3 | *
|
---|
4 | * 0 A.D. is free software: you can redistribute it and/or modify
|
---|
5 | * it under the terms of the GNU General Public License as published by
|
---|
6 | * the Free Software Foundation, either version 2 of the License, or
|
---|
7 | * (at your option) any later version.
|
---|
8 | *
|
---|
9 | * 0 A.D. is distributed in the hope that it will be useful,
|
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
12 | * GNU General Public License for more details.
|
---|
13 | *
|
---|
14 | * You should have received a copy of the GNU General Public License
|
---|
15 | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #ifndef INCLUDED_ICMPPATHFINDER
|
---|
19 | #define INCLUDED_ICMPPATHFINDER
|
---|
20 |
|
---|
21 | #include "simulation2/system/Interface.h"
|
---|
22 |
|
---|
23 | #include "simulation2/components/ICmpObstruction.h"
|
---|
24 | #include "simulation2/helpers/Pathfinding.h"
|
---|
25 |
|
---|
26 | #include "maths/FixedVector2D.h"
|
---|
27 |
|
---|
28 | #include <map>
|
---|
29 |
|
---|
30 | class IObstructionTestFilter;
|
---|
31 | class PathGoal;
|
---|
32 |
|
---|
33 | template<typename T> class Grid;
|
---|
34 |
|
---|
35 | // Returned by asynchronous workers, used to send messages in the main thread.
|
---|
36 | struct WaypointPath;
|
---|
37 |
|
---|
38 | struct PathResult
|
---|
39 | {
|
---|
40 | PathResult() = default;
|
---|
41 | PathResult(u32 t, entity_id_t n, WaypointPath p) : ticket(t), notify(n), path(p) {};
|
---|
42 |
|
---|
43 | u32 ticket;
|
---|
44 | entity_id_t notify;
|
---|
45 | WaypointPath path;
|
---|
46 | };
|
---|
47 |
|
---|
48 | /**
|
---|
49 | * Pathfinder algorithms.
|
---|
50 | *
|
---|
51 | * There are two different modes: a tile-based pathfinder that works over long distances and
|
---|
52 | * accounts for terrain costs but ignore units, and a 'short' vertex-based pathfinder that
|
---|
53 | * provides precise paths and avoids other units.
|
---|
54 | *
|
---|
55 | * Both use the same concept of a PathGoal: either a point, circle or square.
|
---|
56 | * (If the starting point is inside the goal shape then the path will move outwards
|
---|
57 | * to reach the shape's outline.)
|
---|
58 | *
|
---|
59 | * The output is a list of waypoints.
|
---|
60 | */
|
---|
61 | class ICmpPathfinder : public IComponent
|
---|
62 | {
|
---|
63 | public:
|
---|
64 |
|
---|
65 | /**
|
---|
66 | * Get the list of all known passability classes.
|
---|
67 | */
|
---|
68 | virtual void GetPassabilityClasses(std::map<std::string, pass_class_t>& passClasses) const = 0;
|
---|
69 |
|
---|
70 | /**
|
---|
71 | * Get the list of passability classes, separating pathfinding classes and others.
|
---|
72 | */
|
---|
73 | virtual void GetPassabilityClasses(
|
---|
74 | std::map<std::string, pass_class_t>& nonPathfindingPassClasses,
|
---|
75 | std::map<std::string, pass_class_t>& pathfindingPassClasses) const = 0;
|
---|
76 |
|
---|
77 | /**
|
---|
78 | * Get the tag for a given passability class name.
|
---|
79 | * Logs an error and returns something acceptable if the name is unrecognised.
|
---|
80 | */
|
---|
81 | virtual pass_class_t GetPassabilityClass(const std::string& name) const = 0;
|
---|
82 |
|
---|
83 | virtual entity_pos_t GetClearance(pass_class_t passClass) const = 0;
|
---|
84 |
|
---|
85 | /**
|
---|
86 | * Get the larger clearance in all passability classes.
|
---|
87 | */
|
---|
88 | virtual entity_pos_t GetMaximumClearance() const = 0;
|
---|
89 |
|
---|
90 | virtual const Grid<NavcellData>& GetPassabilityGrid() = 0;
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * Get the accumulated dirtiness information since the last time the AI accessed and flushed it.
|
---|
94 | */
|
---|
95 | virtual const GridUpdateInformation& GetAIPathfinderDirtinessInformation() const = 0;
|
---|
96 | virtual void FlushAIPathfinderDirtinessInformation() = 0;
|
---|
97 |
|
---|
98 | /**
|
---|
99 | * Get a grid representing the distance to the shore of the terrain tile.
|
---|
100 | */
|
---|
101 | virtual Grid<u16> ComputeShoreGrid(bool expandOnWater = false) = 0;
|
---|
102 |
|
---|
103 | /**
|
---|
104 | * Asynchronous version of ComputePath.
|
---|
105 | * Request a long path computation, asynchronously.
|
---|
106 | * The result will be sent as CMessagePathResult to 'notify'.
|
---|
107 | * Returns a unique non-zero number, which will match the 'ticket' in the result,
|
---|
108 | * so callers can recognise each individual request they make.
|
---|
109 | */
|
---|
110 | virtual u32 ComputePathAsync(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass, entity_id_t notify) = 0;
|
---|
111 |
|
---|
112 | /*
|
---|
113 | * Request a long-path computation immediately
|
---|
114 | */
|
---|
115 | virtual void ComputePathImmediate(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass, WaypointPath& ret) const = 0;
|
---|
116 |
|
---|
117 | /**
|
---|
118 | * Request a short path computation, asynchronously.
|
---|
119 | * The result will be sent as CMessagePathResult to 'notify'.
|
---|
120 | * Returns a unique non-zero number, which will match the 'ticket' in the result,
|
---|
121 | * so callers can recognise each individual request they make.
|
---|
122 | */
|
---|
123 | virtual u32 ComputeShortPathAsync(entity_pos_t x0, entity_pos_t z0, entity_pos_t clearance, entity_pos_t range, const PathGoal& goal, pass_class_t passClass, bool avoidMovingUnits, entity_id_t controller, entity_id_t notify) = 0;
|
---|
124 |
|
---|
125 | /*
|
---|
126 | * Request a short-path computation immediately.
|
---|
127 | */
|
---|
128 | virtual WaypointPath ComputeShortPathImmediate(const ShortPathRequest& request) const = 0;
|
---|
129 |
|
---|
130 | /**
|
---|
131 | * If the debug overlay is enabled, render the path that will computed by ComputePath.
|
---|
132 | */
|
---|
133 | virtual void SetDebugPath(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass) = 0;
|
---|
134 |
|
---|
135 | /**
|
---|
136 | * @return true if the goal is reachable from (x0, z0) for the given passClass, false otherwise.
|
---|
137 | * Warning: this is synchronous, somewhat expensive and not should not be called too liberally.
|
---|
138 | */
|
---|
139 | virtual bool IsGoalReachable(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass) = 0;
|
---|
140 |
|
---|
141 | /**
|
---|
142 | * Check whether the given movement line is valid and doesn't hit any obstructions
|
---|
143 | * or impassable terrain.
|
---|
144 | * Returns true if the movement is okay.
|
---|
145 | */
|
---|
146 | virtual bool CheckMovement(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, pass_class_t passClass) const = 0;
|
---|
147 |
|
---|
148 | /**
|
---|
149 | * Check whether a unit placed here is valid and doesn't hit any obstructions
|
---|
150 | * or impassable terrain.
|
---|
151 | * When onlyCenterPoint = true, only check the center tile of the unit
|
---|
152 | * @return ICmpObstruction::FOUNDATION_CHECK_SUCCESS if the placement is okay, else
|
---|
153 | * a value describing the type of failure.
|
---|
154 | */
|
---|
155 | virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint = false) const = 0;
|
---|
156 |
|
---|
157 | /**
|
---|
158 | * Check whether a building placed here is valid and doesn't hit any obstructions
|
---|
159 | * or impassable terrain.
|
---|
160 | * @return ICmpObstruction::FOUNDATION_CHECK_SUCCESS if the placement is okay, else
|
---|
161 | * a value describing the type of failure.
|
---|
162 | */
|
---|
163 | virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass) const = 0;
|
---|
164 |
|
---|
165 | /**
|
---|
166 | * Check whether a building placed here is valid and doesn't hit any obstructions
|
---|
167 | * or impassable terrain.
|
---|
168 | * when onlyCenterPoint = true, only check the center tile of the building
|
---|
169 | * @return ICmpObstruction::FOUNDATION_CHECK_SUCCESS if the placement is okay, else
|
---|
170 | * a value describing the type of failure.
|
---|
171 | */
|
---|
172 | virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint) const = 0;
|
---|
173 |
|
---|
174 |
|
---|
175 | /**
|
---|
176 | * Toggle the storage and rendering of debug info.
|
---|
177 | */
|
---|
178 | virtual void SetDebugOverlay(bool enabled) = 0;
|
---|
179 |
|
---|
180 | /**
|
---|
181 | * Toggle the storage and rendering of debug info for the hierarchical pathfinder.
|
---|
182 | */
|
---|
183 | virtual void SetHierDebugOverlay(bool enabled) = 0;
|
---|
184 |
|
---|
185 | /**
|
---|
186 | * Finish computing asynchronous path requests and send the CMessagePathResult messages.
|
---|
187 | */
|
---|
188 | virtual void SendRequestedPaths() = 0;
|
---|
189 |
|
---|
190 | /**
|
---|
191 | * Tell asynchronous pathfinder threads that they can begin computing paths.
|
---|
192 | */
|
---|
193 | virtual void StartProcessingMoves(bool useMax) = 0;
|
---|
194 |
|
---|
195 | /**
|
---|
196 | * Regenerates the grid based on the current obstruction list, if necessary
|
---|
197 | */
|
---|
198 | virtual void UpdateGrid() = 0;
|
---|
199 |
|
---|
200 | /**
|
---|
201 | * Returns some stats about the last ComputePath.
|
---|
202 | */
|
---|
203 | virtual void GetDebugData(u32& steps, double& time, Grid<u8>& grid) const = 0;
|
---|
204 |
|
---|
205 | /**
|
---|
206 | * Sets up the pathfinder passability overlay in Atlas.
|
---|
207 | */
|
---|
208 | virtual void SetAtlasOverlay(bool enable, pass_class_t passClass = 0) = 0;
|
---|
209 |
|
---|
210 | DECLARE_INTERFACE_TYPE(Pathfinder)
|
---|
211 | };
|
---|
212 |
|
---|
213 | #endif // INCLUDED_ICMPPATHFINDER
|
---|