- finally fixing issue #102 (bad cell visible handling when fog of war turned off)

This commit is contained in:
SoftCoder 2016-05-27 16:15:27 -07:00
parent 8a88c4f11e
commit 56494f3cd2
20 changed files with 588 additions and 122 deletions

View File

@ -329,6 +329,14 @@ Ai::~Ai() {
aiInterface = NULL;
}
RandomGen* Ai::getRandom() {
// if(Thread::isCurrentThreadMainThread() == false) {
// throw megaglest_runtime_error("Invalid access to AI random from outside main thread current id = " +
// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
// }
return &random;
}
void Ai::update() {
Chrono chrono;

View File

@ -198,7 +198,7 @@ public:
//state requests
AiInterface *getAiInterface() const {return aiInterface;}
RandomGen* getRandom() {return &random;}
RandomGen* getRandom();
int getCountOfType(const UnitType *ut);
int getMinWarriors() const { return minWarriors; }

View File

@ -51,8 +51,9 @@ PathFinder::PathFinder() {
}
int PathFinder::getPathFindExtendRefreshNodeCount(FactionState &faction) {
int refreshNodeCount = faction.random.randRange(PathFinder::pathFindExtendRefreshNodeCountMin,PathFinder::pathFindExtendRefreshNodeCountMax);
return refreshNodeCount;
//int refreshNodeCount = faction.random.randRange(PathFinder::pathFindExtendRefreshNodeCountMin,PathFinder::pathFindExtendRefreshNodeCountMax);
//return refreshNodeCount;
return PathFinder::pathFindExtendRefreshNodeCountMin;
}
PathFinder::PathFinder(const Map *map) {
@ -202,11 +203,19 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
unit->setTargetPos(pos);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"map->canMove to pos [%s] from [%s]",pos.getString().c_str(),unit->getPos().getString().c_str());
snprintf(szBuf,8096,"#1 map->canMove to pos [%s] from [%s]",pos.getString().c_str(),unit->getPos().getString().c_str());
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
unit->setTargetPos(pos,frameIndex < 0);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"#2 map->canMove to pos [%s] from [%s]",pos.getString().c_str(),unit->getPos().getString().c_str());
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
@ -222,7 +231,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
advPath->pop();
unit->setTargetPos(pos);
unit->setTargetPos(pos,frameIndex < 0);
}
return tsMoving;
@ -321,10 +330,29 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
int factionIndex = unit->getFactionIndex();
FactionState &faction = factions.getFactionState(factionIndex);
int tryRadius = faction.random.randRange(0,1);
if(Thread::isCurrentThreadMainThread() == false) {
throw megaglest_runtime_error("#2 Invalid access to FactionState random from outside main thread current id = " +
intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
}
int tryRadius = faction.random.randRange(1,2);
//int tryRadius = faction.random.IRandomX(1,2);
//int tryRadius = 1;
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In astar bailout() tryRadius %d",tryRadius);
if(frameIndex >= 0) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
// Try to bail out up to PathFinder::pathFindBailoutRadius cells away
if(tryRadius > 0) {
if(tryRadius == 2) {
for(int bailoutX = -PathFinder::pathFindBailoutRadius; bailoutX <= PathFinder::pathFindBailoutRadius && ts == tsBlocked; ++bailoutX) {
for(int bailoutY = -PathFinder::pathFindBailoutRadius; bailoutY <= PathFinder::pathFindBailoutRadius && ts == tsBlocked; ++bailoutY) {
const Vec2i newFinalPos = finalPos + Vec2i(bailoutX,bailoutY);
@ -413,7 +441,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
unit->setTargetPos(pos);
unit->setTargetPos(pos,frameIndex < 0);
}
}
else {
@ -438,7 +466,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
advPath->pop();
unit->setTargetPos(pos);
unit->setTargetPos(pos,frameIndex < 0);
}
}
else {
@ -594,11 +622,11 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
}
unit->setUsePathfinderExtendedMaxNodes(false);
// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
// char szBuf[8096]="";
// snprintf(szBuf,8096,"return factions[unitFactionIndex].precachedTravelState[unit->getId()];");
// unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
// }
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"return factions[unitFactionIndex].precachedTravelState[unit->getId()];");
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
return faction.precachedTravelState[unit->getId()];
}
@ -638,7 +666,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
const Vec2i unitPos = unit->getPos();
const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
float dist= unitPos.dist(finalPos);
float dist = unitPos.dist(finalPos);
faction.useMaxNodeCount = PathFinder::pathFindNodesMax;
@ -808,9 +836,9 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(nodeLimitReached == true) {
if(faction.closedNodesList.empty() == false) {
float bestHeuristic = faction.closedNodesList.begin()->first;
float bestHeuristic = truncateDecimal<float>(faction.closedNodesList.begin()->first,6);
if(lastNode != NULL && bestHeuristic < lastNode->heuristic) {
lastNode= faction.closedNodesList.begin()->second[0];
lastNode= faction.closedNodesList.begin()->second.front();
}
}
}
@ -889,7 +917,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(minorDebugPathfinder) printf("nodePos [%s]\n",nodePos.getString().c_str());
if(frameIndex >= 0) {
faction.precachedPath[unit->getId()].push_back(nodePos);
}
else {
@ -903,19 +930,37 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
string pathToTake = "";
for(int i = 0; i < path->getQueueCount(); ++i) {
Vec2i &pos = path->getQueue()[i];
if(pathToTake != "") {
pathToTake += ", ";
if(frameIndex < 0) {
vector<Vec2i> pathQueue = path->getQueue();
for(unsigned int index = 0; index < pathQueue.size(); ++index) {
Vec2i &pos = pathQueue[index];
if(pathToTake != "") {
pathToTake += ", ";
}
pathToTake += pos.getString();
}
}
else {
for(unsigned int index = 0; index < faction.precachedPath[unit->getId()].size(); ++index) {
Vec2i &pos = faction.precachedPath[unit->getId()][index];
if(pathToTake != "") {
pathToTake += ", ";
}
pathToTake += pos.getString();
}
pathToTake += pos.getString();
}
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
snprintf(szBuf,8096,"Path for unit to take = %s",pathToTake.c_str());
if(frameIndex < 0) {
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
else {
unit->logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
@ -976,25 +1021,24 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
void PathFinder::processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist) {
try {
Vec2i currPos= finalPos + Vec2i(i, j);
Vec2i currPos= finalPos + Vec2i(i, j);
if(map->isAproxFreeCells(currPos, size, field, teamIndex)) {
float dist= currPos.dist(finalPos);
if(map->isAproxFreeCells(currPos, size, field, teamIndex)) {
float dist = currPos.dist(finalPos);
//if nearer from finalPos
if(dist < nearestDist){
nearestPos= currPos;
nearestDist= dist;
}
//if the distance is the same compare distance to unit
else if(dist == nearestDist){
if(currPos.dist(unitPos) < nearestPos.dist(unitPos)) {
nearestPos= currPos;
//if nearer from finalPos
if(dist < nearestDist){
nearestPos = currPos;
nearestDist = dist;
}
//if the distance is the same compare distance to unit
else if(dist == nearestDist){
if(currPos.dist(unitPos) < nearestPos.dist(unitPos)) {
nearestPos = currPos;
}
}
}
}
}
catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
@ -1034,7 +1078,7 @@ Vec2i PathFinder::computeNearestFreePos(const Unit *unit, const Vec2i &finalPos)
Vec2i unitPos= unit->getPosNotThreadSafe();
nearestPos= unitPos;
float nearestDist= unitPos.dist(finalPos);
float nearestDist = unitPos.dist(finalPos);
for(int i= -maxFreeSearchRadius; i <= maxFreeSearchRadius; ++i) {
for(int j= -maxFreeSearchRadius; j <= maxFreeSearchRadius; ++j) {

View File

@ -24,7 +24,7 @@
#include "skill_type.h"
#include "map.h"
#include "unit.h"
//#include "randomc.h"
#include "leak_dumper.h"
using std::vector;
@ -90,15 +90,16 @@ public:
protected:
Mutex *factionMutexPrecache;
public:
FactionState() :
FactionState(int factionIndex) :
//factionMutexPrecache(new Mutex) {
factionMutexPrecache(NULL) {
factionMutexPrecache(NULL) { //, random(factionIndex) {
openPosList.clear();
openNodesList.clear();
closedNodesList.clear();
nodePool.clear();
nodePoolCount = 0;
this->factionIndex = factionIndex;
useMaxNodeCount = 0;
precachedTravelState.clear();
@ -119,7 +120,9 @@ public:
std::vector<Node> nodePool;
int nodePoolCount;
int factionIndex;
RandomGen random;
//CRandomMersenne random;
int useMaxNodeCount;
std::map<int,TravelState> precachedTravelState;
@ -133,7 +136,7 @@ public:
void init() {
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
factions.push_back(new FactionState());
factions.push_back(new FactionState(index));
}
}
@ -224,6 +227,7 @@ private:
}
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
inline static float heuristic(const Vec2i &pos, const Vec2i &finalPos) {
return pos.dist(finalPos);
}
@ -240,29 +244,44 @@ private:
throw megaglest_runtime_error("openNodesList.empty() == true");
}
Node *result = faction.openNodesList.begin()->second[0];
Node *result = faction.openNodesList.begin()->second.front();
faction.openNodesList.begin()->second.erase(faction.openNodesList.begin()->second.begin());
if(faction.openNodesList.begin()->second.size() == 0) {
if(faction.openNodesList.begin()->second.empty()) {
faction.openNodesList.erase(faction.openNodesList.begin());
}
return result;
}
inline bool processNode(Unit *unit, Node *node,const Vec2i finalPos,
int i, int j, bool &nodeLimitReached,int maxNodeCount) {
int x, int y, bool &nodeLimitReached,int maxNodeCount) {
bool result = false;
Vec2i sucPos= node->pos + Vec2i(i, j);
Vec2i sucPos= node->pos + Vec2i(x, y);
int unitFactionIndex = unit->getFactionIndex();
FactionState &faction = factions.getFactionState(unitFactionIndex);
if(openPos(sucPos, faction) == false &&
canUnitMoveSoon(unit, node->pos, sucPos) == true) {
bool foundOpenPosForPos = openPos(sucPos, faction);
bool allowUnitMoveSoon = canUnitMoveSoon(unit, node->pos, sucPos);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In processNode() nodeLimitReached %d unitFactionIndex %d foundOpenPosForPos %d allowUnitMoveSoon %d maxNodeCount %d node->pos = %s finalPos = %s sucPos = %s faction.openPosList.size() %ld closedNodesList.size() %ld",
nodeLimitReached,unitFactionIndex,foundOpenPosForPos, allowUnitMoveSoon, maxNodeCount,node->pos.getString().c_str(),finalPos.getString().c_str(),sucPos.getString().c_str(),faction.openPosList.size(),faction.closedNodesList.size());
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
if(foundOpenPosForPos == false && allowUnitMoveSoon) {
//if node is not open and canMove then generate another node
Node *sucNode= newNode(faction,maxNodeCount);
if(sucNode != NULL) {
sucNode->pos= sucPos;
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
sucNode->heuristic = heuristic(sucNode->pos, finalPos);
sucNode->prev= node;
sucNode->next= NULL;
sucNode->exploredCell = map->getSurfaceCell(
@ -274,6 +293,20 @@ private:
faction.openPosList[sucNode->pos] = true;
result = true;
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In processNode() sucPos = %s",sucPos.getString().c_str());
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
}
else {
nodeLimitReached= true;
@ -287,7 +320,7 @@ private:
Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
int getPathFindExtendRefreshNodeCount(FactionState &faction);
inline bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) {
inline bool canUnitMoveSoon(Unit *unit, const Vec2i &pos1, const Vec2i &pos2) {
bool result = map->aproxCanMoveSoon(unit, pos1, pos2);
return result;
}
@ -298,15 +331,58 @@ private:
std::map<Vec2i,Vec2i> cameFrom, std::map<std::pair<Vec2i,Vec2i> ,
bool> canAddNode, Unit *& unit, int & maxNodeCount, int curFrameIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d",
nodeLimitReached,whileLoopCount,unitFactionIndex,pathFound, maxNodeCount);
if(curFrameIndex >= 0) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
FactionState &faction = factions.getFactionState(unitFactionIndex);
while(nodeLimitReached == false) {
whileLoopCount++;
if(faction.openNodesList.empty() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d",
nodeLimitReached,whileLoopCount,unitFactionIndex,pathFound, maxNodeCount);
if(curFrameIndex >= 0) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
pathFound = false;
break;
}
node = minHeuristicFastLookup(faction);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d node->pos = %s finalPos = %s node->exploredCell = %d",
nodeLimitReached,whileLoopCount,unitFactionIndex,pathFound, maxNodeCount,node->pos.getString().c_str(),finalPos.getString().c_str(),node->exploredCell);
if(curFrameIndex >= 0) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
if(node->pos == finalPos || node->exploredCell == false) {
pathFound = true;
break;
@ -321,8 +397,30 @@ private:
int failureCount = 0;
int cellCount = 0;
int tryDirection = faction.random.randRange(0, 3);
if(tryDirection == 3) {
// if(Thread::isCurrentThreadMainThread() == false) {
// throw megaglest_runtime_error("#1 Invalid access to FactionState random from outside main thread current id = " +
// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
// }
//int tryDirection = 1;
//int tryDirection = faction.random.IRandomX(1, 4);
int tryDirection = faction.random.randRange(1, 4);
//int tryDirection = unit->getRandom(true)->randRange(1, 4);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In doAStarPathSearch() tryDirection %d",tryDirection);
if(curFrameIndex >= 0) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
if(tryDirection == 4) {
for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
@ -332,7 +430,7 @@ private:
}
}
}
else if(tryDirection == 2) {
else if(tryDirection == 3) {
for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
for(int j = 1;j >= -1 && nodeLimitReached == false;--j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
@ -342,7 +440,7 @@ private:
}
}
}
else if(tryDirection == 1) {
else if(tryDirection == 2) {
for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
@ -363,6 +461,21 @@ private:
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d",
nodeLimitReached,whileLoopCount,unitFactionIndex,pathFound, maxNodeCount);
if(curFrameIndex >= 0) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
}
};

View File

@ -4129,6 +4129,7 @@ int glestMain(int argc, char** argv) {
#endif
Thread::setMainThreadId();
// printf("START ALLOC char 200\n");
//char *ptr = new char[200];
// printf("END ALLOC char 200\n");

View File

@ -1542,7 +1542,13 @@ Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceT
// First look immediately around the unit's position
// 0 means start looking leftbottom to top right
// if(Thread::isCurrentThreadMainThread() == false) {
// throw megaglest_runtime_error("#1 Invalid access to Faction random from outside main thread current id = " +
// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
// }
int tryRadius = random.randRange(0,1);
//int tryRadius = unit->getRandom(true)->randRange(0,1);
//int tryRadius = 0;
if(tryRadius == 0) {
for(int j = -harvestDistance; j <= harvestDistance && foundCloseResource == false; ++j) {
for(int k = -harvestDistance; k <= harvestDistance && foundCloseResource == false; ++k) {
@ -1665,6 +1671,10 @@ Vec2i Faction::getClosestResourceTypeTargetFromCache(const Vec2i &pos, const Res
bool foundCloseResource = false;
// 0 means start looking leftbottom to top right
// if(Thread::isCurrentThreadMainThread() == false) {
// throw megaglest_runtime_error("#2 Invalid access to Faction random from outside main thread current id = " +
// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
// }
int tryRadius = random.randRange(0,1);
if(tryRadius == 0) {
// First look immediately around the given position

View File

@ -120,6 +120,11 @@ void UnitPathBasic::add(const Vec2i &path) {
}
}
if(Thread::isCurrentThreadMainThread() == false) {
throw megaglest_runtime_error("Invalid access to UnitPathBasic add from outside main thread current id = " +
intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
}
pathQueue.push_back(path);
}
@ -129,6 +134,11 @@ Vec2i UnitPathBasic::pop(bool removeFrontPos) {
}
Vec2i p= pathQueue.front();
if(removeFrontPos == true) {
if(Thread::isCurrentThreadMainThread() == false) {
throw megaglest_runtime_error("Invalid access to UnitPathBasic delete from outside main thread current id = " +
intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
}
pathQueue.erase(pathQueue.begin());
}
return p;
@ -1371,7 +1381,15 @@ void Unit::setTarget(const Unit *unit){
targetRef= unit;
}
void Unit::setPos(const Vec2i &pos, bool clearPathFinder) {
RandomGen* Unit::getRandom(bool threadAccessAllowed) {
if(threadAccessAllowed == false && Thread::isCurrentThreadMainThread() == false) {
throw megaglest_runtime_error("Invalid access to unit random from outside main thread current id = " +
intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
}
return &random;
}
void Unit::setPos(const Vec2i &pos, bool clearPathFinder, bool threaded) {
if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) {
throw megaglest_runtime_error("#3 Invalid path position = " + pos.getString());
}
@ -1379,6 +1397,13 @@ void Unit::setPos(const Vec2i &pos, bool clearPathFinder) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId);
if(threaded) {
logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
}
else {
logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
}
if(clearPathFinder == true && this->unitPath != NULL) {
this->unitPath->clear();
}
@ -1394,7 +1419,12 @@ void Unit::setPos(const Vec2i &pos, bool clearPathFinder) {
refreshPos();
logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
if(threaded) {
logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
}
else {
logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
}
}
void Unit::refreshPos(bool forceRefresh) {
@ -1452,7 +1482,7 @@ void Unit::calculateFogOfWarRadius(bool forceRefresh) {
}
}
void Unit::setTargetPos(const Vec2i &targetPos) {
void Unit::setTargetPos(const Vec2i &targetPos, bool threaded) {
if(map->isInside(targetPos) == false || map->isInsideSurface(map->toSurfCoords(targetPos)) == false) {
throw megaglest_runtime_error("#4 Invalid path position = " + targetPos.getString());
@ -1474,7 +1504,12 @@ void Unit::setTargetPos(const Vec2i &targetPos) {
this->targetPos= targetPos;
map->clampPos(this->targetPos);
logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
if(threaded) {
logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
}
else {
logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
}
}
void Unit::addAttackParticleSystem(ParticleSystem *ps) {
@ -3608,7 +3643,7 @@ void Unit::morphAttackBoosts(Unit *unit) {
}
}
bool Unit::morph(const MorphCommandType *mct) {
bool Unit::morph(const MorphCommandType *mct, int frameIndex) {
if(mct == NULL) {
char szBuf[8096]="";
@ -3670,7 +3705,7 @@ bool Unit::morph(const MorphCommandType *mct) {
Field original_field = this->currField;
this->currField=morphUnitField;
computeTotalUpgrade();
map->putUnitCells(this, this->pos);
map->putUnitCells(this, this->pos, false, frameIndex < 0);
this->faction->applyDiscount(morphUnitType, mct->getDiscount());
// add new storage
@ -4445,7 +4480,7 @@ void Unit::exploreCells(bool forceRefresh) {
}
else {
// Try the world exploration scan or possible cache
cacheExploredCells = game->getWorld()->exploreCells(newPos, sightRange, teamIndex);
cacheExploredCells = game->getWorld()->exploreCells(newPos, sightRange, teamIndex, this);
// Cache the result for this unit
cacheExploredCellsKey.first = newPos;
@ -4464,7 +4499,7 @@ void Unit::logSynchDataCommon(string file,int line,string source,bool threadedMo
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,
"FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, progress [" MG_I64_SPECIFIER "], progress2 [%d]\nUnit Path [%s]\n",
"FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, progress [" MG_I64_SPECIFIER "], progress2 [%d] random [%d]\nUnit Path [%s]\n",
getFrameCount(),
id,
getFullName(false).c_str(),
@ -4480,6 +4515,7 @@ void Unit::logSynchDataCommon(string file,int line,string source,bool threadedMo
// rotation,
progress,
progress2,
random.getLastNumber(),
(unitPath != NULL ? unitPath->toString().c_str() : "NULL"));
if( lastSynchDataString != string(szBuf) ||

View File

@ -626,9 +626,9 @@ public:
inline void setLoadCount(int loadCount) {this->loadCount= loadCount;}
inline void setLoadType(const ResourceType *loadType) {this->loadType= loadType;}
inline void setProgress2(int progress2) {this->progress2= progress2;}
void setPos(const Vec2i &pos,bool clearPathFinder=false);
void setPos(const Vec2i &pos,bool clearPathFinder=false, bool threaded=false);
void refreshPos(bool forceRefresh=false);
void setTargetPos(const Vec2i &targetPos);
void setTargetPos(const Vec2i &targetPos, bool threaded=false);
void setTarget(const Unit *unit);
//void setTargetVec(const Vec3f &targetVec);
void setMeetingPos(const Vec2i &meetingPos);
@ -683,7 +683,7 @@ public:
int update2();
bool update();
void tick();
RandomGen* getRandom() { return &random; }
RandomGen* getRandom(bool threadAccessAllowed=false);
bool applyAttackBoost(const AttackBoost *boost, const Unit *source);
void deapplyAttackBoost(const AttackBoost *boost, const Unit *source);
@ -691,7 +691,7 @@ public:
void applyUpgrade(const UpgradeType *upgradeType);
void computeTotalUpgrade();
void incKills(int team);
bool morph(const MorphCommandType *mct);
bool morph(const MorphCommandType *mct, int frameIndex);
std::pair<CommandResult,string> checkCommand(Command *command) const;
void applyCommand(Command *command);

View File

@ -132,9 +132,9 @@ SurfaceCell::SurfaceCell() {
nearSubmerged = false;
cellChangedFromOriginalMapLoad = false;
for(int i = 0; i < GameConstants::maxPlayers + GameConstants::specialFactions; ++i) {
visible[i] = false;
explored[i] = false;
for(int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) {
setVisible(index,false);
setExplored(index,false);
}
}
@ -190,6 +190,45 @@ void SurfaceCell::setVisible(int teamIndex, bool visible) {
}
this->visible[teamIndex]= visible;
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In setVisible() teamIndex %d visible %d",teamIndex,visible);
// if(frameIndex < 0) {
// unit->logSynchData(__FILE__,__LINE__,szBuf);
// }
// else {
// unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
// }
if(Thread::isCurrentThreadMainThread()) {
//unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,szBuf);
}
else {
//unit->logSynchData(__FILE__,__LINE__,szBuf);
printf("%s",szBuf);
}
}
}
string SurfaceCell::isVisibleString() const {
string result = "isVisibleList = ";
for(int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) {
result += string(visible[index] ? "true" : "false");
}
return result;
}
string SurfaceCell::isExploredString() const {
string result = "isExploredList = ";
for(int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) {
result += string(explored[index] ? "true" : "false");
}
return result;
}
void SurfaceCell::saveGame(XmlNode *rootNode,int index) const {
@ -1309,12 +1348,12 @@ bool Map::isInUnitTypeCells(const UnitType *ut, const Vec2i &pos,
}
//put a units into the cells
void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) {
void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill, bool threaded) {
assert(unit != NULL);
if(unit == NULL) {
throw megaglest_runtime_error("ut == NULL");
}
putUnitCellsPrivate(unit, pos, unit->getType(), false);
putUnitCellsPrivate(unit, pos, unit->getType(), false, threaded);
// block space for morphing units
if(ignoreSkill==false &&
@ -1323,13 +1362,13 @@ void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) {
Command *command= unit->getCurrCommand();
if(command != NULL && command->getCommandType()->commandTypeClass == ccMorph){
const MorphCommandType *mct= static_cast<const MorphCommandType*>(command->getCommandType());
putUnitCellsPrivate(unit, pos, mct->getMorphUnit(),true);
putUnitCellsPrivate(unit, pos, mct->getMorphUnit(),true, threaded);
unit->setMorphFieldsBlocked(true);
}
}
}
void Map::putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph) {
void Map::putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph, bool threaded) {
assert(unit != NULL);
if(unit == NULL) {
throw megaglest_runtime_error("ut == NULL");
@ -1409,7 +1448,7 @@ void Map::putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut,
}
}
if(canPutInCell == true) {
unit->setPos(pos);
unit->setPos(pos, false, threaded);
}
}

View File

@ -158,6 +158,8 @@ public:
inline bool isVisible(int teamIndex) const {return visible[teamIndex];}
inline bool isExplored(int teamIndex) const {return explored[teamIndex];}
string isVisibleString() const;
string isExploredString() const;
//set
inline void setVertex(const Vec3f &vertex) {this->vertex= vertex;}
@ -335,7 +337,7 @@ public:
//unit placement
bool aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map<Vec2i, std::map<Vec2i, std::map<int, std::map<int, std::map<Field,bool> > > > > *lookupCache=NULL) const;
bool canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2,std::map<Vec2i, std::map<Vec2i, std::map<int, std::map<Field,bool> > > > *lookupCache=NULL) const;
void putUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false);
void putUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false, bool threaded = false);
void clearUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false);
Vec2i computeRefPos(const Selection *selection) const;
@ -392,11 +394,23 @@ public:
}
//checks if a unit can move from between 2 cells using only visible cells (for pathfinding)
inline bool aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const {
inline bool aproxCanMoveSoon(Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const {
if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false ||
isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() return false");
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
return false;
}
@ -410,14 +424,93 @@ public:
//single cell units
if(size == 1) {
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),pos2, field, teamIndex) == false) {
bool tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),pos2, field, teamIndex);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false")));
const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos2));
if(sc->isVisible(teamIndex)) {
bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), pos2, field);
extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false")));
}
else if(sc->isExplored(teamIndex)) {
bool testCond = field==fLand? sc->isFree() && !getDeepSubmerged(getCell(pos2)): true;
extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false")));
}
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() pos2 = %s extraInfo = %s %s %s",pos2.getString().c_str(),extraInfo.c_str(),sc->isVisibleString().c_str(),sc->isExploredString().c_str());
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
if(tryPosResult == false) {
return false;
}
if(pos1.x != pos2.x && pos1.y != pos2.y) {
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),Vec2i(pos1.x, pos2.y), field, teamIndex) == false) {
Vec2i tryPos = Vec2i(pos1.x, pos2.y);
bool tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),tryPos, field, teamIndex);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false")));
const SurfaceCell *sc= getSurfaceCell(toSurfCoords(tryPos));
if(sc->isVisible(teamIndex)) {
bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field);
extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false")));
}
else if(sc->isExplored(teamIndex)) {
bool testCond = field==fLand? sc->isFree() && !getDeepSubmerged(getCell(tryPos)): true;
extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false")));
}
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() extraInfo = %s",extraInfo.c_str());
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
if(tryPosResult == false) {
return false;
}
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),Vec2i(pos2.x, pos1.y), field, teamIndex) == false) {
tryPos = Vec2i(pos2.x, pos1.y);
tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),tryPos, field, teamIndex);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false")));
const SurfaceCell *sc= getSurfaceCell(toSurfCoords(tryPos));
if(sc->isVisible(teamIndex)) {
bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field);
extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false")));
}
else if(sc->isExplored(teamIndex)) {
bool testCond = field==fLand? sc->isFree() && !getDeepSubmerged(getCell(tryPos)): true;
extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false")));
}
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() extraInfo = %s",extraInfo.c_str());
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
if(tryPosResult == false) {
return false;
}
}
@ -432,6 +525,18 @@ public:
}
if(unit == NULL || isBadHarvestPos == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() return false");
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
return false;
}
@ -446,11 +551,35 @@ public:
if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) {
if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) {
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),cellPos, field, teamIndex) == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() return false");
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
return false;
}
}
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() return false");
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
return false;
}
}
@ -466,6 +595,18 @@ public:
}
if(isBadHarvestPos == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In aproxCanMoveSoon() return false");
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
return false;
}
@ -483,7 +624,7 @@ private:
void smoothSurface(Tileset *tileset);
void computeNearSubmerged();
void computeCellColors();
void putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph);
void putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph, bool threaded);
};

