- 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)
//
// 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<UnitPathBasic *>(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<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);
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<UnitPathBasic *>(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<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;
}
@ -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;

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) {
PF_TRACE();
WaypointPath &wpPath = *unit->getWaypointPath();
UnitPath &path = *unit->getPath();
UnitPathInterface *unitpath = unit->getPath();
UnitPath *advPath = dynamic_cast<UnitPath *>(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<UnitPath *>(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<Vec2i> 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);
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);
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);
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);
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);
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);
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);
UnitPath &path = *advPath;
WaypointPath &wpPath = *unit->getWaypointPath();
Vec2i dest;

View File

@ -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<UnitPath *>(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;

View File

@ -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__);

View File

@ -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,

View File

@ -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;
}

View File

@ -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<std::string> 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<PathFinderType>(listBoxPathFinderType.getSelectedItemIndex()));
// First save Used slots
//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 << "FogOfWar=" << gameSettings.getFogOfWar() << std::endl;
saveGameFile << "EnableObserverModeAtEndGame=" << gameSettings.getEnableObserverModeAtEndGame() << std::endl;
saveGameFile << "PathFinderType=" << gameSettings.getPathFinderType() << std::endl;
saveGameFile << "EnableServerControlledAI=" << gameSettings.getEnableServerControlledAI() << std::endl;
saveGameFile << "NetworkFramePeriod=" << gameSettings.getNetworkFramePeriod() << std::endl;
saveGameFile << "NetworkPauseGameForLaggedClients=" << gameSettings.getNetworkPauseGameForLaggedClients() << std::endl;
@ -1368,6 +1391,7 @@ GameSettings MenuStateCustomGame::loadGameSettingsFromFile(std::string fileName)
gameSettings.setDefaultVictoryConditions(properties.getBool("DefaultVictoryConditions"));
gameSettings.setFogOfWar(properties.getBool("FogOfWar"));
gameSettings.setEnableObserverModeAtEndGame(properties.getBool("EnableObserverModeAtEndGame"));
gameSettings.setPathFinderType(static_cast<PathFinderType>(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"));

View File

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

View File

@ -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*> 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__);

View File

@ -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<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
// =====================================================
/** Holds the next cells of a Unit movement
* @extends std::list<Shared::Math::Vec2i>
*/
class UnitPath : public list<Vec2i> {
class UnitPath : public list<Vec2i>, 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<Vec2i>::empty();} /**< is path empty */
virtual bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */
virtual bool isEmpty() const {return list<Vec2i>::empty();} /**< is path empty */
int size() const {return list<Vec2i>::size();} /**< size of path */
void clear() {list<Vec2i>::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<Vec2i>::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<Vec2i> {
@ -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

View File

@ -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);

View File

@ -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

View File

@ -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<const HarvestCommandType*>(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())<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
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<int>(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);
}
}

View File

@ -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;

View File

@ -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; 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();