1 /*************************************************************************** 2 * Copyright (C) 2005-2019 by the FIFE team * 3 * http://www.fifengine.net * 4 * This file is part of FIFE. * 5 * * 6 * FIFE is free software; you can redistribute it and/or * 7 * modify it under the terms of the GNU Lesser General Public * 8 * License as published by the Free Software Foundation; either * 9 * version 2.1 of the License, or (at your option) any later version. * 10 * * 11 * This library is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the * 18 * Free Software Foundation, Inc., * 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 20 ***************************************************************************/ 21 22 // Standard C++ library includes 23 24 // 3rd party library includes 25 26 // FIFE includes 27 // These includes are split up in two parts, separated by one empty line 28 // First block: files included from the FIFE root src directory 29 // Second block: files included from the same folder 30 #include "util/log/logger.h" 31 #include "model/metamodel/object.h" 32 #include "model/structures/layer.h" 33 #include "model/structures/location.h" 34 35 #include "route.h" 36 37 namespace FIFE { 38 39 static Logger _log(LM_STRUCTURES); 40 Route(const Location & start,const Location & end)41 Route::Route(const Location& start, const Location& end): 42 m_status(ROUTE_CREATED), 43 m_startNode(start), 44 m_endNode(end), 45 m_walked(0), 46 m_sessionId(-1), 47 m_rotation(0), 48 m_replanned(false), 49 m_ignoresBlocker(false), 50 m_costId(""), 51 m_object(NULL) { 52 } 53 ~Route()54 Route::~Route() { 55 } 56 setRouteStatus(RouteStatusInfo status)57 void Route::setRouteStatus(RouteStatusInfo status) { 58 if (m_status != status) { 59 m_status = status; 60 } 61 } 62 getRouteStatus()63 RouteStatusInfo Route::getRouteStatus() { 64 return m_status; 65 } 66 setStartNode(const Location & node)67 void Route::setStartNode(const Location& node) { 68 m_startNode = node; 69 if (m_status != ROUTE_CREATED) { 70 m_status = ROUTE_CREATED; 71 if (!m_path.empty()) { 72 m_path.clear(); 73 } 74 m_walked = 1; 75 } 76 } 77 getStartNode()78 const Location& Route::getStartNode() { 79 return m_startNode; 80 } 81 setEndNode(const Location & node)82 void Route::setEndNode(const Location& node) { 83 if (m_status != ROUTE_CREATED) { 84 m_status = ROUTE_CREATED; 85 if (!m_path.empty()) { 86 m_startNode = *m_current; 87 m_path.clear(); 88 } 89 m_walked = 1; 90 } 91 m_endNode = node; 92 } 93 getEndNode()94 const Location& Route::getEndNode() { 95 return m_endNode; 96 } 97 getCurrentNode()98 const Location& Route::getCurrentNode() { 99 if (m_path.empty()) { 100 return m_startNode; 101 } 102 if (m_current == m_path.end()) { 103 return m_path.back(); 104 } 105 return *m_current; 106 } 107 getPreviousNode()108 const Location& Route::getPreviousNode() { 109 if (m_path.empty()) { 110 return m_startNode; 111 } 112 if (m_current != m_path.begin()) { 113 --m_current; 114 const Location& loc = *m_current; 115 ++m_current; 116 return loc; 117 } 118 return *m_current; 119 } 120 getNextNode()121 const Location& Route::getNextNode() { 122 if (m_path.empty()) { 123 return m_startNode; 124 } 125 if (m_current != m_path.end()) { 126 ++m_current; 127 if (m_current != m_path.end()) { 128 const Location& loc = *m_current; 129 --m_current; 130 return loc; 131 } 132 --m_current; 133 } 134 return *m_current; 135 } 136 walkToNextNode(int32_t step)137 bool Route::walkToNextNode(int32_t step) { 138 if (m_path.empty() || step == 0) { 139 return false; 140 } 141 142 int32_t pos = static_cast<int32_t>(m_walked) + step; 143 if (pos > static_cast<int32_t>(m_path.size()) || pos < 0) { 144 return false; 145 } 146 if (step > 0) { 147 for (int32_t i = 0; i < step; ++i, ++m_current); 148 } else { 149 for (int32_t i = 0; i > step; --i, --m_current); 150 } 151 m_walked += step; 152 153 return true; 154 } 155 reachedEnd()156 bool Route::reachedEnd() { 157 if (m_path.empty()) { 158 return true; 159 } 160 return m_current == m_path.end(); 161 } 162 setPath(const Path & path)163 void Route::setPath(const Path& path) { 164 m_path = path; 165 if (!m_path.empty()) { 166 m_status = ROUTE_SOLVED; 167 m_current = m_path.begin(); 168 m_startNode = m_path.front(); 169 m_endNode = m_path.back(); 170 } 171 if (!isMultiCell()) { 172 m_replanned = false; 173 } 174 m_walked = 1; 175 } 176 getPath()177 Path Route::getPath() { 178 return m_path; 179 } 180 cutPath(uint32_t length)181 void Route::cutPath(uint32_t length) { 182 if (length == 0) { 183 if (!m_path.empty()) { 184 m_startNode = *m_current; 185 m_endNode = *m_current; 186 m_path.clear(); 187 m_current = m_path.end(); 188 } 189 m_status = ROUTE_CREATED; 190 m_walked = 1; 191 m_replanned = true; 192 return; 193 } else if (length >= m_path.size()) { 194 return; 195 } 196 197 uint32_t newend = m_walked + length - 1; 198 if (newend > m_path.size()) { 199 return; 200 } 201 202 m_path.resize(newend); 203 m_endNode = m_path.back(); 204 m_replanned = true; 205 } 206 setReplanned(bool replanned)207 void Route::setReplanned(bool replanned) { 208 m_replanned = replanned; 209 } 210 isReplanned()211 bool Route::isReplanned() { 212 return m_replanned; 213 } 214 getPathLength()215 uint32_t Route::getPathLength() { 216 return m_path.size(); 217 } 218 getWalkedLength()219 uint32_t Route::getWalkedLength() { 220 return m_walked; 221 } 222 setSessionId(int32_t id)223 void Route::setSessionId(int32_t id) { 224 m_sessionId = id; 225 } 226 getSessionId()227 int32_t Route::getSessionId() { 228 return m_sessionId; 229 } 230 setRotation(int32_t rotation)231 void Route::setRotation(int32_t rotation) { 232 m_rotation = rotation; 233 } 234 getRotation()235 int32_t Route::getRotation() { 236 return m_rotation; 237 } 238 setCostId(const std::string & cost)239 void Route::setCostId(const std::string& cost) { 240 m_costId = cost; 241 } 242 getCostId()243 const std::string& Route::getCostId() { 244 return m_costId; 245 } 246 isMultiCell()247 bool Route::isMultiCell() { 248 if (m_object) { 249 return m_object->isMultiObject(); 250 } 251 return false; 252 } 253 setOccupiedArea(const std::vector<ModelCoordinate> & area)254 void Route::setOccupiedArea(const std::vector<ModelCoordinate>& area) { 255 m_area = area; 256 } 257 getOccupiedArea()258 const std::vector<ModelCoordinate>& Route::getOccupiedArea() { 259 return m_area; 260 } 261 getOccupiedCells(int32_t rotation)262 std::vector<ModelCoordinate> Route::getOccupiedCells(int32_t rotation) { 263 if (m_object) { 264 return m_object->getMultiObjectCoordinates(rotation); 265 } 266 std::vector<ModelCoordinate> coords; 267 return coords; 268 } 269 getZStepRange()270 int32_t Route::getZStepRange() { 271 if (!m_object) { 272 return -1; 273 } 274 return m_object->getZStepRange(); 275 } 276 isAreaLimited()277 bool Route::isAreaLimited() { 278 if (m_object) { 279 if (!m_object->getWalkableAreas().empty()) { 280 return true; 281 } 282 } 283 return false; 284 } 285 getLimitedAreas()286 const std::list<std::string> Route::getLimitedAreas() { 287 std::list<std::string> areas; 288 if (m_object) { 289 areas = m_object->getWalkableAreas(); 290 } 291 return areas; 292 } 293 setDynamicBlockerIgnored(bool ignore)294 void Route::setDynamicBlockerIgnored(bool ignore) { 295 m_ignoresBlocker = ignore; 296 } 297 isDynamicBlockerIgnored()298 bool Route::isDynamicBlockerIgnored() { 299 return m_ignoresBlocker; 300 } 301 getBlockingPathLocations()302 Path Route::getBlockingPathLocations() { 303 Path p; 304 if (!m_path.empty()) { 305 for (PathIterator it = m_path.begin(); it != m_path.end(); ++it) { 306 Layer* layer = (*it).getLayer(); 307 if (layer->cellContainsBlockingInstance((*it).getLayerCoordinates())) { 308 p.push_back(*it); 309 } 310 } 311 } 312 return p; 313 } 314 setObject(Object * obj)315 void Route::setObject(Object* obj) { 316 m_object = obj; 317 } 318 getObject()319 Object* Route::getObject() { 320 return m_object; 321 } 322 } // FIFE 323