- initial changes to support multiple path finders
This commit is contained in:
parent
f45619980f
commit
bca03b0c0c
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -72,6 +72,8 @@ private:
|
|||
GraphicLabel labelNetworkPauseGameForLaggedClients;
|
||||
GraphicListBox listBoxNetworkPauseGameForLaggedClients;
|
||||
|
||||
GraphicLabel labelPathFinderType;
|
||||
GraphicListBox listBoxPathFinderType;
|
||||
|
||||
bool needToSetChangedGameSettings;
|
||||
time_t lastSetChangedGameSettings;
|
||||
|
|
|
@ -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__);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue