- speed up some heavily used functions

This commit is contained in:
Mark Vejvoda 2012-04-17 07:51:45 +00:00
parent 8488b9c2b4
commit 6e7d4aeec5
4 changed files with 222 additions and 242 deletions

View File

@ -409,52 +409,6 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
// ==================== PRIVATE ====================
bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached,int maxNodeCount) {
bool result = false;
Vec2i sucPos= node->pos + Vec2i(i, j);
// std::map<int, std::map<Vec2i,std::map<Vec2i, bool> > >::iterator iterFind1 = factions[unit->getFactionIndex()].mapFromToNodeList.find(unit->getType()->getId());
// if(iterFind1 != factions[unit->getFactionIndex()].mapFromToNodeList.end()) {
// std::map<Vec2i,std::map<Vec2i, bool> >::iterator iterFind2 = iterFind1->second.find(node->pos);
// if(iterFind2 != iterFind1->second.end()) {
// std::map<Vec2i, bool>::iterator iterFind3 = iterFind2->second.find(sucPos);
// if(iterFind3 != iterFind2->second.end()) {
// //printf("found duplicate check in processNode\n");
// return iterFind3->second;
// }
// }
// }
//bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
//bool canUnitMoveToCell = map->aproxCanMoveSoon(unit, node->pos, sucPos);
if(openPos(sucPos, factions[unit->getFactionIndex()]) == false &&
canUnitMoveSoon(unit, node->pos, sucPos) == true) {
//if node is not open and canMove then generate another node
Node *sucNode= newNode(factions[unit->getFactionIndex()],maxNodeCount);
if(sucNode != NULL) {
sucNode->pos= sucPos;
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
sucNode->prev= node;
sucNode->next= NULL;
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear();
}
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode);
factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true;
result = true;
}
else {
nodeLimitReached= true;
}
}
// factions[unit->getFactionIndex()].mapFromToNodeList[unit->getType()->getId()][node->pos][sucPos] = result;
return result;
}
bool PathFinder::addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucPos, bool &nodeLimitReached,int maxNodeCount,Node **newNodeAdded, bool bypassChecks) {
bool result = false;
@ -1419,18 +1373,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
return ts;
}
PathFinder::Node *PathFinder::newNode(FactionState &faction, int maxNodeCount) {
if( faction.nodePoolCount < faction.nodePool.size() &&
//faction.nodePoolCount < faction.useMaxNodeCount) {
faction.nodePoolCount < maxNodeCount) {
Node *node= &(faction.nodePool[faction.nodePoolCount]);
node->clear();
faction.nodePoolCount++;
return node;
}
return NULL;
}
void PathFinder::processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist) {
Vec2i currPos= finalPos + Vec2i(i, j);
if(map->isAproxFreeCells(currPos, size, field, teamIndex)) {
@ -1478,31 +1420,6 @@ Vec2i PathFinder::computeNearestFreePos(const Unit *unit, const Vec2i &finalPos)
return nearestPos;
}
float PathFinder::heuristic(const Vec2i &pos, const Vec2i &finalPos) {
return pos.dist(finalPos);
}
PathFinder::Node * PathFinder::minHeuristicFastLookup(FactionState &faction) {
assert(faction.openNodesList.empty() == false);
if(faction.openNodesList.empty() == true) {
throw megaglest_runtime_error("openNodesList.empty() == true");
}
Node *result = faction.openNodesList.begin()->second[0];
faction.openNodesList.begin()->second.erase(faction.openNodesList.begin()->second.begin());
if(faction.openNodesList.begin()->second.size() == 0) {
faction.openNodesList.erase(faction.openNodesList.begin());
}
return result;
}
bool PathFinder::openPos(const Vec2i &sucPos, FactionState &faction) {
if(faction.openPosList.find(sucPos) == faction.openPosList.end()) {
return false;
}
return true;
}
int PathFinder::findNodeIndex(Node *node, Nodes &nodeList) {
int index = -1;
if(node != NULL) {
@ -1531,32 +1448,6 @@ int PathFinder::findNodeIndex(Node *node, std::vector<Node> &nodeList) {
return index;
}
bool PathFinder::canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) {
bool result = true;
// std::map<int,std::map<Field,BadUnitNodeList> > &badCellList = factions[unit->getFactionIndex()].badCellList;
// if(badCellList.find(unit->getType()->getSize()) != badCellList.end()) {
// std::map<Field,BadUnitNodeList> &badFieldList = badCellList[unit->getType()->getSize()];
// if(badFieldList.find(unit->getCurrField()) != badFieldList.end()) {
// BadUnitNodeList &badList = badFieldList[unit->getCurrField()];
// if(badList.isPosBad(pos1,pos2) == true) {
// result = false;
// }
// }
// }
// if(result == true) {
// //bool canUnitMoveToCell = map->canMove(unit, unitPos, pos);
// //bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos);
// result = map->aproxCanMoveSoon(unit, pos1, pos2);
// if(result == false) {
// badCellList[unit->getType()->getSize()][unit->getCurrField()].badPosList[pos1][pos2]=false;
// }
// }
result = map->aproxCanMoveSoon(unit, pos1, pos2);
return result;
}
void PathFinder::saveGame(XmlNode *rootNode) {
std::map<string,string> mapTagReplacements;
XmlNode *pathfinderNode = rootNode->addChild("PathFinder");

View File

@ -18,6 +18,9 @@
#include <map>
#include "game_constants.h"
#include "skill_type.h"
#include "map.h"
#include "unit.h"
#include "leak_dumper.h"
using std::vector;
@ -25,8 +28,8 @@ using Shared::Graphics::Vec2i;
namespace Glest { namespace Game {
class Map;
class Unit;
//class Map;
//class Unit;
// The order of directions is:
// N, NE, E, SE, S, SW, W, NW
@ -156,14 +159,96 @@ public:
private:
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1);
Node *newNode(FactionState &faction,int maxNodeCount);
//Node *newNode(FactionState &faction,int maxNodeCount);
inline static Node *newNode(FactionState &faction, int maxNodeCount) {
if( faction.nodePoolCount < faction.nodePool.size() &&
//faction.nodePoolCount < faction.useMaxNodeCount) {
faction.nodePoolCount < maxNodeCount) {
Node *node= &(faction.nodePool[faction.nodePoolCount]);
node->clear();
faction.nodePoolCount++;
return node;
}
return NULL;
}
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
float heuristic(const Vec2i &pos, const Vec2i &finalPos);
bool openPos(const Vec2i &sucPos,FactionState &faction);
//float heuristic(const Vec2i &pos, const Vec2i &finalPos);
inline static float heuristic(const Vec2i &pos, const Vec2i &finalPos) {
return pos.dist(finalPos);
}
Node * minHeuristicFastLookup(FactionState &faction);
//bool openPos(const Vec2i &sucPos,FactionState &faction);
inline static bool openPos(const Vec2i &sucPos, FactionState &faction) {
if(faction.openPosList.find(sucPos) == faction.openPosList.end()) {
return false;
}
return true;
}
//Node * minHeuristicFastLookup(FactionState &faction);
inline static Node * minHeuristicFastLookup(FactionState &faction) {
assert(faction.openNodesList.empty() == false);
if(faction.openNodesList.empty() == true) {
throw megaglest_runtime_error("openNodesList.empty() == true");
}
Node *result = faction.openNodesList.begin()->second[0];
faction.openNodesList.begin()->second.erase(faction.openNodesList.begin()->second.begin());
if(faction.openNodesList.begin()->second.size() == 0) {
faction.openNodesList.erase(faction.openNodesList.begin());
}
return result;
}
//bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached, int maxNodeCount);
inline bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached,int maxNodeCount) {
bool result = false;
Vec2i sucPos= node->pos + Vec2i(i, j);
// std::map<int, std::map<Vec2i,std::map<Vec2i, bool> > >::iterator iterFind1 = factions[unit->getFactionIndex()].mapFromToNodeList.find(unit->getType()->getId());
// if(iterFind1 != factions[unit->getFactionIndex()].mapFromToNodeList.end()) {
// std::map<Vec2i,std::map<Vec2i, bool> >::iterator iterFind2 = iterFind1->second.find(node->pos);
// if(iterFind2 != iterFind1->second.end()) {
// std::map<Vec2i, bool>::iterator iterFind3 = iterFind2->second.find(sucPos);
// if(iterFind3 != iterFind2->second.end()) {
// //printf("found duplicate check in processNode\n");
// return iterFind3->second;
// }
// }
// }
//bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
//bool canUnitMoveToCell = map->aproxCanMoveSoon(unit, node->pos, sucPos);
if(openPos(sucPos, factions[unit->getFactionIndex()]) == false &&
canUnitMoveSoon(unit, node->pos, sucPos) == true) {
//if node is not open and canMove then generate another node
Node *sucNode= newNode(factions[unit->getFactionIndex()],maxNodeCount);
if(sucNode != NULL) {
sucNode->pos= sucPos;
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
sucNode->prev= node;
sucNode->next= NULL;
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear();
}
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode);
factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true;
result = true;
}
else {
nodeLimitReached= true;
}
}
// factions[unit->getFactionIndex()].mapFromToNodeList[unit->getType()->getId()][node->pos][sucPos] = result;
return result;
}
bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached, int maxNodeCount);
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
int getPathFindExtendRefreshNodeCount(int factionIndex);
@ -187,7 +272,33 @@ private:
Vec2i jump(Vec2i dest, direction dir, Vec2i start,std::vector<Vec2i> &path,int pathLength);
bool addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucPos, bool &nodeLimitReached,int maxNodeCount,Node **newNodeAdded,bool bypassChecks);
bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2);
//bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2);
inline bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) {
bool result = true;
// std::map<int,std::map<Field,BadUnitNodeList> > &badCellList = factions[unit->getFactionIndex()].badCellList;
// if(badCellList.find(unit->getType()->getSize()) != badCellList.end()) {
// std::map<Field,BadUnitNodeList> &badFieldList = badCellList[unit->getType()->getSize()];
// if(badFieldList.find(unit->getCurrField()) != badFieldList.end()) {
// BadUnitNodeList &badList = badFieldList[unit->getCurrField()];
// if(badList.isPosBad(pos1,pos2) == true) {
// result = false;
// }
// }
// }
// if(result == true) {
// //bool canUnitMoveToCell = map->canMove(unit, unitPos, pos);
// //bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos);
// result = map->aproxCanMoveSoon(unit, pos1, pos2);
// if(result == false) {
// badCellList[unit->getType()->getSize()][unit->getCurrField()].badPosList[pos1][pos2]=false;
// }
// }
result = map->aproxCanMoveSoon(unit, pos1, pos2);
return result;
}
};
}}//end namespace

