- initial changes to support multiple path finders

This commit is contained in:
Mark Vejvoda 2010-07-21 18:21:40 +00:00
parent f45619980f
commit bca03b0c0c
16 changed files with 596 additions and 137 deletions

View File

@ -1,7 +1,7 @@
// ============================================================== // ==============================================================
// This file is part of Glest (www.glest.org) // 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 // You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published // the terms of the GNU General Public License as published
@ -55,22 +55,37 @@ PathFinder::~PathFinder(){
delete [] nodePool; delete [] nodePool;
} }
PathFinder::TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos){ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos){
//route cache //route cache
UnitPath *path= unit->getPath(); UnitPathInterface *path= unit->getPath();
if(finalPos==unit->getPos()){ if(finalPos==unit->getPos()) {
//if arrived //if arrived
unit->setCurrSkill(scStop); unit->setCurrSkill(scStop);
return tsArrived; return tsArrived;
} }
else if(!path->empty()){ else {
//route cache if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
Vec2i pos= path->peek(); if(!path->isEmpty()) {
if(map->canMove(unit, unit->getPos(), pos)){ //route cache
path->pop(); Vec2i pos= path->pop();
unit->setTargetPos(pos); if(map->canMove(unit, unit->getPos(), pos)) {
return tsOnTheWay; unit->setTargetPos(pos);
return tsOnTheWay;
}
}
}
else if(dynamic_cast<UnitPath *>(path) != NULL) {
UnitPath *advPath = dynamic_cast<UnitPath *>(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); unit->setCurrSkill(scStop);
break; break;
case tsOnTheWay: case tsOnTheWay:
Vec2i pos= path->peek(); {
if(map->canMove(unit, unit->getPos(), pos)){ if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
path->pop(); Vec2i pos= path->pop();
unit->setTargetPos(pos); if(map->canMove(unit, unit->getPos(), pos)) {
} unit->setTargetPos(pos);
else{ }
unit->setCurrSkill(scStop); else {
return tsBlocked; unit->setCurrSkill(scStop);
return tsBlocked;
}
}
else if(dynamic_cast<UnitPath *>(path) != NULL) {
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
Vec2i pos= advPath->peek();
if(map->canMove(unit, unit->getPos(), pos)) {
advPath->pop();
unit->setTargetPos(pos);
}
else {
unit->setCurrSkill(scStop);
return tsBlocked;
}
}
} }
break; break;
} }
@ -101,7 +131,7 @@ PathFinder::TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos){
// ==================== PRIVATE ==================== // ==================== PRIVATE ====================
//route a unit using A* algorithm //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; nodePoolCount= 0;
const Vec2i finalPos= computeNearestFreePos(unit, targetPos); const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
@ -185,7 +215,7 @@ PathFinder::TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos){
//check results of path finding //check results of path finding
TravelState ts; TravelState ts;
UnitPath *path= unit->getPath(); UnitPathInterface *path= unit->getPath();
if(pathFound==false || lastNode==firstNode){ if(pathFound==false || lastNode==firstNode){
//blocked //blocked
ts= tsBlocked; ts= tsBlocked;

View File

@ -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 <vector>
#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<Node*> 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

View File

@ -401,7 +401,11 @@ HAAStarResult RoutePlanner::findWaypointPathUnExplored(Unit *unit, const Vec2i &
bool RoutePlanner::refinePath(Unit *unit) { bool RoutePlanner::refinePath(Unit *unit) {
PF_TRACE(); PF_TRACE();
WaypointPath &wpPath = *unit->getWaypointPath(); WaypointPath &wpPath = *unit->getWaypointPath();
UnitPath &path = *unit->getPath();
UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
assert(!wpPath.empty()); assert(!wpPath.empty());
const Vec2i &startPos = path.empty() ? unit->getPos() : path.back(); const Vec2i &startPos = path.empty() ? unit->getPos() : path.back();
@ -437,7 +441,10 @@ bool RoutePlanner::refinePath(Unit *unit) {
void RoutePlanner::smoothPath(Unit *unit) { void RoutePlanner::smoothPath(Unit *unit) {
PF_TRACE(); PF_TRACE();
if (unit->getPath()->size() < 3) { UnitPathInterface *path = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
if (advPath->size() < 3) {
return; return;
} }
AnnotatedMap* const &aMap = world->getCartographer()->getMasterMap(); AnnotatedMap* const &aMap = world->getCartographer()->getMasterMap();
@ -446,8 +453,8 @@ void RoutePlanner::smoothPath(Unit *unit) {
min_y = 1 << 17, min_y = 1 << 17,
max_y = -1; max_y = -1;
set<Vec2i> onPath; set<Vec2i> onPath;
UnitPath::iterator it = unit->getPath()->begin(); UnitPath::iterator it = advPath->begin();
for ( ; it != unit->getPath()->end(); ++it) { for ( ; it != advPath->end(); ++it) {
if (it->x < min_x) min_x = it->x; if (it->x < min_x) min_x = it->x;
if (it->x > max_x) max_x = it->x; if (it->x > max_x) max_x = it->x;
if (it->y < min_y) min_y = it->y; 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); Rect2i bounds(min_x, min_y, max_x + 1, max_y + 1);
it = unit->getPath()->begin(); it = advPath->begin();
UnitPath::iterator nit = it; UnitPath::iterator nit = it;
++nit; ++nit;
while (nit != unit->getPath()->end()) { while (nit != advPath->end()) {
onPath.erase(*it); onPath.erase(*it);
Vec2i sp = *it; Vec2i sp = *it;
for (int d = 0; d < odCount; ++d) { for (int d = 0; d < odCount; ++d) {
@ -490,10 +497,10 @@ void RoutePlanner::smoothPath(Unit *unit) {
while (*eit != intersect) { while (*eit != intersect) {
onPath.erase(*eit++); onPath.erase(*eit++);
} }
nit = unit->getPath()->erase(nit, eit); nit = advPath->erase(nit, eit);
sp += OrdinalOffsets[d]; sp += OrdinalOffsets[d];
while (sp != intersect) { 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 ?? onPath.insert(sp); // do we need this? Can these get us further hits ??
sp += OrdinalOffsets[d]; sp += OrdinalOffsets[d];
} }
@ -507,7 +514,11 @@ void RoutePlanner::smoothPath(Unit *unit) {
TravelState RoutePlanner::doRouteCache(Unit *unit) { TravelState RoutePlanner::doRouteCache(Unit *unit) {
PF_TRACE(); PF_TRACE();
UnitPath &path = *unit->getPath();
UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
WaypointPath &wpPath = *unit->getWaypointPath(); WaypointPath &wpPath = *unit->getWaypointPath();
assert(unit->getPos().dist(path.front()) < 1.5f); assert(unit->getPos().dist(path.front()) < 1.5f);
if (attemptMove(unit)) { if (attemptMove(unit)) {
@ -540,7 +551,11 @@ TravelState RoutePlanner::doRouteCache(Unit *unit) {
TravelState RoutePlanner::doQuickPathSearch(Unit *unit, const Vec2i &target) { TravelState RoutePlanner::doQuickPathSearch(Unit *unit, const Vec2i &target) {
PF_TRACE(); PF_TRACE();
AnnotatedMap *aMap = world->getCartographer()->getAnnotatedMap(unit); AnnotatedMap *aMap = world->getCartographer()->getAnnotatedMap(unit);
UnitPath &path = *unit->getPath();
UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
// IF_DEBUG_EDITION( clearOpenClosed(unit->getPos(), target); ) // IF_DEBUG_EDITION( clearOpenClosed(unit->getPos(), target); )
aMap->annotateLocal(unit); aMap->annotateLocal(unit);
float cost = quickSearch(unit->getCurrField(), unit->getType()->getSize(), unit->getPos(), target); 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) { TravelState RoutePlanner::findAerialPath(Unit *unit, const Vec2i &targetPos) {
PF_TRACE(); PF_TRACE();
AnnotatedMap *aMap = world->getCartographer()->getMasterMap(); AnnotatedMap *aMap = world->getCartographer()->getMasterMap();
UnitPath &path = *unit->getPath(); UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
PosGoal goal(targetPos); PosGoal goal(targetPos);
MoveCost cost(unit, aMap); MoveCost cost(unit, aMap);
DiagonalDistance dd(targetPos); DiagonalDistance dd(targetPos);
@ -605,7 +622,9 @@ TravelState RoutePlanner::findAerialPath(Unit *unit, const Vec2i &targetPos) {
*/ */
TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos) { TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos) {
PF_TRACE(); PF_TRACE();
UnitPath &path = *unit->getPath(); UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
WaypointPath &wpPath = *unit->getWaypointPath(); WaypointPath &wpPath = *unit->getWaypointPath();
// if arrived (where we wanted to go) // 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) { TravelState RoutePlanner::customGoalSearch(PMap1Goal &goal, Unit *unit, const Vec2i &target) {
PF_TRACE(); PF_TRACE();
UnitPath &path = *unit->getPath();
UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
WaypointPath &wpPath = *unit->getWaypointPath(); WaypointPath &wpPath = *unit->getWaypointPath();
const Vec2i &start = unit->getPos(); const Vec2i &start = unit->getPos();
// setup search // 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) { TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2i &target) {
PF_TRACE(); PF_TRACE();
UnitPath &path = *unit->getPath(); UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
WaypointPath &wpPath = *unit->getWaypointPath(); WaypointPath &wpPath = *unit->getWaypointPath();
// if at goal // if at goal
@ -822,7 +846,9 @@ TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2
* @return true if repair succeeded */ * @return true if repair succeeded */
bool RoutePlanner::repairPath(Unit *unit) { bool RoutePlanner::repairPath(Unit *unit) {
PF_TRACE(); PF_TRACE();
UnitPath &path = *unit->getPath(); UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(unitpath);
UnitPath &path = *advPath;
WaypointPath &wpPath = *unit->getWaypointPath(); WaypointPath &wpPath = *unit->getWaypointPath();
Vec2i dest; Vec2i dest;

View File

@ -1,7 +1,7 @@
// ============================================================== // ==============================================================
// This file is part of Glest (www.glest.org) // 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 // 2009-2010 James McCulloch
// //
// You can redistribute this code and/or modify it under // You can redistribute this code and/or modify it under
@ -125,13 +125,6 @@ public:
} }
}; };
enum TravelState{
tsArrived,
tsMoving,
tsBlocked,
tsImpossible
};
enum HAAStarResult { enum HAAStarResult {
hsrFailed, hsrFailed,
hsrComplete, hsrComplete,
@ -194,11 +187,13 @@ private:
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos); Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
bool attemptMove(Unit *unit) const { bool attemptMove(Unit *unit) const {
assert(!unit->getPath()->empty()); UnitPathInterface *path = unit->getPath();
Vec2i pos = unit->getPath()->peek(); UnitPath *advPath = dynamic_cast<UnitPath *>(path);
assert(advPath->isEmpty() == false);
Vec2i pos = advPath->peek();
if (isLegalMove(unit, pos)) { if (isLegalMove(unit, pos)) {
unit->setTargetPos(pos); unit->setTargetPos(pos);
unit->getPath()->pop(); advPath->pop();
return true; return true;
} }
return false; return false;

View File

@ -101,7 +101,7 @@ Game::~Game(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
NetworkManager::getInstance().end(); NetworkManager::getInstance().end();
sleep(0); //sleep(0);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);

View File

@ -21,6 +21,19 @@ namespace Glest{ namespace Game{
// class GameConstants // class GameConstants
// ===================================================== // =====================================================
enum PathFinderType {
pfBasic,
pfRoutePlanner
};
enum TravelState {
tsArrived,
tsMoving,
tsBlocked,
tsOnTheWay,
tsImpossible
};
enum ControlType{ enum ControlType{
ctClosed, ctClosed,
ctCpuEasy, ctCpuEasy,

View File

@ -51,16 +51,18 @@ private:
bool enableServerControlledAI; bool enableServerControlledAI;
int networkFramePeriod; int networkFramePeriod;
bool networkPauseGameForLaggedClients; bool networkPauseGameForLaggedClients;
PathFinderType pathFinderType;
public: public:
GameSettings() { GameSettings() {
fogOfWar = true; fogOfWar = true;
enableObserverModeAtEndGame = false; enableObserverModeAtEndGame = false;
enableServerControlledAI = false; enableServerControlledAI = false;
networkFramePeriod = GameConstants::networkFramePeriod; networkFramePeriod = GameConstants::networkFramePeriod;
networkPauseGameForLaggedClients = false; networkPauseGameForLaggedClients = false;
pathFinderType = pfBasic;
for(int i = 0; i < GameConstants::maxPlayers; ++i) { for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factionTypeNames[i] = ""; factionTypeNames[i] = "";
@ -108,6 +110,7 @@ public:
bool getEnableServerControlledAI() const {return enableServerControlledAI;} bool getEnableServerControlledAI() const {return enableServerControlledAI;}
int getNetworkFramePeriod() const {return networkFramePeriod; } int getNetworkFramePeriod() const {return networkFramePeriod; }
bool getNetworkPauseGameForLaggedClients() const {return networkPauseGameForLaggedClients; } bool getNetworkPauseGameForLaggedClients() const {return networkPauseGameForLaggedClients; }
PathFinderType getPathFinderType() const { return pathFinderType; }
//set //set
void setDescription(const string& description) {this->description= description;} void setDescription(const string& description) {this->description= description;}
@ -134,6 +137,7 @@ public:
void setEnableServerControlledAI(bool value) {this->enableServerControlledAI = value;} void setEnableServerControlledAI(bool value) {this->enableServerControlledAI = value;}
void setNetworkFramePeriod(int value) {this->networkFramePeriod = value; } void setNetworkFramePeriod(int value) {this->networkFramePeriod = value; }
void setNetworkPauseGameForLaggedClients(bool value) {this->networkPauseGameForLaggedClients = value; } void setNetworkPauseGameForLaggedClients(bool value) {this->networkPauseGameForLaggedClients = value; }
void setPathFinderType(PathFinderType value) {this->pathFinderType = value; }
string toString() const { string toString() const {
string result = ""; string result = "";
@ -165,6 +169,7 @@ public:
result += "enableServerControlledAI = " + intToStr(enableServerControlledAI) + "\n"; result += "enableServerControlledAI = " + intToStr(enableServerControlledAI) + "\n";
result += "networkFramePeriod = " + intToStr(networkFramePeriod) + "\n"; result += "networkFramePeriod = " + intToStr(networkFramePeriod) + "\n";
result += "networkPauseGameForLaggedClients = " + intToStr(networkPauseGameForLaggedClients) + "\n"; result += "networkPauseGameForLaggedClients = " + intToStr(networkPauseGameForLaggedClients) + "\n";
result += "pathFinderType = " + intToStr(pathFinderType) + "\n";
return result; return result;
} }

View File

@ -154,19 +154,26 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
// fog - o - war // fog - o - war
// @350 ? 300 ? // @350 ? 300 ?
labelFogOfWar.init(400, aHeadPos, 80); labelFogOfWar.init(300, aHeadPos, 80);
listBoxFogOfWar.init(400, aPos, 80); listBoxFogOfWar.init(300, aPos, 80);
listBoxFogOfWar.pushBackItem(lang.get("Yes")); listBoxFogOfWar.pushBackItem(lang.get("Yes"));
listBoxFogOfWar.pushBackItem(lang.get("No")); listBoxFogOfWar.pushBackItem(lang.get("No"));
listBoxFogOfWar.setSelectedItemIndex(0); listBoxFogOfWar.setSelectedItemIndex(0);
// Enable Observer Mode // Enable Observer Mode
labelEnableObserverMode.init(600, aHeadPos, 80); labelEnableObserverMode.init(400, aHeadPos, 80);
listBoxEnableObserverMode.init(600, aPos, 80); listBoxEnableObserverMode.init(400, aPos, 110);
listBoxEnableObserverMode.pushBackItem(lang.get("Yes")); listBoxEnableObserverMode.pushBackItem(lang.get("Yes"));
listBoxEnableObserverMode.pushBackItem(lang.get("No")); listBoxEnableObserverMode.pushBackItem(lang.get("No"));
listBoxEnableObserverMode.setSelectedItemIndex(0); 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 //tileset listBox
findDirs(config.getPathListForType(ptTilesets), results); findDirs(config.getPathListForType(ptTilesets), results);
if (results.empty()) { if (results.empty()) {
@ -190,9 +197,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
labelTechTree.init(600, mapHeadPos); labelTechTree.init(600, mapHeadPos);
labelPublishServer.init(120, networkHeadPos, 100); labelPublishServer.init(50, networkHeadPos, 100);
labelPublishServer.setText(lang.get("PublishServer")); labelPublishServer.setText(lang.get("PublishServer"));
listBoxPublishServer.init(130, networkPos, 100); listBoxPublishServer.init(60, networkPos, 100);
listBoxPublishServer.pushBackItem(lang.get("Yes")); listBoxPublishServer.pushBackItem(lang.get("Yes"));
listBoxPublishServer.pushBackItem(lang.get("No")); listBoxPublishServer.pushBackItem(lang.get("No"));
if(openNetworkSlots) if(openNetworkSlots)
@ -201,10 +208,10 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
listBoxPublishServer.setSelectedItemIndex(1); listBoxPublishServer.setSelectedItemIndex(1);
labelPublishServerExternalPort.init(290, networkHeadPos, 150); labelPublishServerExternalPort.init(220, networkHeadPos, 150);
labelPublishServerExternalPort.setText(lang.get("PublishServerExternalPort")); 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()); string supportExternalPortList = config.getString("MasterServerExternalPortList",intToStr(GameConstants::serverPort).c_str());
std::vector<std::string> externalPortList; std::vector<std::string> externalPortList;
Tokenize(supportExternalPortList,externalPortList,","); Tokenize(supportExternalPortList,externalPortList,",");
@ -217,9 +224,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
listBoxPublishServer.setSelectedItemIndex(0); listBoxPublishServer.setSelectedItemIndex(0);
// Network Frame Period // Network Frame Period
labelNetworkFramePeriod.init(440, networkHeadPos, 80); labelNetworkFramePeriod.init(370, networkHeadPos, 80);
labelNetworkFramePeriod.setText(lang.get("NetworkFramePeriod")); labelNetworkFramePeriod.setText(lang.get("NetworkFramePeriod"));
listBoxNetworkFramePeriod.init(450, networkPos, 80); listBoxNetworkFramePeriod.init(380, networkPos, 80);
listBoxNetworkFramePeriod.pushBackItem("10"); listBoxNetworkFramePeriod.pushBackItem("10");
listBoxNetworkFramePeriod.pushBackItem("20"); listBoxNetworkFramePeriod.pushBackItem("20");
listBoxNetworkFramePeriod.pushBackItem("30"); listBoxNetworkFramePeriod.pushBackItem("30");
@ -227,18 +234,18 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
listBoxNetworkFramePeriod.setSelectedItem("20"); listBoxNetworkFramePeriod.setSelectedItem("20");
// Network Frame Period // Network Frame Period
labelNetworkPauseGameForLaggedClients.init(550, networkHeadPos, 80); labelNetworkPauseGameForLaggedClients.init(530, networkHeadPos, 80);
labelNetworkPauseGameForLaggedClients.setText(lang.get("NetworkPauseGameForLaggedClients")); labelNetworkPauseGameForLaggedClients.setText(lang.get("NetworkPauseGameForLaggedClients"));
listBoxNetworkPauseGameForLaggedClients.init(560, networkPos, 80); listBoxNetworkPauseGameForLaggedClients.init(540, networkPos, 80);
listBoxNetworkPauseGameForLaggedClients.pushBackItem(lang.get("No")); listBoxNetworkPauseGameForLaggedClients.pushBackItem(lang.get("No"));
listBoxNetworkPauseGameForLaggedClients.pushBackItem(lang.get("Yes")); listBoxNetworkPauseGameForLaggedClients.pushBackItem(lang.get("Yes"));
listBoxNetworkPauseGameForLaggedClients.setSelectedItem(lang.get("No")); listBoxNetworkPauseGameForLaggedClients.setSelectedItem(lang.get("No"));
// Enable Server Controlled AI // Enable Server Controlled AI
labelEnableServerControlledAI.init(690, networkHeadPos, 80); labelEnableServerControlledAI.init(670, networkHeadPos, 80);
labelEnableServerControlledAI.setText(lang.get("EnableServerControlledAI")); labelEnableServerControlledAI.setText(lang.get("EnableServerControlledAI"));
listBoxEnableServerControlledAI.init(700, networkPos, 80); listBoxEnableServerControlledAI.init(680, networkPos, 80);
listBoxEnableServerControlledAI.pushBackItem(lang.get("Yes")); listBoxEnableServerControlledAI.pushBackItem(lang.get("Yes"));
listBoxEnableServerControlledAI.pushBackItem(lang.get("No")); listBoxEnableServerControlledAI.pushBackItem(lang.get("No"));
listBoxEnableServerControlledAI.setSelectedItemIndex(0); listBoxEnableServerControlledAI.setSelectedItemIndex(0);
@ -546,6 +553,16 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
MutexSafeWrapper safeMutex(&masterServerThreadAccessor); MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true)
{
needToSetChangedGameSettings = true;
lastSetChangedGameSettings = time(NULL);
}
}
else if (listBoxPathFinderType.mouseClick(x, y)) {
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true) if(hasNetworkGameSettings() == true)
{ {
needToSetChangedGameSettings = true; needToSetChangedGameSettings = true;
@ -693,6 +710,9 @@ void MenuStateCustomGame::mouseMove(int x, int y, const MouseState *ms){
labelNetworkPauseGameForLaggedClients.mouseMove(x, y); labelNetworkPauseGameForLaggedClients.mouseMove(x, y);
listBoxNetworkPauseGameForLaggedClients.mouseMove(x, y); listBoxNetworkPauseGameForLaggedClients.mouseMove(x, y);
labelPathFinderType.mouseMove(x, y);
listBoxPathFinderType.mouseMove(x, y);
} }
void MenuStateCustomGame::render(){ void MenuStateCustomGame::render(){
@ -728,13 +748,14 @@ void MenuStateCustomGame::render(){
renderer.renderLabel(&labelTeam); renderer.renderLabel(&labelTeam);
renderer.renderLabel(&labelMapInfo); renderer.renderLabel(&labelMapInfo);
renderer.renderLabel(&labelEnableObserverMode); renderer.renderLabel(&labelEnableObserverMode);
renderer.renderLabel(&labelPathFinderType);
renderer.renderListBox(&listBoxMap); renderer.renderListBox(&listBoxMap);
renderer.renderListBox(&listBoxFogOfWar); renderer.renderListBox(&listBoxFogOfWar);
renderer.renderListBox(&listBoxTileset); renderer.renderListBox(&listBoxTileset);
renderer.renderListBox(&listBoxTechTree); renderer.renderListBox(&listBoxTechTree);
renderer.renderListBox(&listBoxEnableObserverMode); renderer.renderListBox(&listBoxEnableObserverMode);
renderer.renderListBox(&listBoxPathFinderType);
renderer.renderChatManager(&chatManager); renderer.renderChatManager(&chatManager);
renderer.renderConsole(&console,showFullConsole,true); renderer.renderConsole(&console,showFullConsole,true);
@ -1223,6 +1244,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) {
gameSettings->setDefaultVictoryConditions(true); gameSettings->setDefaultVictoryConditions(true);
gameSettings->setFogOfWar(listBoxFogOfWar.getSelectedItemIndex() == 0); gameSettings->setFogOfWar(listBoxFogOfWar.getSelectedItemIndex() == 0);
gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0);
gameSettings->setPathFinderType(static_cast<PathFinderType>(listBoxPathFinderType.getSelectedItemIndex()));
// First save Used slots // First save Used slots
//for(int i=0; i<mapInfo.players; ++i) //for(int i=0; i<mapInfo.players; ++i)
@ -1316,6 +1338,7 @@ void MenuStateCustomGame::saveGameSettingsToFile(std::string fileName) {
saveGameFile << "DefaultVictoryConditions=" << gameSettings.getDefaultVictoryConditions() << std::endl; saveGameFile << "DefaultVictoryConditions=" << gameSettings.getDefaultVictoryConditions() << std::endl;
saveGameFile << "FogOfWar=" << gameSettings.getFogOfWar() << std::endl; saveGameFile << "FogOfWar=" << gameSettings.getFogOfWar() << std::endl;
saveGameFile << "EnableObserverModeAtEndGame=" << gameSettings.getEnableObserverModeAtEndGame() << std::endl; saveGameFile << "EnableObserverModeAtEndGame=" << gameSettings.getEnableObserverModeAtEndGame() << std::endl;
saveGameFile << "PathFinderType=" << gameSettings.getPathFinderType() << std::endl;
saveGameFile << "EnableServerControlledAI=" << gameSettings.getEnableServerControlledAI() << std::endl; saveGameFile << "EnableServerControlledAI=" << gameSettings.getEnableServerControlledAI() << std::endl;
saveGameFile << "NetworkFramePeriod=" << gameSettings.getNetworkFramePeriod() << std::endl; saveGameFile << "NetworkFramePeriod=" << gameSettings.getNetworkFramePeriod() << std::endl;
saveGameFile << "NetworkPauseGameForLaggedClients=" << gameSettings.getNetworkPauseGameForLaggedClients() << std::endl; saveGameFile << "NetworkPauseGameForLaggedClients=" << gameSettings.getNetworkPauseGameForLaggedClients() << std::endl;
@ -1368,6 +1391,7 @@ GameSettings MenuStateCustomGame::loadGameSettingsFromFile(std::string fileName)
gameSettings.setDefaultVictoryConditions(properties.getBool("DefaultVictoryConditions")); gameSettings.setDefaultVictoryConditions(properties.getBool("DefaultVictoryConditions"));
gameSettings.setFogOfWar(properties.getBool("FogOfWar")); gameSettings.setFogOfWar(properties.getBool("FogOfWar"));
gameSettings.setEnableObserverModeAtEndGame(properties.getBool("EnableObserverModeAtEndGame")); gameSettings.setEnableObserverModeAtEndGame(properties.getBool("EnableObserverModeAtEndGame"));
gameSettings.setPathFinderType(static_cast<PathFinderType>(properties.getInt("PathFinderType",intToStr(pfBasic).c_str())));
gameSettings.setEnableServerControlledAI(properties.getBool("EnableServerControlledAI","false")); gameSettings.setEnableServerControlledAI(properties.getBool("EnableServerControlledAI","false"));
gameSettings.setNetworkFramePeriod(properties.getInt("NetworkFramePeriod",intToStr(GameConstants::networkFramePeriod).c_str())/10*10); gameSettings.setNetworkFramePeriod(properties.getInt("NetworkFramePeriod",intToStr(GameConstants::networkFramePeriod).c_str())/10*10);
gameSettings.setNetworkPauseGameForLaggedClients(properties.getBool("NetworkPauseGameForLaggedClients","false")); gameSettings.setNetworkPauseGameForLaggedClients(properties.getBool("NetworkPauseGameForLaggedClients","false"));
@ -1412,6 +1436,8 @@ GameSettings MenuStateCustomGame::loadGameSettingsFromFile(std::string fileName)
Lang &lang= Lang::getInstance(); Lang &lang= Lang::getInstance();
listBoxFogOfWar.setSelectedItem(gameSettings.getFogOfWar() == true ? lang.get("Yes") : lang.get("No")); listBoxFogOfWar.setSelectedItem(gameSettings.getFogOfWar() == true ? lang.get("Yes") : lang.get("No"));
listBoxEnableObserverMode.setSelectedItem(gameSettings.getEnableObserverModeAtEndGame() == 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")); listBoxEnableServerControlledAI.setSelectedItem(gameSettings.getEnableServerControlledAI() == true ? lang.get("Yes") : lang.get("No"));
labelNetworkFramePeriod.setText(lang.get("NetworkFramePeriod")); labelNetworkFramePeriod.setText(lang.get("NetworkFramePeriod"));

View File

@ -72,6 +72,8 @@ private:
GraphicLabel labelNetworkPauseGameForLaggedClients; GraphicLabel labelNetworkPauseGameForLaggedClients;
GraphicListBox listBoxNetworkPauseGameForLaggedClients; GraphicListBox listBoxNetworkPauseGameForLaggedClients;
GraphicLabel labelPathFinderType;
GraphicListBox listBoxPathFinderType;
bool needToSetChangedGameSettings; bool needToSetChangedGameSettings;
time_t lastSetChangedGameSettings; time_t lastSetChangedGameSettings;

View File

@ -34,6 +34,50 @@ using namespace Shared::Util;
namespace Glest{ namespace Game{ 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 // class UnitPath
// ===================================================== // =====================================================
@ -111,7 +155,7 @@ set<Unit*> Unit::livingUnitsp;
// ============================ Constructor & destructor ============================= // ============================ 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__); 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; RandomGen random;
this->unitPath = unitpath;
this->pos=pos; this->pos=pos;
this->type=type; this->type=type;
this->faction=faction; this->faction=faction;
@ -135,7 +180,7 @@ Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map
setModelFacing(placeFacing); setModelFacing(placeFacing);
Config &config= Config::getInstance(); Config &config= Config::getInstance();
showUnitParticles= config.getBool("UnitParticles"); showUnitParticles= config.getBool("UnitParticles");
lastPos= pos; lastPos= pos;
@ -212,6 +257,10 @@ Unit::~Unit(){
} }
stopDamageParticles(); stopDamageParticles();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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) { void Unit::setModelFacing(CardinalDir value) {
@ -643,7 +692,7 @@ CommandResult Unit::giveCommand(Command *command, bool tryQueue) {
//empty command queue //empty command queue
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
clearCommands(); clearCommands();
unitPath.clear(); this->unitPath->clear();
} }
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A\n",__FILE__,__FUNCTION__); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A\n",__FILE__,__FUNCTION__);
@ -684,7 +733,7 @@ CommandResult Unit::finishCommand(){
//pop front //pop front
delete commands.front(); delete commands.front();
commands.erase(commands.begin()); commands.erase(commands.begin());
unitPath.clear(); this->unitPath->clear();
while (!commands.empty()) { while (!commands.empty()) {
if (commands.front()->getUnit() != NULL && livingUnitsp.find(commands.front()->getUnit()) == livingUnitsp.end()) { if (commands.front()->getUnit() != NULL && livingUnitsp.find(commands.front()->getUnit()) == livingUnitsp.end()) {
@ -714,7 +763,7 @@ CommandResult Unit::cancelCommand(){
commands.pop_back(); commands.pop_back();
//clear routes //clear routes
unitPath.clear(); this->unitPath->clear();
return crSuccess; return crSuccess;
} }
@ -1589,7 +1638,7 @@ std::string Unit::toString() const {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
result += " totalUpgrade = " + totalUpgrade.toString(); result += " totalUpgrade = " + totalUpgrade.toString();
result += " " + unitPath.toString() + "\n"; result += " " + this->unitPath->toString() + "\n";
result += "\n"; result += "\n";
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);

View File

@ -95,13 +95,49 @@ public:
Faction *getUnitFaction() const { return faction; } 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<Vec2i> 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 // class UnitPath
// ===================================================== // =====================================================
/** Holds the next cells of a Unit movement /** Holds the next cells of a Unit movement
* @extends std::list<Shared::Math::Vec2i> * @extends std::list<Shared::Math::Vec2i>
*/ */
class UnitPath : public list<Vec2i> { class UnitPath : public list<Vec2i>, public UnitPathInterface {
private: private:
static const int maxBlockCount = 10; /**< number of command updates to wait on a blocked path */ static const int maxBlockCount = 10; /**< number of command updates to wait on a blocked path */
@ -110,12 +146,12 @@ private:
public: public:
UnitPath() : blockCount(0) {} /**< Construct path object */ UnitPath() : blockCount(0) {} /**< Construct path object */
bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */ virtual bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */
bool empty() const {return list<Vec2i>::empty();} /**< is path empty */ virtual bool isEmpty() const {return list<Vec2i>::empty();} /**< is path empty */
int size() const {return list<Vec2i>::size();} /**< size of path */ int size() const {return list<Vec2i>::size();} /**< size of path */
void clear() {list<Vec2i>::clear(); blockCount = 0;} /**< clear the path */ virtual void clear() {list<Vec2i>::clear(); blockCount = 0;} /**< clear the path */
void incBlockCount() {++blockCount;} /**< increment block counter */ virtual void incBlockCount() {++blockCount;} /**< increment block counter */
void push(Vec2i &pos) {push_front(pos);} /**< push onto front of path */ virtual void push(const Vec2i &pos) {push_front(pos);} /**< push onto front of path */
#if 0 #if 0
// old style, to work with original PathFinder // old style, to work with original PathFinder
@ -124,11 +160,11 @@ public:
#else #else
// new style, for the new RoutePlanner // new style, for the new RoutePlanner
Vec2i peek() {return front();} /**< peek at the next position */ 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 #endif
int getBlockCount() const { return blockCount; } int getBlockCount() const { return blockCount; }
std::string toString() const; virtual std::string toString() const;
}; };
class WaypointPath : public list<Vec2i> { class WaypointPath : public list<Vec2i> {
@ -205,7 +241,7 @@ private:
TotalUpgrade totalUpgrade; TotalUpgrade totalUpgrade;
Map *map; Map *map;
UnitPath unitPath; UnitPathInterface *unitPath;
WaypointPath waypointPath; WaypointPath waypointPath;
Commands commands; Commands commands;
@ -220,7 +256,7 @@ private:
bool visible; bool visible;
public: 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(); ~Unit();
//queries //queries
@ -256,8 +292,8 @@ public:
const Level *getLevel() const {return level;} const Level *getLevel() const {return level;}
const Level *getNextLevel() const; const Level *getNextLevel() const;
string getFullName() const; string getFullName() const;
const UnitPath *getPath() const {return &unitPath;} const UnitPathInterface *getPath() const {return unitPath;}
UnitPath *getPath() {return &unitPath;} UnitPathInterface *getPath() {return unitPath;}
WaypointPath *getWaypointPath() {return &waypointPath;} WaypointPath *getWaypointPath() {return &waypointPath;}
//pos //pos

View File

@ -247,6 +247,24 @@ bool Map::isInsideSurface(const Vec2i &sPos) const{
return isInsideSurface(sPos.x, sPos.y); 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 //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 { bool Map::isResourceNear(const Vec2i &pos, int size, const ResourceType *rt, Vec2i &resourcePos) const {
Vec2i p1 = pos + Vec2i(-1); Vec2i p1 = pos + Vec2i(-1);

View File

@ -196,6 +196,7 @@ public:
bool isInside(const Vec2i &pos) const; bool isInside(const Vec2i &pos) const;
bool isInsideSurface(int sx, int sy) const; bool isInsideSurface(int sx, int sy) const;
bool isInsideSurface(const Vec2i &sPos) 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; bool isResourceNear(const Vec2i &pos, int size, const ResourceType *rt, Vec2i &resourcePos) const;
//free cells //free cells

View File

@ -51,8 +51,15 @@ void UnitUpdater::init(Game *game){
this->map= world->getMap(); this->map= world->getMap();
this->console= game->getConsole(); this->console= game->getConsole();
this->scriptManager= game->getScriptManager(); 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(); Vec2i pos= command->getUnit()!=NULL? command->getUnit()->getCenteredPos(): command->getPos();
switch (routePlanner->findPath(unit, pos)) { TravelState tsValue = tsImpossible;
case PathFinder::tsOnTheWay: 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()); unit->setCurrSkill(mct->getMoveSkillType());
break; break;
case PathFinder::tsBlocked: case tsBlocked:
unit->setCurrSkill(scStop); unit->setCurrSkill(scStop);
if(unit->getPath()->isBlocked()){ if(unit->getPath()->isBlocked()){
unit->finishCommand(); unit->finishCommand();
@ -239,12 +256,22 @@ void UnitUpdater::updateAttack(Unit *unit){
pos= command->getPos(); 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 //if unit arrives destPos order has ended
switch (routePlanner->findPath(unit, pos)){ switch (tsValue){
case PathFinder::tsOnTheWay: case tsOnTheWay:
unit->setCurrSkill(act->getMoveSkillType()); unit->setCurrSkill(act->getMoveSkillType());
break; break;
case PathFinder::tsBlocked: case tsBlocked:
if(unit->getPath()->isBlocked()){ if(unit->getPath()->isBlocked()){
unit->finishCommand(); unit->finishCommand();
} }
@ -285,19 +312,51 @@ void UnitUpdater::updateBuild(Unit *unit){
//if not building //if not building
const UnitType *ut= command->getUnitType(); const UnitType *ut= command->getUnitType();
switch (routePlanner->findPathToBuildSite(unit, ut, command->getPos(), command->getFacing())) { TravelState tsValue = tsImpossible;
case PathFinder::tsOnTheWay: 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()); unit->setCurrSkill(bct->getMoveSkillType());
break; break;
case PathFinder::tsArrived: case tsArrived:
//if arrived destination {
//if arrived destination
assert(ut); 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(); const UnitType *builtUnitType= command->getUnitType();
CardinalDir facing = command->getFacing(); 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(); builtUnit->create();
if(!builtUnitType->hasSkillClass(scBeBuilt)){ if(!builtUnitType->hasSkillClass(scBeBuilt)){
@ -308,7 +367,15 @@ void UnitUpdater::updateBuild(Unit *unit){
unit->setCurrSkill(bct->getBuildSkillType()); unit->setCurrSkill(bct->getBuildSkillType());
unit->setTarget(builtUnit); unit->setTarget(builtUnit);
map->prepareTerrain(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); command->setUnit(builtUnit);
//play start sound //play start sound
@ -329,9 +396,10 @@ void UnitUpdater::updateBuild(Unit *unit){
console->addStdMessage("BuildingNoPlace"); console->addStdMessage("BuildingNoPlace");
} }
} }
}
break; break;
case PathFinder::tsBlocked: case tsBlocked:
if(unit->getPath()->isBlocked()){ if(unit->getPath()->isBlocked()){
unit->cancelCommand(); unit->cancelCommand();
} }
@ -375,6 +443,9 @@ void UnitUpdater::updateHarvest(Unit *unit){
const HarvestCommandType *hct= static_cast<const HarvestCommandType*>(command->getCommandType()); const HarvestCommandType *hct= static_cast<const HarvestCommandType*>(command->getCommandType());
Vec2i targetPos; Vec2i targetPos;
TravelState tsValue = tsImpossible;
UnitPathInterface *path= unit->getPath();
if(unit->getCurrSkill()->getClass() != scHarvest) { if(unit->getCurrSkill()->getClass() != scHarvest) {
//if not working //if not working
if(unit->getLoadCount()==0){ if(unit->getLoadCount()==0){
@ -382,23 +453,52 @@ void UnitUpdater::updateHarvest(Unit *unit){
Resource *r= map->getSurfaceCell(Map::toSurfCoords(command->getPos()))->getResource(); Resource *r= map->getSurfaceCell(Map::toSurfCoords(command->getPos()))->getResource();
if(r!=NULL && hct->canHarvest(r->getType())){ if(r!=NULL && hct->canHarvest(r->getType())){
//if can harvest dest. pos //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())<harvestDistance &&
map->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 //if it finds resources it starts harvesting
unit->setCurrSkill(hct->getHarvestSkillType()); unit->setCurrSkill(hct->getHarvestSkillType());
unit->setTargetPos(targetPos); unit->setTargetPos(targetPos);
command->setPos(targetPos); command->setPos(targetPos);
unit->setLoadCount(0); 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 //if not continue walking
switch (routePlanner->findPathToResource(unit, command->getPos(), r->getType())) { TravelState tsValue = tsImpossible;
case tsMoving: switch(this->game->getGameSettings()->getPathFinderType()) {
unit->setCurrSkill(hct->getMoveSkillType()); case pfBasic:
break; tsValue = pathFinder.findPath(unit, command->getPos());
default: if (tsValue == tsOnTheWay) {
break; unit->setCurrSkill(hct->getMoveSkillType());
} }
break;
case pfRoutePlanner:
tsValue = routePlanner->findPathToResource(unit, command->getPos(), r->getType());
if (tsValue == tsMoving) {
unit->setCurrSkill(hct->getMoveSkillType());
}
break;
}
} }
} }
else{ else{
@ -412,9 +512,19 @@ void UnitUpdater::updateHarvest(Unit *unit){
else{ else{
//if loaded, return to store //if loaded, return to store
Unit *store= world->nearestStore(unit->getPos(), unit->getFaction()->getIndex(), unit->getLoadType()); Unit *store= world->nearestStore(unit->getPos(), unit->getFaction()->getIndex(), unit->getLoadType());
if(store!=NULL){ if(store!=NULL) {
switch(routePlanner->findPathToStore(unit, store)){ TravelState tsValue = tsImpossible;
case PathFinder::tsOnTheWay: 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()); unit->setCurrSkill(hct->getMoveLoadedSkillType());
break; break;
default: default:
@ -471,7 +581,15 @@ void UnitUpdater::updateHarvest(Unit *unit){
if (r->decAmount(1)) { if (r->decAmount(1)) {
const ResourceType *rt = r->getType(); const ResourceType *rt = r->getType();
sc->deleteResource(); 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()); unit->setCurrSkill(hct->getStopLoadedSkillType());
} }
} }
@ -500,6 +618,8 @@ void UnitUpdater::updateRepair(Unit *unit){
Unit *repaired= map->getCell(command->getPos())->getUnit(fLand); Unit *repaired= map->getCell(command->getPos())->getUnit(fLand);
bool nextToRepaired= repaired!=NULL && map->isNextTo(unit->getPos(), repaired); bool nextToRepaired= repaired!=NULL && map->isNextTo(unit->getPos(), repaired);
UnitPathInterface *path= unit->getPath();
if(unit->getCurrSkill()->getClass()!=scRepair || !nextToRepaired){ if(unit->getCurrSkill()->getClass()!=scRepair || !nextToRepaired){
//if not repairing //if not repairing
if(repaired!=NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()){ if(repaired!=NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()){
@ -508,18 +628,27 @@ void UnitUpdater::updateRepair(Unit *unit){
unit->setTarget(repaired); unit->setTarget(repaired);
unit->setCurrSkill(rct->getRepairSkillType()); unit->setCurrSkill(rct->getRepairSkillType());
} }
else{ else {
TravelState ts; TravelState ts;
if (repaired && !repaired->getType()->isMobile()) { switch(this->game->getGameSettings()->getPathFinderType()) {
ts = routePlanner->findPathToBuildSite(unit, repaired->getType(), repaired->getPos(), repaired->getModelFacing()); case pfBasic:
} else { ts = pathFinder.findPath(unit, command->getPos());
ts = routePlanner->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) { switch(ts) {
case PathFinder::tsOnTheWay: case tsOnTheWay:
unit->setCurrSkill(rct->getMoveSkillType()); unit->setCurrSkill(rct->getMoveSkillType());
break; break;
case PathFinder::tsBlocked: case tsBlocked:
if(unit->getPath()->isBlocked()){ if(unit->getPath()->isBlocked()){
unit->finishCommand(); unit->finishCommand();
} }
@ -568,7 +697,18 @@ void UnitUpdater::updateProduce(Unit *unit){
if(unit->getProgress2()>pct->getProduced()->getProductionTime()){ if(unit->getProgress2()>pct->getProduced()->getProductionTime()){
unit->finishCommand(); unit->finishCommand();
unit->setCurrSkill(scStop); 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()); 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{ else{
unit->update2(); unit->update2();
if(unit->getProgress2()>mct->getProduced()->getProductionTime()){ if(unit->getProgress2()>mct->getProduced()->getProductionTime()){
int oldSize = 0;
bool needMapUpdate = false;
int oldSize = unit->getType()->getSize(); switch(this->game->getGameSettings()->getPathFinderType()) {
bool needMapUpdate = unit->getType()->isMobile() != mct->getMorphUnit()->isMobile(); case pfBasic:
break;
case pfRoutePlanner:
oldSize = unit->getType()->getSize();
needMapUpdate = unit->getType()->isMobile() != mct->getMorphUnit()->isMobile();
break;
}
//finish the command //finish the command
if(unit->morph(mct)){ if(unit->morph(mct)){
@ -648,10 +796,17 @@ void UnitUpdater::updateMorph(Unit *unit){
if(gui->isSelected(unit)){ if(gui->isSelected(unit)){
gui->onSelectionChanged(); gui->onSelectionChanged();
} }
if (needMapUpdate) { switch(this->game->getGameSettings()->getPathFinderType()) {
int size = std::max(oldSize, unit->getType()->getSize()); case pfBasic:
world->getCartographer()->updateMapMetrics(unit->getPos(), size); break;
} case pfRoutePlanner:
if (needMapUpdate) {
int size = std::max(oldSize, unit->getType()->getSize());
world->getCartographer()->updateMapMetrics(unit->getPos(), size);
}
break;
}
scriptManager->onUnitCreated(unit); scriptManager->onUnitCreated(unit);
} }
else{ else{
@ -720,9 +875,16 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac
if(attacked->decHp(static_cast<int>(damage))){ if(attacked->decHp(static_cast<int>(damage))){
world->getStats()->kill(attacker->getFactionIndex(), attacked->getFactionIndex()); world->getStats()->kill(attacker->getFactionIndex(), attacked->getFactionIndex());
attacker->incKills(); 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); scriptManager->onUnitDied(attacked);
} }
} }

View File

@ -43,7 +43,7 @@ private:
private: private:
static const int maxResSearchRadius= 10; static const int maxResSearchRadius= 10;
//static const int harvestDistance= 5; static const int harvestDistance= 5;
static const int ultraResourceFactor= 3; static const int ultraResourceFactor= 3;
static const int megaResourceFactor= 4; static const int megaResourceFactor= 4;
@ -54,7 +54,7 @@ private:
World *world; World *world;
Console *console; Console *console;
ScriptManager *scriptManager; ScriptManager *scriptManager;
//PathFinder pathFinder; PathFinder pathFinder;
RoutePlanner *routePlanner; RoutePlanner *routePlanner;
Game *game; Game *game;
RandomGen random; RandomGen random;

View File

@ -442,7 +442,17 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po
const FactionType* ft= faction->getType(); const FactionType* ft= faction->getType();
const UnitType* ut= ft->getUnitType(unitName); 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()); 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); const UnitType *ut= ft->getStartingUnit(j);
int initNumber= ft->getStartingUnitAmount(j); int initNumber= ft->getStartingUnitAmount(j);
for(int l=0; l<initNumber; l++){ for(int l=0; l<initNumber; l++){
Unit *unit= new Unit(getNextUnitId(f), Vec2i(0), ut, f, &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(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH);
int startLocationIndex= f->getStartLocationIndex(); int startLocationIndex= f->getStartLocationIndex();