View File

@ -205,8 +205,8 @@ void Minimap::resetFowTex() {
for(int indexPixelHeight = 0;
indexPixelHeight < fowTex->getPixmap()->getH();
++indexPixelHeight){
if ((fogOfWar == false && overridefogOfWarValue == false) &&
(gameSettings->getFlagTypes1() & ft1_show_map_resources) != ft1_show_map_resources) {
if ((fogOfWar == false && overridefogOfWarValue == false)) {
//(gameSettings->getFlagTypes1() & ft1_show_map_resources) != ft1_show_map_resources) {
//printf("Line: %d\n",__LINE__);
float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight);
@ -219,7 +219,7 @@ void Minimap::resetFowTex() {
}
}
else if((fogOfWar && overridefogOfWarValue) ||
(gameSettings->getFlagTypes1() & ft1_show_map_resources) != ft1_show_map_resources) {
(gameSettings->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources) {
//printf("Line: %d\n",__LINE__);
float p0= fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight);

View File

@ -282,7 +282,7 @@ bool UnitUpdater::updateUnit(Unit *unit) {
//move unit in cells
if(unit->getCurrSkill()->getClass() == scMove) {
world->moveUnitCells(unit);
world->moveUnitCells(unit, true);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after world->moveUnitCells()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
@ -750,6 +750,13 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
}
else {
//if unit arrives destPos order has ended
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"#1 [updateAttack] tsValue = %d",tsValue);
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
switch (tsValue) {
case tsMoving:
unit->setCurrSkill(act->getMoveSkillType());
@ -804,9 +811,10 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
}
*/
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"[updateAttack]");
snprintf(szBuf,8096,"#2 [updateAttack] tsValue = %d",tsValue);
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
@ -1254,7 +1262,7 @@ void UnitUpdater::updateHarvestEmergencyReturn(Unit *unit, int frameIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
char szBuf[8096]="";
snprintf(szBuf,8096,"[updateHarvestEmergencyReturn]");
unit->logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
//printf("\n#1 updateHarvestEmergencyReturn\n");
@ -2304,7 +2312,7 @@ void UnitUpdater::updateProduce(Unit *unit, int frameIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
//place unit creates the unit
if(!world->placeUnit(unit->getCenteredPos(), 10, produced)) {
if(!world->placeUnit(unit->getCenteredPos(), 10, produced, false, frameIndex < 0)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d]\n",__FILE__,__FUNCTION__,__LINE__,produced->getId());
delete produced;
}
@ -2437,7 +2445,7 @@ void UnitUpdater::updateMorph(Unit *unit, int frameIndex) {
if(map->canMorph(unit->getPos(),unit,mct->getMorphUnit())){
unit->setCurrSkill(mct->getMorphSkillType());
// block space for morphing units ( block space before and after morph ! )
map->putUnitCells(unit, unit->getPos());
map->putUnitCells(unit, unit->getPos(), false, frameIndex < 0);
}
else{
if(unit->getFactionIndex()==world->getThisFactionIndex()){
@ -2460,7 +2468,7 @@ void UnitUpdater::updateMorph(Unit *unit, int frameIndex) {
}
//finish the command
if(unit->morph(mct)){
if(unit->morph(mct, frameIndex)){
unit->finishCommand();
if(gui->isSelected(unit)){
gui->onSelectionChanged();
@ -2966,7 +2974,8 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
unit->getRandom()->addLastCaller(randomInfoData);
if( attackingEnemySeen!=NULL && unit->getRandom()->randRange(0,2,extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__)) != 2 ) {
if( attackingEnemySeen != NULL && unit->getRandom()->randRange(0,2,extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__)) != 2 ) {
//if( attackingEnemySeen != NULL) {
*rangedPtr = attackingEnemySeen;
enemySeen = attackingEnemySeen;
//printf("Da hat er wen gefunden:%s\n",enemySeen->getType()->getName(false).c_str());

View File

@ -39,6 +39,7 @@ namespace Glest{ namespace Game{
// This limit is to keep RAM use under control while offering better performance.
int MaxExploredCellsLookupItemCache = 9500;
//int MaxExploredCellsLookupItemCache = 0;
time_t ExploredCellsLookupItem::lastDebug = 0;
// ===================== PUBLIC ========================
@ -1127,7 +1128,7 @@ const UnitType * World::findUnitTypeByName(const string factionName, const strin
}
//looks for a place for a unit around a start location, returns true if succeded
bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated) {
bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated, bool threaded) {
if(unit == NULL) {
throw megaglest_runtime_error("unit == NULL");
}
@ -1149,7 +1150,7 @@ bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spacia
}
if(freeSpace) {
unit->setPos(pos);
unit->setPos(pos, false, threaded);
Vec2i meetingPos = pos-Vec2i(1);
unit->setMeetingPos(meetingPos);
return true;
@ -1161,7 +1162,7 @@ bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spacia
}
//clears a unit old position from map and places new position
void World::moveUnitCells(Unit *unit) {
void World::moveUnitCells(Unit *unit, bool threaded) {
if(unit == NULL) {
throw megaglest_runtime_error("unit == NULL");
}
@ -1174,7 +1175,7 @@ void World::moveUnitCells(Unit *unit) {
// from the old one
if(newPos != unit->getPos()) {
map.clearUnitCells(unit, unit->getPos());
map.putUnitCells(unit, newPos);
map.putUnitCells(unit, newPos, false, threaded);
}
// Add resources close by to the faction's cache
unit->getFaction()->addCloseResourceTargetToCache(newPos);
@ -1182,6 +1183,12 @@ void World::moveUnitCells(Unit *unit) {
//water splash
if(tileset.getWaterEffects() && unit->getCurrField() == fLand) {
if(map.getSubmerged(map.getCell(unit->getLastPos()))) {
if(Thread::isCurrentThreadMainThread() == false) {
throw megaglest_runtime_error("#1 Invalid access to World random from outside main thread current id = " +
intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
}
int unitSize= unit->getType()->getSize();
for(int i = 0; i < 3; ++i) {
waterEffects.addWaterSplash(
@ -1808,7 +1815,7 @@ void World::setUnitPosition(int unitId, Vec2i pos) {
throw megaglest_runtime_error("Can not find unit to set position unitId = " + intToStr(unitId),true);
}
unit->setTargetPos(pos);
this->moveUnitCells(unit);
this->moveUnitCells(unit, false);
}
void World::addCellMarker(Vec2i pos, int factionIndex, const string &note, const string textureFile) {
@ -1960,10 +1967,20 @@ void World::initCells(bool fogOfWar) {
sc->setExplored(k, (game->getGameSettings()->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources);
sc->setVisible(k, !fogOfWar);
}
for (int k = GameConstants::maxPlayers; k < GameConstants::maxPlayers + GameConstants::specialFactions; k++) {
sc->setExplored(k, true);
sc->setVisible(k, true);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In initCells() x = %d y = %d %s %s",i,j,sc->isVisibleString().c_str(),sc->isExploredString().c_str());
if(Thread::isCurrentThreadMainThread()) {
//unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,szBuf);
}
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -2333,7 +2350,7 @@ void World::exploreCells(int teamIndex, ExploredCellsLookupItem &exploredCellsCa
// ==================== exploration ====================
ExploredCellsLookupItem World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex) {
ExploredCellsLookupItem World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex, Unit *unit) {
// cache lookup of previously calculated cells + sight range
if(MaxExploredCellsLookupItemCache > 0) {
if(difftime(time(NULL),ExploredCellsLookupItem::lastDebug) >= 10) {
@ -2413,13 +2430,28 @@ ExploredCellsLookupItem World::exploreCells(const Vec2i &newPos, int sightRange,
//explore
float posLength = currRelPos.length();
if(posLength < surfSightRange + indirectSightRange + 1) {
bool updateExplored = (posLength < surfSightRange + indirectSightRange + 1);
bool updateVisible = (posLength < surfSightRange);
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In exploreCells() currRelPos = %s currPos = %s posLength = %f updateExplored = %d updateVisible = %d sightRange = %d teamIndex = %d",
currRelPos.getString().c_str(), currPos.getString().c_str(),posLength,updateExplored, updateVisible, sightRange, teamIndex);
if(Thread::isCurrentThreadMainThread() == false) {
unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf);
}
else {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
}
if(updateExplored) {
sc->setExplored(teamIndex, true);
exploredCellsCache.exploredCellList.push_back(sc);
}
//visible
if(posLength < surfSightRange) {
if(updateVisible) {
sc->setVisible(teamIndex, true);
exploredCellsCache.visibleCellList.push_back(sc);
}
@ -2509,7 +2541,7 @@ void World::computeFow() {
// Once we have calculated fog of war texture alpha, they are cached so we
// restore the default texture in one shot for speed
if(cacheFowAlphaTexture == true) {
if(fogOfWar && cacheFowAlphaTexture == true) {
if(cacheFowAlphaTextureFogOfWarValue != fogOfWar) {
cacheFowAlphaTexture = false;
}
@ -2521,7 +2553,18 @@ void World::computeFow() {
for(int indexFaction = 0;
indexFaction < GameConstants::maxPlayers + GameConstants::specialFactions;
++indexFaction) {
if(fogOfWar || indexFaction != thisTeamIndex) {
// If fog of war enabled set cell visible to false and later set those close to units to true
if(fogOfWar) {
for(int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) {
for(int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) {
// set all cells to not visible
map.getSurfaceCell(indexSurfaceW, indexSurfaceH)->setVisible(indexFaction, false);
}
}
}
if(!fogOfWar || (indexFaction != thisTeamIndex)) {
bool showWorldForFaction = showWorldForPlayer(indexFaction);
if(showWorldForFaction == true) {
resetFowAlphaFactionCount++;
@ -2529,13 +2572,10 @@ void World::computeFow() {
for(int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) {
for(int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) {
// set all cells to not visible
map.getSurfaceCell(indexSurfaceW, indexSurfaceH)->setVisible(indexFaction, false);
// reset fog of ware texture alpha values
if(cacheFowAlphaTexture == false &&
if(!fogOfWar || (cacheFowAlphaTexture == false &&
showWorldForFaction == true &&
resetFowAlphaFactionCount <= 1) {
resetFowAlphaFactionCount <= 1)) {
const Vec2i surfPos(indexSurfaceW,indexSurfaceH);
//compute max alpha
@ -2558,12 +2598,13 @@ void World::computeFow() {
}
}
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,getFrameCount());
}
// Once we have calculated fog of war texture alpha, will we cache it so that we
// can restore it later
if(cacheFowAlphaTexture == false && resetFowAlphaFactionCount > 0) {
if(fogOfWar && cacheFowAlphaTexture == false && resetFowAlphaFactionCount > 0) {
cacheFowAlphaTexture = true;
cacheFowAlphaTextureFogOfWarValue = fogOfWar;
minimap.copyFowTexAlphaSurface();

View File

@ -215,8 +215,8 @@ public:
Unit* findUnitById(int id) const;
const UnitType* findUnitTypeById(const FactionType* factionType, int id);
const UnitType *findUnitTypeByName(const string factionName, const string unitTypeName);
bool placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated= false);
void moveUnitCells(Unit *unit);
bool placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated= false, bool threaded=false);
void moveUnitCells(Unit *unit, bool threaded);
bool toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const;
bool toRenderUnit(const Unit *unit) const;
@ -297,7 +297,7 @@ public:
}
bool canTickWorld() const;
ExploredCellsLookupItem exploreCells(const Vec2i &newPos, int sightRange, int teamIndex);
ExploredCellsLookupItem exploreCells(const Vec2i &newPos, int sightRange, int teamIndex, Unit *unit);
void exploreCells(int teamIndex,ExploredCellsLookupItem &exploredCellsCache);
bool showWorldForPlayer(int factionIndex, bool excludeFogOfWarCheck=false) const;

View File

@ -260,7 +260,6 @@ public:
inline float dist(const Vec2<T> &v) const{
float distance = Vec2<T>(v-*this).length();
distance = truncateDecimal<float>(distance,6);
return distance;
}
@ -270,8 +269,12 @@ public:
}
inline float length() const {
#ifdef USE_STREFLOP
float len = static_cast<float>(streflop::sqrt(static_cast<streflop::Simple>(x*x + y*y)));
#else
float len = static_cast<float>(std::sqrt(static_cast<float>(x*x + y*y)));
len = truncateDecimal<float>(len,6);
#endif
return len;
}
@ -494,13 +497,16 @@ public:
inline float dist(const Vec3<T> &v) const {
float distance = Vec3<T>(v-*this).length();
distance = truncateDecimal<float>(distance,6);
return distance;
}
inline float length() const {
#ifdef USE_STREFLOP
float len = static_cast<float>(streflop::sqrt(static_cast<streflop::Simple>(x*x + y*y + z*z)));
#else
float len = static_cast<float>(std::sqrt(x*x + y*y + z*z));
len = truncateDecimal<float>(len,6);
#endif
return len;
}

View File

@ -79,6 +79,7 @@ private:
static Mutex mutexthreadList;
static vector<Thread *> threadList;
static bool enableVerboseMode;
static unsigned long mainThreadId;
protected:
void addThreadToList();
@ -90,6 +91,11 @@ public:
Thread();
virtual ~Thread();
static unsigned long getCurrentThreadId();
static unsigned long getMainThreadId() { return mainThreadId; }
static void setMainThreadId();
static bool isCurrentThreadMainThread();
static void setEnableVerboseMode(bool value) { enableVerboseMode = value; }
static bool getEnableVerboseMode() { return enableVerboseMode; }

View File

@ -74,6 +74,7 @@ public:
debugNetwork,
debugPerformance,
debugWorldSynch,
debugWorldSynchMax,
debugUnitCommands,
debugPathFinder,
debugLUA,

View File

@ -686,7 +686,7 @@ std::vector<std::string> Socket::getLocalIPAddressList() {
for(int ipIdx = 0; myhostent->h_addr_list[ipIdx] != NULL; ++ipIdx) {
Ip::Inet_NtoA(SockAddrToUint32((struct in_addr *)myhostent->h_addr_list[ipIdx]), myhostaddr);
printf("ipIdx = %d [%s]\n",ipIdx,myhostaddr);
//printf("ipIdx = %d [%s]\n",ipIdx,myhostaddr);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] myhostaddr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,myhostaddr);
if(strlen(myhostaddr) > 0 &&

View File

@ -26,6 +26,7 @@ namespace Shared { namespace Platform {
bool Thread::enableVerboseMode = false;
Mutex Thread::mutexthreadList;
vector<Thread *> Thread::threadList;
unsigned long Thread::mainThreadId = -1;
auto_ptr<Mutex> Mutex::mutexMutexList(new Mutex(CODE_AT_LINE));
vector<Mutex *> Mutex::mutexList;
@ -138,6 +139,16 @@ Thread::Thread() : thread(NULL),
addThreadToList();
}
unsigned long Thread::getCurrentThreadId() {
return SDL_ThreadID();
}
void Thread::setMainThreadId() {
mainThreadId = getCurrentThreadId();
}
bool Thread::isCurrentThreadMainThread() {
return getCurrentThreadId() == mainThreadId;
}
void Thread::addThreadToList() {
MutexSafeWrapper safeMutex(&Thread::mutexthreadList);
Thread::threadList.push_back(this);

View File

@ -31,7 +31,7 @@ const int RandomGen::m= 714025;
const int RandomGen::a= 1366;
const int RandomGen::b= 150889;
RandomGen::RandomGen(){
RandomGen::RandomGen() {
lastNumber= 0;
disableLastCallerTracking = false;
}
@ -77,7 +77,7 @@ int RandomGen::randRange(int min, int max,string lastCaller) {
}
int diff= max-min;
float numerator = static_cast<float>(diff + 1) * static_cast<float>(RandomGen::rand(lastCaller));
float numerator = static_cast<float>(diff + 1) * static_cast<float>(this->rand(lastCaller));
int res= min + static_cast<int>(truncateDecimal<float>(numerator / static_cast<float>(m),6));
if(res < min || res > max) {
char szBuf[8096]="";
@ -94,7 +94,7 @@ float RandomGen::randRange(float min, float max,string lastCaller) {
throw megaglest_runtime_error(szBuf);
}
float rand01 = static_cast<float>(RandomGen::rand(lastCaller)) / (m-1);
float rand01 = static_cast<float>(this->rand(lastCaller)) / (m-1);
float res= min + (max - min) * rand01;
res = truncateDecimal<float>(res,6);