View File

@ -53,30 +53,8 @@ Cell::Cell() {
// ==================== misc ====================
//returns if the cell is free
bool Cell::isFree(Field field) const {
bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting();
if(result == false) {
//printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str());
}
return result;
}
//returns if the cell is free
bool Cell::isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const {
bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting();
if(result == false) {
if(originPos.dist(cellPos) > 5 && getUnit(field)->getType()->isMobile() == true) {
result = true;
}
//printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str());
}
return result;
}
void Cell::saveGame(XmlNode *rootNode, int index) const {
bool saveCell = false;
@ -171,16 +149,6 @@ void SurfaceCell::end(){
}
}
bool SurfaceCell::isFree() const {
bool result = object==NULL || object->getWalkable();
if(result == false) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
}
return result;
}
void SurfaceCell::deleteResource() {
cellChangedFromOriginalMapLoad = true;
@ -357,48 +325,6 @@ void Map::end(){
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
int Map::getSurfaceCellArraySize() const {
return (surfaceW * surfaceH);
}
SurfaceCell *Map::getSurfaceCell(const Vec2i &sPos) const {
return getSurfaceCell(sPos.x, sPos.y);
}
SurfaceCell *Map::getSurfaceCell(int sx, int sy) const {
int arrayIndex = sy * surfaceW + sx;
if(arrayIndex < 0 || arrayIndex >= getSurfaceCellArraySize()) {
throw megaglest_runtime_error("arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr(arrayIndex) +
" surfaceW = " + intToStr(surfaceW) + " surfaceH = " + intToStr(surfaceH) +
" sx: " + intToStr(sx) + " sy: " + intToStr(sy));
}
else if(surfaceCells == NULL) {
throw megaglest_runtime_error("surfaceCells == NULL");
}
return &surfaceCells[arrayIndex];
}
int Map::getCellArraySize() const {
return (w * h);
}
Cell *Map::getCell(const Vec2i &pos) const {
return getCell(pos.x, pos.y);
}
Cell *Map::getCell(int x, int y) const {
int arrayIndex = y * w + x;
if(arrayIndex < 0 || arrayIndex >= getCellArraySize()) {
//abort();
throw megaglest_runtime_error("arrayIndex >= getCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h));
}
else if(cells == NULL) {
throw megaglest_runtime_error("cells == NULL");
}
return &cells[arrayIndex];
}
Vec2i Map::getStartLocation(int locationIndex) const {
if(locationIndex >= maxPlayers) {
char szBuf[4096]="";
@ -558,22 +484,6 @@ void Map::init(Tileset *tileset) {
// ==================== is ====================
bool Map::isInside(int x, int y) const {
return x>=0 && y>=0 && x<w && y<h;
}
bool Map::isInside(const Vec2i &pos) const {
return isInside(pos.x, pos.y);
}
bool Map::isInsideSurface(int sx, int sy) const {
return sx>=0 && sy>=0 && sx<surfaceW && sy<surfaceH;
}
bool Map::isInsideSurface(const Vec2i &sPos) const {
return isInsideSurface(sPos.x, sPos.y);
}
class FindBestPos {
public:
float distanceFromUnitNoAdjustment;

View File

@ -20,6 +20,7 @@
#include "game_constants.h"
#include "selection.h"
#include <cassert>
#include "unit_type.h"
#include "leak_dumper.h"
@ -59,17 +60,37 @@ public:
Cell();
//get
Unit *getUnit(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return units[field];}
Unit *getUnitWithEmptyCellMap(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return unitsWithEmptyCellMap[field];}
float getHeight() const {return height;}
inline Unit *getUnit(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return units[field];}
inline Unit *getUnitWithEmptyCellMap(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return unitsWithEmptyCellMap[field];}
inline float getHeight() const {return height;}
void setUnit(int field, Unit *unit) { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} units[field]= unit;}
void setUnitWithEmptyCellMap(int field, Unit *unit) { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} unitsWithEmptyCellMap[field]= unit;}
void setHeight(float height) {this->height= height;}
bool isFree(Field field) const;
inline bool isFree(Field field) const {
bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting();
bool isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const;
if(result == false) {
//printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str());
}
return result;
}
inline bool isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const {
bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting();
if(result == false) {
if(originPos.dist(cellPos) > 5 && getUnit(field)->getType()->isMobile() == true) {
result = true;
}
//printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str());
}
return result;
}
void saveGame(XmlNode *rootNode,int index) const;
void loadGame(const XmlNode *rootNode, int index, World *world);
@ -125,8 +146,8 @@ public:
const Vec2f &getSurfTexCoord() const {return surfTexCoord;}
bool getNearSubmerged() const {return nearSubmerged;}
bool isVisible(int teamIndex) const {return visible[teamIndex];}
bool isExplored(int teamIndex) const {return explored[teamIndex];}
inline bool isVisible(int teamIndex) const {return visible[teamIndex];}
inline bool isExplored(int teamIndex) const {return explored[teamIndex];}
//set
void setVertex(const Vec3f &vertex) {this->vertex= vertex;}
@ -145,7 +166,14 @@ public:
//misc
void deleteResource();
bool decAmount(int value);
bool isFree() const;
inline bool isFree() const {
bool result = object==NULL || object->getWalkable();
if(result == false) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
}
return result;
}
bool getCellChangedFromOriginalMapLoad() const { return cellChangedFromOriginalMapLoad; }
void saveGame(XmlNode *rootNode,int index) const;
@ -196,34 +224,74 @@ public:
Checksum load(const string &path, TechTree *techTree, Tileset *tileset);
//get
Cell *getCell(int x, int y) const;
int getCellArraySize() const;
Cell *getCell(const Vec2i &pos) const;
int getSurfaceCellArraySize() const;
SurfaceCell *getSurfaceCell(int sx, int sy) const;
SurfaceCell *getSurfaceCell(const Vec2i &sPos) const;
int getW() const {return w;}
int getH() const {return h;}
int getSurfaceW() const {return surfaceW;}
int getSurfaceH() const {return surfaceH;}
int getMaxPlayers() const {return maxPlayers;}
float getHeightFactor() const {return heightFactor;}
float getWaterLevel() const {return waterLevel;}
float getCliffLevel() const {return cliffLevel;}
int getCameraHeight() const {return cameraHeight;}
float getMaxMapHeight() const {return maxMapHeight;}
inline Cell *getCell(int x, int y) const {
int arrayIndex = y * w + x;
if(arrayIndex < 0 || arrayIndex >= getCellArraySize()) {
//abort();
throw megaglest_runtime_error("arrayIndex >= getCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h));
}
else if(cells == NULL) {
throw megaglest_runtime_error("cells == NULL");
}
return &cells[arrayIndex];
}
inline Cell *getCell(const Vec2i &pos) const {
return getCell(pos.x, pos.y);
}
inline int getCellArraySize() const {
return (w * h);
}
inline int getSurfaceCellArraySize() const {
return (surfaceW * surfaceH);
}
inline SurfaceCell *getSurfaceCell(int sx, int sy) const {
int arrayIndex = sy * surfaceW + sx;
if(arrayIndex < 0 || arrayIndex >= getSurfaceCellArraySize()) {
throw megaglest_runtime_error("arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr(arrayIndex) +
" surfaceW = " + intToStr(surfaceW) + " surfaceH = " + intToStr(surfaceH) +
" sx: " + intToStr(sx) + " sy: " + intToStr(sy));
}
else if(surfaceCells == NULL) {
throw megaglest_runtime_error("surfaceCells == NULL");
}
return &surfaceCells[arrayIndex];
}
inline SurfaceCell *getSurfaceCell(const Vec2i &sPos) const {
return getSurfaceCell(sPos.x, sPos.y);
}
inline int getW() const {return w;}
inline int getH() const {return h;}
inline int getSurfaceW() const {return surfaceW;}
inline int getSurfaceH() const {return surfaceH;}
inline int getMaxPlayers() const {return maxPlayers;}
inline float getHeightFactor() const {return heightFactor;}
inline float getWaterLevel() const {return waterLevel;}
inline float getCliffLevel() const {return cliffLevel;}
inline int getCameraHeight() const {return cameraHeight;}
inline float getMaxMapHeight() const {return maxMapHeight;}
Vec2i getStartLocation(int locationIndex) const;
bool getSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel;}
bool getSubmerged(const Cell *c) const {return c->getHeight()<waterLevel;}
bool getDeepSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel-(1.5f/heightFactor);}
bool getDeepSubmerged(const Cell *c) const {return c->getHeight()<waterLevel-(1.5f/heightFactor);}
float getSurfaceHeight(const Vec2i &pos) const;
inline bool getSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel;}
inline bool getSubmerged(const Cell *c) const {return c->getHeight()<waterLevel;}
inline bool getDeepSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel-(1.5f/heightFactor);}
inline bool getDeepSubmerged(const Cell *c) const {return c->getHeight()<waterLevel-(1.5f/heightFactor);}
//float getSurfaceHeight(const Vec2i &pos) const;
//is
bool isInside(int x, int y) const;
bool isInside(const Vec2i &pos) const;
bool isInsideSurface(int sx, int sy) const;
bool isInsideSurface(const Vec2i &sPos) const;
inline bool isInside(int x, int y) const {
return x>=0 && y>=0 && x<w && y<h;
}
inline bool isInside(const Vec2i &pos) const {
return isInside(pos.x, pos.y);
}
inline bool isInsideSurface(int sx, int sy) const {
return sx>=0 && sy>=0 && sx<surfaceW && sy<surfaceH;
}
inline bool isInsideSurface(const Vec2i &sPos) const {
return isInsideSurface(sPos.x, sPos.y);
}
bool isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, int size, Unit *unit=NULL,bool fallbackToPeersHarvestingSameResource=false,Vec2i *resourceClickPos=NULL) const;
bool isResourceNear(const Vec2i &pos, int size, const ResourceType *rt, Vec2i &resourcePos) const;
@ -265,8 +333,8 @@ public:
void computeInterpolatedHeights();
//static
static Vec2i toSurfCoords(const Vec2i &unitPos) {return unitPos / cellScale;}
static Vec2i toUnitCoords(const Vec2i &surfPos) {return surfPos * cellScale;}
inline static Vec2i toSurfCoords(const Vec2i &unitPos) {return unitPos / cellScale;}
inline static Vec2i toUnitCoords(const Vec2i &surfPos) {return surfPos * cellScale;}
static string getMapPath(const string &mapName, string scenarioDir="", bool errorOnNotFound=true);
bool isFreeCellOrMightBeFreeSoon(Vec2i originPos, const Vec2i &pos, Field field) const;