From bca03b0c0cb9247972265535f81e2a8b7632d474 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Wed, 21 Jul 2010 18:21:40 +0000 Subject: [PATCH] - initial changes to support multiple path finders --- source/glest_game/ai/path_finder.cpp | 72 +++-- source/glest_game/ai/path_finder.h | 75 +++++ source/glest_game/ai/route_planner.cpp | 56 +++- source/glest_game/ai/route_planner.h | 17 +- source/glest_game/game/game.cpp | 2 +- source/glest_game/game/game_constants.h | 13 + source/glest_game/game/game_settings.h | 11 +- .../menu/menu_state_custom_game.cpp | 56 +++- .../glest_game/menu/menu_state_custom_game.h | 2 + source/glest_game/type_instances/unit.cpp | 61 +++- source/glest_game/type_instances/unit.h | 60 +++- source/glest_game/world/map.cpp | 18 ++ source/glest_game/world/map.h | 1 + source/glest_game/world/unit_updater.cpp | 260 ++++++++++++++---- source/glest_game/world/unit_updater.h | 4 +- source/glest_game/world/world.cpp | 25 +- 16 files changed, 596 insertions(+), 137 deletions(-) create mode 100644 source/glest_game/ai/path_finder.h diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index e7328f4e..5df68072 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -55,22 +55,37 @@ PathFinder::~PathFinder(){ delete [] nodePool; } -PathFinder::TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos){ +TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos){ //route cache - UnitPath *path= unit->getPath(); - if(finalPos==unit->getPos()){ + UnitPathInterface *path= unit->getPath(); + if(finalPos==unit->getPos()) { //if arrived unit->setCurrSkill(scStop); return tsArrived; } - else if(!path->empty()){ - //route cache - Vec2i pos= path->peek(); - if(map->canMove(unit, unit->getPos(), pos)){ - path->pop(); - unit->setTargetPos(pos); - return tsOnTheWay; + else { + if(dynamic_cast(path) != NULL) { + if(!path->isEmpty()) { + //route cache + Vec2i pos= path->pop(); + if(map->canMove(unit, unit->getPos(), pos)) { + unit->setTargetPos(pos); + return tsOnTheWay; + } + } + } + else if(dynamic_cast(path) != NULL) { + UnitPath *advPath = dynamic_cast(path); + if(advPath->isEmpty() == false) { + //route cache + Vec2i pos= advPath->peek(); + if(map->canMove(unit, unit->getPos(), pos)){ + path->pop(); + unit->setTargetPos(pos); + return tsOnTheWay; + } + } } } @@ -84,14 +99,29 @@ PathFinder::TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos){ unit->setCurrSkill(scStop); break; case tsOnTheWay: - Vec2i pos= path->peek(); - if(map->canMove(unit, unit->getPos(), pos)){ - path->pop(); - unit->setTargetPos(pos); - } - else{ - unit->setCurrSkill(scStop); - return tsBlocked; + { + if(dynamic_cast(path) != NULL) { + Vec2i pos= path->pop(); + if(map->canMove(unit, unit->getPos(), pos)) { + unit->setTargetPos(pos); + } + else { + unit->setCurrSkill(scStop); + return tsBlocked; + } + } + else if(dynamic_cast(path) != NULL) { + UnitPath *advPath = dynamic_cast(path); + Vec2i pos= advPath->peek(); + if(map->canMove(unit, unit->getPos(), pos)) { + advPath->pop(); + unit->setTargetPos(pos); + } + else { + unit->setCurrSkill(scStop); + return tsBlocked; + } + } } break; } @@ -101,7 +131,7 @@ PathFinder::TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos){ // ==================== PRIVATE ==================== //route a unit using A* algorithm -PathFinder::TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){ +TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){ nodePoolCount= 0; const Vec2i finalPos= computeNearestFreePos(unit, targetPos); @@ -185,7 +215,7 @@ PathFinder::TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){ //check results of path finding TravelState ts; - UnitPath *path= unit->getPath(); + UnitPathInterface *path= unit->getPath(); if(pathFound==false || lastNode==firstNode){ //blocked ts= tsBlocked; diff --git a/source/glest_game/ai/path_finder.h b/source/glest_game/ai/path_finder.h new file mode 100644 index 00000000..b708c92f --- /dev/null +++ b/source/glest_game/ai/path_finder.h @@ -0,0 +1,75 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _GLEST_GAME_PATHFINDER_H_ +#define _GLEST_GAME_PATHFINDER_H_ + +#include "vec.h" + +#include +#include "game_constants.h" + +using std::vector; +using Shared::Graphics::Vec2i; + +namespace Glest { namespace Game { + +class Map; +class Unit; + +// ===================================================== +// class PathFinder +// +/// Finds paths for units using a modification of the A* algorithm +// ===================================================== + +class PathFinder { +public: + struct Node{ + Vec2i pos; + Node *next; + Node *prev; + float heuristic; + bool exploredCell; + }; + typedef vector Nodes; + +public: + static const int maxFreeSearchRadius; + static const int pathFindNodesMax; + static const int pathFindRefresh; + +private: + Nodes openNodes; + Nodes closedNodes; + Node *nodePool; + int nodePoolCount; + const Map *map; + +public: + PathFinder(); + PathFinder(const Map *map); + ~PathFinder(); + void init(const Map *map); + TravelState findPath(Unit *unit, const Vec2i &finalPos); + +private: + TravelState aStar(Unit *unit, const Vec2i &finalPos); + Node *newNode(); + Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos); + float heuristic(const Vec2i &pos, const Vec2i &finalPos); + Nodes::iterator minHeuristic(); + bool openPos(const Vec2i &sucPos); +}; + +}}//end namespace + +#endif diff --git a/source/glest_game/ai/route_planner.cpp b/source/glest_game/ai/route_planner.cpp index 0125bf79..ba583bf7 100644 --- a/source/glest_game/ai/route_planner.cpp +++ b/source/glest_game/ai/route_planner.cpp @@ -401,7 +401,11 @@ HAAStarResult RoutePlanner::findWaypointPathUnExplored(Unit *unit, const Vec2i & bool RoutePlanner::refinePath(Unit *unit) { PF_TRACE(); WaypointPath &wpPath = *unit->getWaypointPath(); - UnitPath &path = *unit->getPath(); + + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + + UnitPath &path = *advPath; assert(!wpPath.empty()); const Vec2i &startPos = path.empty() ? unit->getPos() : path.back(); @@ -437,7 +441,10 @@ bool RoutePlanner::refinePath(Unit *unit) { void RoutePlanner::smoothPath(Unit *unit) { PF_TRACE(); - if (unit->getPath()->size() < 3) { + UnitPathInterface *path = unit->getPath(); + UnitPath *advPath = dynamic_cast(path); + + if (advPath->size() < 3) { return; } AnnotatedMap* const &aMap = world->getCartographer()->getMasterMap(); @@ -446,8 +453,8 @@ void RoutePlanner::smoothPath(Unit *unit) { min_y = 1 << 17, max_y = -1; set onPath; - UnitPath::iterator it = unit->getPath()->begin(); - for ( ; it != unit->getPath()->end(); ++it) { + UnitPath::iterator it = advPath->begin(); + for ( ; it != advPath->end(); ++it) { if (it->x < min_x) min_x = it->x; if (it->x > max_x) max_x = it->x; if (it->y < min_y) min_y = it->y; @@ -456,11 +463,11 @@ void RoutePlanner::smoothPath(Unit *unit) { } Rect2i bounds(min_x, min_y, max_x + 1, max_y + 1); - it = unit->getPath()->begin(); + it = advPath->begin(); UnitPath::iterator nit = it; ++nit; - while (nit != unit->getPath()->end()) { + while (nit != advPath->end()) { onPath.erase(*it); Vec2i sp = *it; for (int d = 0; d < odCount; ++d) { @@ -490,10 +497,10 @@ void RoutePlanner::smoothPath(Unit *unit) { while (*eit != intersect) { onPath.erase(*eit++); } - nit = unit->getPath()->erase(nit, eit); + nit = advPath->erase(nit, eit); sp += OrdinalOffsets[d]; while (sp != intersect) { - unit->getPath()->insert(nit, sp); + advPath->insert(nit, sp); onPath.insert(sp); // do we need this? Can these get us further hits ?? sp += OrdinalOffsets[d]; } @@ -507,7 +514,11 @@ void RoutePlanner::smoothPath(Unit *unit) { TravelState RoutePlanner::doRouteCache(Unit *unit) { PF_TRACE(); - UnitPath &path = *unit->getPath(); + + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + + UnitPath &path = *advPath; WaypointPath &wpPath = *unit->getWaypointPath(); assert(unit->getPos().dist(path.front()) < 1.5f); if (attemptMove(unit)) { @@ -540,7 +551,11 @@ TravelState RoutePlanner::doRouteCache(Unit *unit) { TravelState RoutePlanner::doQuickPathSearch(Unit *unit, const Vec2i &target) { PF_TRACE(); AnnotatedMap *aMap = world->getCartographer()->getAnnotatedMap(unit); - UnitPath &path = *unit->getPath(); + + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + + UnitPath &path = *advPath; // IF_DEBUG_EDITION( clearOpenClosed(unit->getPos(), target); ) aMap->annotateLocal(unit); float cost = quickSearch(unit->getCurrField(), unit->getType()->getSize(), unit->getPos(), target); @@ -567,7 +582,9 @@ TravelState RoutePlanner::doQuickPathSearch(Unit *unit, const Vec2i &target) { TravelState RoutePlanner::findAerialPath(Unit *unit, const Vec2i &targetPos) { PF_TRACE(); AnnotatedMap *aMap = world->getCartographer()->getMasterMap(); - UnitPath &path = *unit->getPath(); + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + UnitPath &path = *advPath; PosGoal goal(targetPos); MoveCost cost(unit, aMap); DiagonalDistance dd(targetPos); @@ -605,7 +622,9 @@ TravelState RoutePlanner::findAerialPath(Unit *unit, const Vec2i &targetPos) { */ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos) { PF_TRACE(); - UnitPath &path = *unit->getPath(); + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + UnitPath &path = *advPath; WaypointPath &wpPath = *unit->getWaypointPath(); // if arrived (where we wanted to go) @@ -715,7 +734,10 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos) TravelState RoutePlanner::customGoalSearch(PMap1Goal &goal, Unit *unit, const Vec2i &target) { PF_TRACE(); - UnitPath &path = *unit->getPath(); + + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + UnitPath &path = *advPath; WaypointPath &wpPath = *unit->getWaypointPath(); const Vec2i &start = unit->getPos(); // setup search @@ -751,7 +773,9 @@ TravelState RoutePlanner::customGoalSearch(PMap1Goal &goal, Unit *unit, const Ve TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2i &target) { PF_TRACE(); - UnitPath &path = *unit->getPath(); + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + UnitPath &path = *advPath; WaypointPath &wpPath = *unit->getWaypointPath(); // if at goal @@ -822,7 +846,9 @@ TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2 * @return true if repair succeeded */ bool RoutePlanner::repairPath(Unit *unit) { PF_TRACE(); - UnitPath &path = *unit->getPath(); + UnitPathInterface *unitpath = unit->getPath(); + UnitPath *advPath = dynamic_cast(unitpath); + UnitPath &path = *advPath; WaypointPath &wpPath = *unit->getWaypointPath(); Vec2i dest; diff --git a/source/glest_game/ai/route_planner.h b/source/glest_game/ai/route_planner.h index ca2831c5..89601d50 100644 --- a/source/glest_game/ai/route_planner.h +++ b/source/glest_game/ai/route_planner.h @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // 2009-2010 James McCulloch // // You can redistribute this code and/or modify it under @@ -125,13 +125,6 @@ public: } }; -enum TravelState{ - tsArrived, - tsMoving, - tsBlocked, - tsImpossible -}; - enum HAAStarResult { hsrFailed, hsrComplete, @@ -194,11 +187,13 @@ private: Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos); bool attemptMove(Unit *unit) const { - assert(!unit->getPath()->empty()); - Vec2i pos = unit->getPath()->peek(); + UnitPathInterface *path = unit->getPath(); + UnitPath *advPath = dynamic_cast(path); + assert(advPath->isEmpty() == false); + Vec2i pos = advPath->peek(); if (isLegalMove(unit, pos)) { unit->setTargetPos(pos); - unit->getPath()->pop(); + advPath->pop(); return true; } return false; diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 8f101fea..06bdab6e 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -101,7 +101,7 @@ Game::~Game(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); NetworkManager::getInstance().end(); - sleep(0); + //sleep(0); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/game/game_constants.h b/source/glest_game/game/game_constants.h index a91a799c..8d7f1290 100644 --- a/source/glest_game/game/game_constants.h +++ b/source/glest_game/game/game_constants.h @@ -21,6 +21,19 @@ namespace Glest{ namespace Game{ // class GameConstants // ===================================================== +enum PathFinderType { + pfBasic, + pfRoutePlanner +}; + +enum TravelState { + tsArrived, + tsMoving, + tsBlocked, + tsOnTheWay, + tsImpossible +}; + enum ControlType{ ctClosed, ctCpuEasy, diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index 47ac085b..0e4e8874 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -51,16 +51,18 @@ private: bool enableServerControlledAI; int networkFramePeriod; bool networkPauseGameForLaggedClients; + PathFinderType pathFinderType; public: GameSettings() { fogOfWar = true; - enableObserverModeAtEndGame = false; - enableServerControlledAI = false; - networkFramePeriod = GameConstants::networkFramePeriod; + enableObserverModeAtEndGame = false; + enableServerControlledAI = false; + networkFramePeriod = GameConstants::networkFramePeriod; networkPauseGameForLaggedClients = false; + pathFinderType = pfBasic; for(int i = 0; i < GameConstants::maxPlayers; ++i) { factionTypeNames[i] = ""; @@ -108,6 +110,7 @@ public: bool getEnableServerControlledAI() const {return enableServerControlledAI;} int getNetworkFramePeriod() const {return networkFramePeriod; } bool getNetworkPauseGameForLaggedClients() const {return networkPauseGameForLaggedClients; } + PathFinderType getPathFinderType() const { return pathFinderType; } //set void setDescription(const string& description) {this->description= description;} @@ -134,6 +137,7 @@ public: void setEnableServerControlledAI(bool value) {this->enableServerControlledAI = value;} void setNetworkFramePeriod(int value) {this->networkFramePeriod = value; } void setNetworkPauseGameForLaggedClients(bool value) {this->networkPauseGameForLaggedClients = value; } + void setPathFinderType(PathFinderType value) {this->pathFinderType = value; } string toString() const { string result = ""; @@ -165,6 +169,7 @@ public: result += "enableServerControlledAI = " + intToStr(enableServerControlledAI) + "\n"; result += "networkFramePeriod = " + intToStr(networkFramePeriod) + "\n"; result += "networkPauseGameForLaggedClients = " + intToStr(networkPauseGameForLaggedClients) + "\n"; + result += "pathFinderType = " + intToStr(pathFinderType) + "\n"; return result; } diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index d248c929..d036c9c0 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -154,19 +154,26 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b // fog - o - war // @350 ? 300 ? - labelFogOfWar.init(400, aHeadPos, 80); - listBoxFogOfWar.init(400, aPos, 80); + labelFogOfWar.init(300, aHeadPos, 80); + listBoxFogOfWar.init(300, aPos, 80); listBoxFogOfWar.pushBackItem(lang.get("Yes")); listBoxFogOfWar.pushBackItem(lang.get("No")); listBoxFogOfWar.setSelectedItemIndex(0); // Enable Observer Mode - labelEnableObserverMode.init(600, aHeadPos, 80); - listBoxEnableObserverMode.init(600, aPos, 80); + labelEnableObserverMode.init(400, aHeadPos, 80); + listBoxEnableObserverMode.init(400, aPos, 110); listBoxEnableObserverMode.pushBackItem(lang.get("Yes")); listBoxEnableObserverMode.pushBackItem(lang.get("No")); listBoxEnableObserverMode.setSelectedItemIndex(0); + labelPathFinderType.init(540, aHeadPos, 80); + labelPathFinderType.setText(lang.get("PathFinderType")); + listBoxPathFinderType.init(540, aPos, 140); + listBoxPathFinderType.pushBackItem(lang.get("PathFinderTypeRegular")); + listBoxPathFinderType.pushBackItem(lang.get("PathFinderTypeRoutePlanner")); + listBoxPathFinderType.setSelectedItemIndex(0); + //tileset listBox findDirs(config.getPathListForType(ptTilesets), results); if (results.empty()) { @@ -190,9 +197,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b labelTechTree.init(600, mapHeadPos); - labelPublishServer.init(120, networkHeadPos, 100); + labelPublishServer.init(50, networkHeadPos, 100); labelPublishServer.setText(lang.get("PublishServer")); - listBoxPublishServer.init(130, networkPos, 100); + listBoxPublishServer.init(60, networkPos, 100); listBoxPublishServer.pushBackItem(lang.get("Yes")); listBoxPublishServer.pushBackItem(lang.get("No")); if(openNetworkSlots) @@ -201,10 +208,10 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b listBoxPublishServer.setSelectedItemIndex(1); - labelPublishServerExternalPort.init(290, networkHeadPos, 150); + labelPublishServerExternalPort.init(220, networkHeadPos, 150); labelPublishServerExternalPort.setText(lang.get("PublishServerExternalPort")); - listBoxPublishServerExternalPort.init(300, networkPos, 100); + listBoxPublishServerExternalPort.init(230, networkPos, 100); string supportExternalPortList = config.getString("MasterServerExternalPortList",intToStr(GameConstants::serverPort).c_str()); std::vector externalPortList; Tokenize(supportExternalPortList,externalPortList,","); @@ -217,9 +224,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b listBoxPublishServer.setSelectedItemIndex(0); // Network Frame Period - labelNetworkFramePeriod.init(440, networkHeadPos, 80); + labelNetworkFramePeriod.init(370, networkHeadPos, 80); labelNetworkFramePeriod.setText(lang.get("NetworkFramePeriod")); - listBoxNetworkFramePeriod.init(450, networkPos, 80); + listBoxNetworkFramePeriod.init(380, networkPos, 80); listBoxNetworkFramePeriod.pushBackItem("10"); listBoxNetworkFramePeriod.pushBackItem("20"); listBoxNetworkFramePeriod.pushBackItem("30"); @@ -227,18 +234,18 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b listBoxNetworkFramePeriod.setSelectedItem("20"); // Network Frame Period - labelNetworkPauseGameForLaggedClients.init(550, networkHeadPos, 80); + labelNetworkPauseGameForLaggedClients.init(530, networkHeadPos, 80); labelNetworkPauseGameForLaggedClients.setText(lang.get("NetworkPauseGameForLaggedClients")); - listBoxNetworkPauseGameForLaggedClients.init(560, networkPos, 80); + listBoxNetworkPauseGameForLaggedClients.init(540, networkPos, 80); listBoxNetworkPauseGameForLaggedClients.pushBackItem(lang.get("No")); listBoxNetworkPauseGameForLaggedClients.pushBackItem(lang.get("Yes")); listBoxNetworkPauseGameForLaggedClients.setSelectedItem(lang.get("No")); // Enable Server Controlled AI - labelEnableServerControlledAI.init(690, networkHeadPos, 80); + labelEnableServerControlledAI.init(670, networkHeadPos, 80); labelEnableServerControlledAI.setText(lang.get("EnableServerControlledAI")); - listBoxEnableServerControlledAI.init(700, networkPos, 80); + listBoxEnableServerControlledAI.init(680, networkPos, 80); listBoxEnableServerControlledAI.pushBackItem(lang.get("Yes")); listBoxEnableServerControlledAI.pushBackItem(lang.get("No")); listBoxEnableServerControlledAI.setSelectedItemIndex(0); @@ -546,6 +553,16 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ MutexSafeWrapper safeMutex(&masterServerThreadAccessor); needToRepublishToMasterserver = true; + if(hasNetworkGameSettings() == true) + { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + else if (listBoxPathFinderType.mouseClick(x, y)) { + MutexSafeWrapper safeMutex(&masterServerThreadAccessor); + needToRepublishToMasterserver = true; + if(hasNetworkGameSettings() == true) { needToSetChangedGameSettings = true; @@ -693,6 +710,9 @@ void MenuStateCustomGame::mouseMove(int x, int y, const MouseState *ms){ labelNetworkPauseGameForLaggedClients.mouseMove(x, y); listBoxNetworkPauseGameForLaggedClients.mouseMove(x, y); + + labelPathFinderType.mouseMove(x, y); + listBoxPathFinderType.mouseMove(x, y); } void MenuStateCustomGame::render(){ @@ -728,13 +748,14 @@ void MenuStateCustomGame::render(){ renderer.renderLabel(&labelTeam); renderer.renderLabel(&labelMapInfo); renderer.renderLabel(&labelEnableObserverMode); + renderer.renderLabel(&labelPathFinderType); - renderer.renderListBox(&listBoxMap); renderer.renderListBox(&listBoxFogOfWar); renderer.renderListBox(&listBoxTileset); renderer.renderListBox(&listBoxTechTree); renderer.renderListBox(&listBoxEnableObserverMode); + renderer.renderListBox(&listBoxPathFinderType); renderer.renderChatManager(&chatManager); renderer.renderConsole(&console,showFullConsole,true); @@ -1223,6 +1244,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { gameSettings->setDefaultVictoryConditions(true); gameSettings->setFogOfWar(listBoxFogOfWar.getSelectedItemIndex() == 0); gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); + gameSettings->setPathFinderType(static_cast(listBoxPathFinderType.getSelectedItemIndex())); // First save Used slots //for(int i=0; i(properties.getInt("PathFinderType",intToStr(pfBasic).c_str()))); gameSettings.setEnableServerControlledAI(properties.getBool("EnableServerControlledAI","false")); gameSettings.setNetworkFramePeriod(properties.getInt("NetworkFramePeriod",intToStr(GameConstants::networkFramePeriod).c_str())/10*10); gameSettings.setNetworkPauseGameForLaggedClients(properties.getBool("NetworkPauseGameForLaggedClients","false")); @@ -1412,6 +1436,8 @@ GameSettings MenuStateCustomGame::loadGameSettingsFromFile(std::string fileName) Lang &lang= Lang::getInstance(); listBoxFogOfWar.setSelectedItem(gameSettings.getFogOfWar() == true ? lang.get("Yes") : lang.get("No")); listBoxEnableObserverMode.setSelectedItem(gameSettings.getEnableObserverModeAtEndGame() == true ? lang.get("Yes") : lang.get("No")); + listBoxPathFinderType.setSelectedItemIndex(gameSettings.getPathFinderType()); + listBoxEnableServerControlledAI.setSelectedItem(gameSettings.getEnableServerControlledAI() == true ? lang.get("Yes") : lang.get("No")); labelNetworkFramePeriod.setText(lang.get("NetworkFramePeriod")); diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index 7cc5dfec..c54c878b 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -72,6 +72,8 @@ private: GraphicLabel labelNetworkPauseGameForLaggedClients; GraphicListBox listBoxNetworkPauseGameForLaggedClients; + GraphicLabel labelPathFinderType; + GraphicListBox listBoxPathFinderType; bool needToSetChangedGameSettings; time_t lastSetChangedGameSettings; diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 1ef47673..5b38785c 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -34,6 +34,50 @@ using namespace Shared::Util; namespace Glest{ namespace Game{ +const int UnitPathBasic::maxBlockCount= 10; + +UnitPathBasic::UnitPathBasic() { + this->blockCount = 0; + this->pathQueue.clear(); +} + +bool UnitPathBasic::isEmpty() const { + return pathQueue.empty(); +} + +bool UnitPathBasic::isBlocked() const { + return blockCount >= maxBlockCount; +} + +void UnitPathBasic::clear() { + pathQueue.clear(); + blockCount= 0; +} + +void UnitPathBasic::incBlockCount() { + pathQueue.clear(); + blockCount++; +} + +void UnitPathBasic::push(const Vec2i &path){ + pathQueue.push_back(path); +} + +Vec2i UnitPathBasic::pop() { + Vec2i p= pathQueue.front(); + pathQueue.erase(pathQueue.begin()); + return p; +} +std::string UnitPathBasic::toString() const { + std::string result = ""; + + result = "unit path blockCount = " + intToStr(blockCount) + " pathQueue size = " + intToStr(pathQueue.size()); + for(int idx = 0; idx < pathQueue.size(); idx++) { + result += " index = " + intToStr(idx) + " " + pathQueue[idx].getString(); + } + + return result; +} // ===================================================== // class UnitPath // ===================================================== @@ -111,7 +155,7 @@ set Unit::livingUnitsp; // ============================ Constructor & destructor ============================= -Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) { +Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -119,6 +163,7 @@ Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map RandomGen random; + this->unitPath = unitpath; this->pos=pos; this->type=type; this->faction=faction; @@ -135,7 +180,7 @@ Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map setModelFacing(placeFacing); - Config &config= Config::getInstance(); + Config &config= Config::getInstance(); showUnitParticles= config.getBool("UnitParticles"); lastPos= pos; @@ -212,6 +257,10 @@ Unit::~Unit(){ } stopDamageParticles(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + delete this->unitPath; + this->unitPath = NULL; + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void Unit::setModelFacing(CardinalDir value) { @@ -643,7 +692,7 @@ CommandResult Unit::giveCommand(Command *command, bool tryQueue) { //empty command queue SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); clearCommands(); - unitPath.clear(); + this->unitPath->clear(); } //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A\n",__FILE__,__FUNCTION__); @@ -684,7 +733,7 @@ CommandResult Unit::finishCommand(){ //pop front delete commands.front(); commands.erase(commands.begin()); - unitPath.clear(); + this->unitPath->clear(); while (!commands.empty()) { if (commands.front()->getUnit() != NULL && livingUnitsp.find(commands.front()->getUnit()) == livingUnitsp.end()) { @@ -714,7 +763,7 @@ CommandResult Unit::cancelCommand(){ commands.pop_back(); //clear routes - unitPath.clear(); + this->unitPath->clear(); return crSuccess; } @@ -1589,7 +1638,7 @@ std::string Unit::toString() const { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); result += " totalUpgrade = " + totalUpgrade.toString(); - result += " " + unitPath.toString() + "\n"; + result += " " + this->unitPath->toString() + "\n"; result += "\n"; //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 5bb15bcd..8890f6b0 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -95,13 +95,49 @@ public: Faction *getUnitFaction() const { return faction; } }; +class UnitPathInterface { + +public: + + virtual bool isBlocked() const = 0; + virtual bool isEmpty() const = 0; + + virtual void clear() = 0; + virtual void incBlockCount() = 0; + virtual void push(const Vec2i &path) = 0; + virtual Vec2i pop() = 0; + + virtual std::string toString() const = 0; +}; + +class UnitPathBasic : public UnitPathInterface { +private: + static const int maxBlockCount; + +private: + int blockCount; + vector pathQueue; + +public: + UnitPathBasic(); + virtual bool isBlocked() const; + virtual bool isEmpty() const; + + virtual void clear(); + virtual void incBlockCount(); + virtual void push(const Vec2i &path); + Vec2i pop(); + + virtual std::string toString() const; +}; + // ===================================================== // class UnitPath // ===================================================== /** Holds the next cells of a Unit movement * @extends std::list */ -class UnitPath : public list { +class UnitPath : public list, public UnitPathInterface { private: static const int maxBlockCount = 10; /**< number of command updates to wait on a blocked path */ @@ -110,12 +146,12 @@ private: public: UnitPath() : blockCount(0) {} /**< Construct path object */ - bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */ - bool empty() const {return list::empty();} /**< is path empty */ + virtual bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */ + virtual bool isEmpty() const {return list::empty();} /**< is path empty */ int size() const {return list::size();} /**< size of path */ - void clear() {list::clear(); blockCount = 0;} /**< clear the path */ - void incBlockCount() {++blockCount;} /**< increment block counter */ - void push(Vec2i &pos) {push_front(pos);} /**< push onto front of path */ + virtual void clear() {list::clear(); blockCount = 0;} /**< clear the path */ + virtual void incBlockCount() {++blockCount;} /**< increment block counter */ + virtual void push(const Vec2i &pos) {push_front(pos);} /**< push onto front of path */ #if 0 // old style, to work with original PathFinder @@ -124,11 +160,11 @@ public: #else // new style, for the new RoutePlanner Vec2i peek() {return front();} /**< peek at the next position */ - void pop() {erase(begin());} /**< pop the next position off the path */ + virtual Vec2i pop() { Vec2i p= front(); erase(begin()); return p; } /**< pop the next position off the path */ #endif int getBlockCount() const { return blockCount; } - std::string toString() const; + virtual std::string toString() const; }; class WaypointPath : public list { @@ -205,7 +241,7 @@ private: TotalUpgrade totalUpgrade; Map *map; - UnitPath unitPath; + UnitPathInterface *unitPath; WaypointPath waypointPath; Commands commands; @@ -220,7 +256,7 @@ private: bool visible; public: - Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); + Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); ~Unit(); //queries @@ -256,8 +292,8 @@ public: const Level *getLevel() const {return level;} const Level *getNextLevel() const; string getFullName() const; - const UnitPath *getPath() const {return &unitPath;} - UnitPath *getPath() {return &unitPath;} + const UnitPathInterface *getPath() const {return unitPath;} + UnitPathInterface *getPath() {return unitPath;} WaypointPath *getWaypointPath() {return &waypointPath;} //pos diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 9c538639..1b99c87d 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -247,6 +247,24 @@ bool Map::isInsideSurface(const Vec2i &sPos) const{ return isInsideSurface(sPos.x, sPos.y); } +//returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource +bool Map::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos) const{ + for(int i=-1; i<=1; ++i){ + for(int j=-1; j<=1; ++j){ + if(isInside(pos.x+i, pos.y+j)){ + Resource *r= getSurfaceCell(toSurfCoords(Vec2i(pos.x+i, pos.y+j)))->getResource(); + if(r!=NULL){ + if(r->getType()==rt){ + resourcePos= pos + Vec2i(i,j); + return true; + } + } + } + } + } + return false; +} + //returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource bool Map::isResourceNear(const Vec2i &pos, int size, const ResourceType *rt, Vec2i &resourcePos) const { Vec2i p1 = pos + Vec2i(-1); diff --git a/source/glest_game/world/map.h b/source/glest_game/world/map.h index e4476a5e..aa3dc509 100755 --- a/source/glest_game/world/map.h +++ b/source/glest_game/world/map.h @@ -196,6 +196,7 @@ public: bool isInside(const Vec2i &pos) const; bool isInsideSurface(int sx, int sy) const; bool isInsideSurface(const Vec2i &sPos) const; + bool isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos) const; bool isResourceNear(const Vec2i &pos, int size, const ResourceType *rt, Vec2i &resourcePos) const; //free cells diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 6b23d8d3..d1c610a2 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -51,8 +51,15 @@ void UnitUpdater::init(Game *game){ this->map= world->getMap(); this->console= game->getConsole(); this->scriptManager= game->getScriptManager(); - routePlanner = world->getRoutePlanner(); - //pathFinder.init(map); + + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + pathFinder.init(map); + break; + case pfRoutePlanner: + routePlanner = world->getRoutePlanner(); + break; + } } @@ -190,12 +197,22 @@ void UnitUpdater::updateMove(Unit *unit){ Vec2i pos= command->getUnit()!=NULL? command->getUnit()->getCenteredPos(): command->getPos(); - switch (routePlanner->findPath(unit, pos)) { - case PathFinder::tsOnTheWay: + TravelState tsValue = tsImpossible; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder.findPath(unit, pos); + break; + case pfRoutePlanner: + tsValue = routePlanner->findPath(unit, pos); + break; + } + + switch (tsValue) { + case tsOnTheWay: unit->setCurrSkill(mct->getMoveSkillType()); break; - case PathFinder::tsBlocked: + case tsBlocked: unit->setCurrSkill(scStop); if(unit->getPath()->isBlocked()){ unit->finishCommand(); @@ -239,12 +256,22 @@ void UnitUpdater::updateAttack(Unit *unit){ pos= command->getPos(); } + TravelState tsValue = tsImpossible; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder.findPath(unit, pos); + break; + case pfRoutePlanner: + tsValue = routePlanner->findPath(unit, pos); + break; + } + //if unit arrives destPos order has ended - switch (routePlanner->findPath(unit, pos)){ - case PathFinder::tsOnTheWay: + switch (tsValue){ + case tsOnTheWay: unit->setCurrSkill(act->getMoveSkillType()); break; - case PathFinder::tsBlocked: + case tsBlocked: if(unit->getPath()->isBlocked()){ unit->finishCommand(); } @@ -285,19 +312,51 @@ void UnitUpdater::updateBuild(Unit *unit){ //if not building const UnitType *ut= command->getUnitType(); - switch (routePlanner->findPathToBuildSite(unit, ut, command->getPos(), command->getFacing())) { - case PathFinder::tsOnTheWay: + TravelState tsValue = tsImpossible; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder.findPath(unit, command->getPos()-Vec2i(1)); + break; + case pfRoutePlanner: + tsValue = routePlanner->findPathToBuildSite(unit, ut, command->getPos(), command->getFacing()); + break; + } + + switch (tsValue) { + case tsOnTheWay: unit->setCurrSkill(bct->getMoveSkillType()); break; - case PathFinder::tsArrived: - //if arrived destination + case tsArrived: + { + //if arrived destination assert(ut); - if (map->canOccupy(command->getPos(), ut->getField(), ut, command->getFacing())) { - //if(map->isFreeCells(command->getPos(), ut->getSize(), fLand)){ + + bool canOccupyCell = false; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + canOccupyCell = map->isFreeCells(command->getPos(), ut->getSize(), fLand); + break; + case pfRoutePlanner: + canOccupyCell = map->canOccupy(command->getPos(), ut->getField(), ut, command->getFacing()); + break; + } + + if (canOccupyCell == true) { const UnitType *builtUnitType= command->getUnitType(); CardinalDir facing = command->getFacing(); - Unit *builtUnit= new Unit(world->getNextUnitId(unit->getFaction()), command->getPos(), builtUnitType, unit->getFaction(), world->getMap(), facing); + + UnitPathInterface *newpath = NULL; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + case pfRoutePlanner: + newpath = new UnitPath(); + break; + } + + Unit *builtUnit= new Unit(world->getNextUnitId(unit->getFaction()), newpath, command->getPos(), builtUnitType, unit->getFaction(), world->getMap(), facing); builtUnit->create(); if(!builtUnitType->hasSkillClass(scBeBuilt)){ @@ -308,7 +367,15 @@ void UnitUpdater::updateBuild(Unit *unit){ unit->setCurrSkill(bct->getBuildSkillType()); unit->setTarget(builtUnit); map->prepareTerrain(builtUnit); - world->getCartographer()->updateMapMetrics(builtUnit->getPos(), builtUnit->getType()->getSight()); + + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + case pfRoutePlanner: + world->getCartographer()->updateMapMetrics(builtUnit->getPos(), builtUnit->getType()->getSight()); + break; + } + command->setUnit(builtUnit); //play start sound @@ -329,9 +396,10 @@ void UnitUpdater::updateBuild(Unit *unit){ console->addStdMessage("BuildingNoPlace"); } } + } break; - case PathFinder::tsBlocked: + case tsBlocked: if(unit->getPath()->isBlocked()){ unit->cancelCommand(); } @@ -375,6 +443,9 @@ void UnitUpdater::updateHarvest(Unit *unit){ const HarvestCommandType *hct= static_cast(command->getCommandType()); Vec2i targetPos; + TravelState tsValue = tsImpossible; + UnitPathInterface *path= unit->getPath(); + if(unit->getCurrSkill()->getClass() != scHarvest) { //if not working if(unit->getLoadCount()==0){ @@ -382,23 +453,52 @@ void UnitUpdater::updateHarvest(Unit *unit){ Resource *r= map->getSurfaceCell(Map::toSurfCoords(command->getPos()))->getResource(); if(r!=NULL && hct->canHarvest(r->getType())){ //if can harvest dest. pos - if (map->isResourceNear(unit->getPos(), unit->getType()->getSize(), r->getType(), targetPos)) { + bool canHarvestDestPos = false; + + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + canHarvestDestPos = (unit->getPos().dist(command->getPos())isResourceNear(unit->getPos(), r->getType(), targetPos)); + break; + case pfRoutePlanner: + canHarvestDestPos = map->isResourceNear(unit->getPos(), unit->getType()->getSize(), r->getType(), targetPos); + break; + } + + if (canHarvestDestPos == true) { //if it finds resources it starts harvesting unit->setCurrSkill(hct->getHarvestSkillType()); unit->setTargetPos(targetPos); command->setPos(targetPos); unit->setLoadCount(0); - unit->setLoadType(r->getType()); + + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + unit->setLoadType(map->getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->getResource()->getType()); + break; + case pfRoutePlanner: + unit->setLoadType(r->getType()); + break; + } } - else{ + else { + //if not continue walking - switch (routePlanner->findPathToResource(unit, command->getPos(), r->getType())) { - case tsMoving: - unit->setCurrSkill(hct->getMoveSkillType()); - break; - default: - break; - } + TravelState tsValue = tsImpossible; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder.findPath(unit, command->getPos()); + if (tsValue == tsOnTheWay) { + unit->setCurrSkill(hct->getMoveSkillType()); + } + break; + case pfRoutePlanner: + tsValue = routePlanner->findPathToResource(unit, command->getPos(), r->getType()); + if (tsValue == tsMoving) { + unit->setCurrSkill(hct->getMoveSkillType()); + } + break; + } } } else{ @@ -412,9 +512,19 @@ void UnitUpdater::updateHarvest(Unit *unit){ else{ //if loaded, return to store Unit *store= world->nearestStore(unit->getPos(), unit->getFaction()->getIndex(), unit->getLoadType()); - if(store!=NULL){ - switch(routePlanner->findPathToStore(unit, store)){ - case PathFinder::tsOnTheWay: + if(store!=NULL) { + TravelState tsValue = tsImpossible; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder.findPath(unit, store->getCenteredPos()); + break; + case pfRoutePlanner: + tsValue = routePlanner->findPathToStore(unit, store); + break; + } + + switch(tsValue) { + case tsOnTheWay: unit->setCurrSkill(hct->getMoveLoadedSkillType()); break; default: @@ -471,7 +581,15 @@ void UnitUpdater::updateHarvest(Unit *unit){ if (r->decAmount(1)) { const ResourceType *rt = r->getType(); sc->deleteResource(); - world->getCartographer()->onResourceDepleted(Map::toSurfCoords(unit->getTargetPos()), rt); + + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + case pfRoutePlanner: + world->getCartographer()->onResourceDepleted(Map::toSurfCoords(unit->getTargetPos()), rt); + break; + } + unit->setCurrSkill(hct->getStopLoadedSkillType()); } } @@ -500,6 +618,8 @@ void UnitUpdater::updateRepair(Unit *unit){ Unit *repaired= map->getCell(command->getPos())->getUnit(fLand); bool nextToRepaired= repaired!=NULL && map->isNextTo(unit->getPos(), repaired); + UnitPathInterface *path= unit->getPath(); + if(unit->getCurrSkill()->getClass()!=scRepair || !nextToRepaired){ //if not repairing if(repaired!=NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()){ @@ -508,18 +628,27 @@ void UnitUpdater::updateRepair(Unit *unit){ unit->setTarget(repaired); unit->setCurrSkill(rct->getRepairSkillType()); } - else{ + else { TravelState ts; - if (repaired && !repaired->getType()->isMobile()) { - ts = routePlanner->findPathToBuildSite(unit, repaired->getType(), repaired->getPos(), repaired->getModelFacing()); - } else { - ts = routePlanner->findPath(unit, command->getPos()); - } + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + ts = pathFinder.findPath(unit, command->getPos()); + break; + case pfRoutePlanner: + if (repaired && !repaired->getType()->isMobile()) { + ts = routePlanner->findPathToBuildSite(unit, repaired->getType(), repaired->getPos(), repaired->getModelFacing()); + } + else { + ts = routePlanner->findPath(unit, command->getPos()); + } + break; + } + switch(ts) { - case PathFinder::tsOnTheWay: + case tsOnTheWay: unit->setCurrSkill(rct->getMoveSkillType()); break; - case PathFinder::tsBlocked: + case tsBlocked: if(unit->getPath()->isBlocked()){ unit->finishCommand(); } @@ -568,7 +697,18 @@ void UnitUpdater::updateProduce(Unit *unit){ if(unit->getProgress2()>pct->getProduced()->getProductionTime()){ unit->finishCommand(); unit->setCurrSkill(scStop); - produced= new Unit(world->getNextUnitId(unit->getFaction()), Vec2i(0), pct->getProducedUnit(), unit->getFaction(), world->getMap(), CardinalDir::NORTH); + + UnitPathInterface *newpath = NULL; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + case pfRoutePlanner: + newpath = new UnitPath(); + break; + } + + produced= new Unit(world->getNextUnitId(unit->getFaction()), newpath, Vec2i(0), pct->getProducedUnit(), unit->getFaction(), world->getMap(), CardinalDir::NORTH); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to place unit for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,produced->toString().c_str()); @@ -638,9 +778,17 @@ void UnitUpdater::updateMorph(Unit *unit){ else{ unit->update2(); if(unit->getProgress2()>mct->getProduced()->getProductionTime()){ + int oldSize = 0; + bool needMapUpdate = false; - int oldSize = unit->getType()->getSize(); - bool needMapUpdate = unit->getType()->isMobile() != mct->getMorphUnit()->isMobile(); + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + case pfRoutePlanner: + oldSize = unit->getType()->getSize(); + needMapUpdate = unit->getType()->isMobile() != mct->getMorphUnit()->isMobile(); + break; + } //finish the command if(unit->morph(mct)){ @@ -648,10 +796,17 @@ void UnitUpdater::updateMorph(Unit *unit){ if(gui->isSelected(unit)){ gui->onSelectionChanged(); } - if (needMapUpdate) { - int size = std::max(oldSize, unit->getType()->getSize()); - world->getCartographer()->updateMapMetrics(unit->getPos(), size); - } + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + case pfRoutePlanner: + if (needMapUpdate) { + int size = std::max(oldSize, unit->getType()->getSize()); + world->getCartographer()->updateMapMetrics(unit->getPos(), size); + } + break; + } + scriptManager->onUnitCreated(unit); } else{ @@ -720,9 +875,16 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac if(attacked->decHp(static_cast(damage))){ world->getStats()->kill(attacker->getFactionIndex(), attacked->getFactionIndex()); attacker->incKills(); - if (!attacked->getType()->isMobile()) { - world->getCartographer()->updateMapMetrics(attacked->getPos(), attacked->getType()->getSize()); - } + + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + case pfRoutePlanner: + if (!attacked->getType()->isMobile()) { + world->getCartographer()->updateMapMetrics(attacked->getPos(), attacked->getType()->getSize()); + } + break; + } scriptManager->onUnitDied(attacked); } } diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index bf21a2d6..2f3c9ee3 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -43,7 +43,7 @@ private: private: static const int maxResSearchRadius= 10; - //static const int harvestDistance= 5; + static const int harvestDistance= 5; static const int ultraResourceFactor= 3; static const int megaResourceFactor= 4; @@ -54,7 +54,7 @@ private: World *world; Console *console; ScriptManager *scriptManager; - //PathFinder pathFinder; + PathFinder pathFinder; RoutePlanner *routePlanner; Game *game; RandomGen random; diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index bddf4bf4..2a1f5278 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -442,7 +442,17 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po const FactionType* ft= faction->getType(); const UnitType* ut= ft->getUnitType(unitName); - Unit* unit= new Unit(getNextUnitId(faction), pos, ut, faction, &map, CardinalDir::NORTH); + UnitPathInterface *newpath = NULL; + switch(game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + case pfRoutePlanner: + newpath = new UnitPath(); + break; + } + + Unit* unit= new Unit(getNextUnitId(faction), newpath, pos, ut, faction, &map, CardinalDir::NORTH); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); @@ -721,7 +731,18 @@ void World::initUnits(){ const UnitType *ut= ft->getStartingUnit(j); int initNumber= ft->getStartingUnitAmount(j); for(int l=0; lgetGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + case pfRoutePlanner: + newpath = new UnitPath(); + break; + } + + Unit *unit= new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH); int startLocationIndex= f->getStartLocationIndex();