- bugfix when bad values are in map file, game would freeze at game start due to endless loop

This commit is contained in:
Mark Vejvoda 2011-02-25 22:13:11 +00:00
parent 9de151d975
commit bced200dd1
7 changed files with 62 additions and 40 deletions

View File

@ -572,6 +572,8 @@ bool Ai::haveBlockedUnits() {
} }
bool Ai::getAdjacentUnits(std::map<float, std::map<int, const Unit *> > &signalAdjacentUnits, const Unit *unit) { bool Ai::getAdjacentUnits(std::map<float, std::map<int, const Unit *> > &signalAdjacentUnits, const Unit *unit) {
//printf("In getAdjacentUnits...\n");
bool result = false; bool result = false;
Map *map = aiInterface->getMap(); Map *map = aiInterface->getMap();
Vec2i unitPos = unit->getPos(); Vec2i unitPos = unit->getPos();

View File

@ -69,6 +69,8 @@ PathFinder::~PathFinder(){
} }
TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck) { TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck) {
//printf("PathFinder::findPath...\n");
if(map == NULL) { if(map == NULL) {
throw runtime_error("map == NULL"); throw runtime_error("map == NULL");
} }
@ -343,6 +345,8 @@ bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i,
//route a unit using A* algorithm //route a unit using A* algorithm
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout) { TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout) {
//printf("PathFinder::aStar...\n");
Chrono chrono; Chrono chrono;
chrono.start(); chrono.start();

View File

@ -1008,7 +1008,7 @@ void Game::mouseDownLeft(int x, int y) {
int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW())); int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH())); int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
if(map->isInside(xCell, yCell)){ if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
if(gui.isSelectingPos()){ if(gui.isSelectingPos()){
gui.mouseDownLeftGraphics(xCell, yCell, true); gui.mouseDownLeftGraphics(xCell, yCell, true);
} }
@ -1091,7 +1091,7 @@ void Game::mouseDownRight(int x, int y) {
int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW())); int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH())); int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
if(map->isInside(xCell, yCell)){ if(map->isInside(xCell, yCell) && map->isInsideSurface(map->toSurfCoords(Vec2i(xCell,yCell)))) {
gui.mouseDownRightGraphics(xCell, yCell,true); gui.mouseDownRightGraphics(xCell, yCell,true);
} }
} }
@ -1150,7 +1150,7 @@ void Game::mouseDoubleClickLeft(int x, int y) {
const Metrics &metrics= Metrics::getInstance(); const Metrics &metrics= Metrics::getInstance();
//display panel //display panel
if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()){ if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()) {
int xd= x - metrics.getDisplayX(); int xd= x - metrics.getDisplayX();
int yd= y - metrics.getDisplayY(); int yd= y - metrics.getDisplayY();
if(gui.mouseValid(xd, yd)){ if(gui.mouseValid(xd, yd)){

View File

@ -177,7 +177,6 @@ void GameCamera::update(){
} }
Quad2i GameCamera::computeVisibleQuad() const { Quad2i GameCamera::computeVisibleQuad() const {
if(MaxVisibleQuadItemCache != 0) { if(MaxVisibleQuadItemCache != 0) {
std::map<float, std::map<float, std::map<Vec3f, Quad2i> > >::const_iterator iterFind = cacheVisibleQuad.find(fov); std::map<float, std::map<float, std::map<Vec3f, Quad2i> > >::const_iterator iterFind = cacheVisibleQuad.find(fov);
if(iterFind != cacheVisibleQuad.end()) { if(iterFind != cacheVisibleQuad.end()) {
@ -190,7 +189,6 @@ Quad2i GameCamera::computeVisibleQuad() const {
} }
} }
} }
float nearDist = 20.f; float nearDist = 20.f;
float dist = pos.y > 20.f ? pos.y * 1.2f : 20.f; float dist = pos.y > 20.f ? pos.y * 1.2f : 20.f;
float farDist = 90.f * (pos.y > 20.f ? pos.y / 15.f : 1.f); float farDist = 90.f * (pos.y > 20.f ? pos.y / 15.f : 1.f);
@ -215,33 +213,42 @@ Quad2i GameCamera::computeVisibleQuad() const {
Vec2i p3(static_cast<int>(p.x + v2.x * nearDist), static_cast<int>(p.y + v2.y * nearDist)); Vec2i p3(static_cast<int>(p.x + v2.x * nearDist), static_cast<int>(p.y + v2.y * nearDist));
Vec2i p4(static_cast<int>(p.x + v2.x * farDist), static_cast<int>(p.y + v2.y * farDist)); Vec2i p4(static_cast<int>(p.x + v2.x * farDist), static_cast<int>(p.y + v2.y * farDist));
Quad2i result;
if (hAng >= 135 && hAng <= 225) { if (hAng >= 135 && hAng <= 225) {
result = Quad2i(p1, p2, p3, p4);
if(MaxVisibleQuadItemCache != 0 && if(MaxVisibleQuadItemCache != 0 &&
(MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { (MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) {
cacheVisibleQuad[fov][hAng][pos] = Quad2i(p1, p2, p3, p4); cacheVisibleQuad[fov][hAng][pos] = result;
} }
return Quad2i(p1, p2, p3, p4);
} }
if (hAng >= 45 && hAng <= 135) { else if (hAng >= 45 && hAng <= 135) {
result = Quad2i(p3, p1, p4, p2);
if(MaxVisibleQuadItemCache != 0 && if(MaxVisibleQuadItemCache != 0 &&
(MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { (MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) {
cacheVisibleQuad[fov][hAng][pos] = Quad2i(p3, p1, p4, p2); cacheVisibleQuad[fov][hAng][pos] = result;
} }
return Quad2i(p3, p1, p4, p2);
} }
if (hAng >= 225 && hAng <= 315) { else if (hAng >= 225 && hAng <= 315) {
result = Quad2i(p2, p4, p1, p3);
if(MaxVisibleQuadItemCache != 0 && if(MaxVisibleQuadItemCache != 0 &&
(MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { (MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) {
cacheVisibleQuad[fov][hAng][pos] = Quad2i(p2, p4, p1, p3); cacheVisibleQuad[fov][hAng][pos] = result;
}
}
else {
result = Quad2i(p4, p3, p2, p1);
if(MaxVisibleQuadItemCache != 0 &&
(MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) {
cacheVisibleQuad[fov][hAng][pos] = Quad2i(p4, p3, p2, p1);
} }
return Quad2i(p2, p4, p1, p3);
} }
if(MaxVisibleQuadItemCache != 0 && if(result.p[0].x < -1000) {
(MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { int ii = 0;
cacheVisibleQuad[fov][hAng][pos] = Quad2i(p4, p3, p2, p1);
} }
return Quad2i(p4, p3, p2, p1); return result;
} }
void GameCamera::switchState(){ void GameCamera::switchState(){

View File

@ -4756,7 +4756,7 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
quadCache.clearNonVolatileCacheData(); quadCache.clearNonVolatileCacheData();
PosQuadIterator pqi(visibleQuad, Map::cellScale); PosQuadIterator pqi(map,visibleQuad, Map::cellScale);
while(pqi.next()) { while(pqi.next()) {
const Vec2i &pos= pqi.getPos(); const Vec2i &pos= pqi.getPos();
if(map->isInside(pos)) { if(map->isInside(pos)) {
@ -4784,7 +4784,7 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1); const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
Quad2i scaledQuad = visibleQuad / Map::cellScale; Quad2i scaledQuad = visibleQuad / Map::cellScale;
PosQuadIterator pqis(scaledQuad); PosQuadIterator pqis(map,scaledQuad);
while(pqis.next()) { while(pqis.next()) {
const Vec2i &pos= pqis.getPos(); const Vec2i &pos= pqis.getPos();
if(mapBounds.isInside(pos)) { if(mapBounds.isInside(pos)) {

View File

@ -211,10 +211,10 @@ Checksum Map::load(const string &path, TechTree *techTree, Tileset *tileset) {
} }
else if(header.version==2){ else if(header.version==2){
//desc = header.version2.short_desc; //desc = header.version2.short_desc;
if(header.version2.cliffLevel>0){ if(header.version2.cliffLevel > 0 && header.version2.cliffLevel < 5000){
cliffLevel=static_cast<float>((header.version2.cliffLevel-0.01f)/(heightFactor)); cliffLevel=static_cast<float>((header.version2.cliffLevel-0.01f)/(heightFactor));
} }
if(header.version2.cameraHeight>0) if(header.version2.cameraHeight > 0 && header.version2.cameraHeight < 5000)
{ {
cameraHeight = header.version2.cameraHeight; cameraHeight = header.version2.cameraHeight;
} }
@ -327,7 +327,8 @@ bool Map::isInsideSurface(const Vec2i &sPos) const {
bool Map::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, int size, Unit *unit, bool fallbackToPeersHarvestingSameResource) const { bool Map::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, int size, Unit *unit, bool fallbackToPeersHarvestingSameResource) const {
for(int i = -1; i <= size; ++i) { for(int i = -1; i <= size; ++i) {
for(int j = -1; j <= size; ++j) { for(int j = -1; j <= size; ++j) {
if(isInside(pos.x + i, pos.y + j)) { Vec2i resPos = Vec2i(pos.x + i, pos.y + j);
if(isInside(resPos) && isInsideSurface(toSurfCoords(resPos))) {
Resource *r= getSurfaceCell(toSurfCoords(Vec2i(pos.x + i, pos.y + j)))->getResource(); Resource *r= getSurfaceCell(toSurfCoords(Vec2i(pos.x + i, pos.y + j)))->getResource();
if(r != NULL) { if(r != NULL) {
if(r->getType() == rt) { if(r->getType() == rt) {
@ -375,7 +376,7 @@ bool Map::isResourceNear(const Vec2i &pos, int size, const ResourceType *rt, Vec
Util::PerimeterIterator iter(p1, p2); Util::PerimeterIterator iter(p1, p2);
while (iter.more()) { while (iter.more()) {
Vec2i cur = iter.next(); Vec2i cur = iter.next();
if (isInside(cur)) { if (isInside(cur) && isInsideSurface(toSurfCoords(cur))) {
Resource *r = getSurfaceCell(toSurfCoords(cur))->getResource(); Resource *r = getSurfaceCell(toSurfCoords(cur))->getResource();
if (r && r->getType() == rt) { if (r && r->getType() == rt) {
resourcePos = cur; resourcePos = cur;
@ -537,7 +538,7 @@ bool Map::canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::m
for(int i=pos2.x; i<pos2.x+size; ++i) { for(int i=pos2.x; i<pos2.x+size; ++i) {
for(int j=pos2.y; j<pos2.y+size; ++j) { for(int j=pos2.y; j<pos2.y+size; ++j) {
if(isInside(i, j)) { if(isInside(i, j) && isInsideSurface(toSurfCoords(Vec2i(i,j)))) {
if(getCell(i, j)->getUnit(field) != unit) { if(getCell(i, j)->getUnit(field) != unit) {
if(isFreeCell(Vec2i(i, j), field) == false) { if(isFreeCell(Vec2i(i, j), field) == false) {
if(lookupCache != NULL) { if(lookupCache != NULL) {
@ -823,7 +824,7 @@ bool Map::isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos,
for(int i=-1; i <= ut->getSize(); ++i){ for(int i=-1; i <= ut->getSize(); ++i){
for(int j = -1; j <= ut->getSize(); ++j) { for(int j = -1; j <= ut->getSize(); ++j) {
Vec2i currPos = pos + Vec2i(i, j); Vec2i currPos = pos + Vec2i(i, j);
if(isInside(currPos) == true) { if(isInside(currPos) == true && isInsideSurface(toSurfCoords(currPos)) == true) {
//Cell *unitCell = getCell(currPos); //Cell *unitCell = getCell(currPos);
//if(unitCell == testCell) { //if(unitCell == testCell) {
if(isNextTo(testPos,currPos) == true) { if(isNextTo(testPos,currPos) == true) {
@ -992,7 +993,7 @@ bool Map::isNextTo(const Vec2i &pos, const Unit *unit) const {
for(int i=-1; i<=1; ++i) { for(int i=-1; i<=1; ++i) {
for(int j=-1; j<=1; ++j) { for(int j=-1; j<=1; ++j) {
if(isInside(pos.x+i, pos.y+j)) { if(isInside(pos.x+i, pos.y+j) && isInsideSurface(toSurfCoords(Vec2i(pos.x+i, pos.y+j)))) {
if(getCell(pos.x+i, pos.y+j)->getUnit(fLand) == unit) { if(getCell(pos.x+i, pos.y+j)->getUnit(fLand) == unit) {
return true; return true;
} }
@ -1010,7 +1011,7 @@ bool Map::isNextTo(const Vec2i &pos, const Vec2i &nextToPos) const {
for(int i=-1; i<=1; ++i) { for(int i=-1; i<=1; ++i) {
for(int j=-1; j<=1; ++j) { for(int j=-1; j<=1; ++j) {
if(isInside(pos.x+i, pos.y+j)) { if(isInside(pos.x+i, pos.y+j) && isInsideSurface(toSurfCoords(Vec2i(pos.x+i, pos.y+j)))) {
if(getCell(pos.x+i, pos.y+j) == getCell(nextToPos.x,nextToPos.y)) { if(getCell(pos.x+i, pos.y+j) == getCell(nextToPos.x,nextToPos.y)) {
return true; return true;
} }
@ -1197,7 +1198,7 @@ void Map::computeNearSubmerged(){
for(int k=-1; k<=2; ++k){ for(int k=-1; k<=2; ++k){
for(int l=-1; l<=2; ++l){ for(int l=-1; l<=2; ++l){
Vec2i pos= Vec2i(i+k, j+l); Vec2i pos= Vec2i(i+k, j+l);
if(isInsideSurface(pos)){ if(isInsideSurface(pos) && isInsideSurface(toSurfCoords(pos))) {
if(getSubmerged(getSurfaceCell(pos))) if(getSubmerged(getSurfaceCell(pos)))
anySubmerged= true; anySubmerged= true;
} }
@ -1274,9 +1275,9 @@ bool PosCircularIterator::next(){
return false; return false;
} }
#ifdef USE_STREFLOP #ifdef USE_STREFLOP
while(streflop::floor(pos.dist(center)) >= (radius+1) || !map->isInside(pos)); while(streflop::floor(pos.dist(center)) >= (radius+1) || !map->isInside(pos) || !map->isInsideSurface(map->toSurfCoords(pos)) );
#else #else
while(floor(pos.dist(center)) >= (radius+1) || !map->isInside(pos)); while(floor(pos.dist(center)) >= (radius+1) || !map->isInside(pos) || !map->isInsideSurface(map->toSurfCoords(pos)) );
#endif #endif
//while(!(pos.dist(center) <= radius && map->isInside(pos))); //while(!(pos.dist(center) <= radius && map->isInside(pos)));
@ -1292,7 +1293,9 @@ const Vec2i &PosCircularIterator::getPos(){
// class PosQuadIterator // class PosQuadIterator
// ===================================================== // =====================================================
PosQuadIterator::PosQuadIterator(const Quad2i &quad, int step){ PosQuadIterator::PosQuadIterator(const Map *map,const Quad2i &quad, int step) {
this->map = map;
this->quad= quad; this->quad= quad;
this->boundingRect= quad.computeBoundingRect(); this->boundingRect= quad.computeBoundingRect();
this->step= step; this->step= step;
@ -1300,25 +1303,29 @@ PosQuadIterator::PosQuadIterator(const Quad2i &quad, int step){
--pos.x; --pos.x;
pos.x= (pos.x/step)*step; pos.x= (pos.x/step)*step;
pos.y= (pos.y/step)*step; pos.y= (pos.y/step)*step;
//map->clampPos(pos);
} }
bool PosQuadIterator::next(){ bool PosQuadIterator::next() {
do{ do {
pos.x+= step; pos.x += step;
if(pos.x > boundingRect.p[1].x){ if(pos.x > boundingRect.p[1].x) {
pos.x= (boundingRect.p[0].x/step)*step; pos.x = (boundingRect.p[0].x / step) * step;
pos.y+= step; pos.y += step;
} }
if(pos.y>boundingRect.p[1].y) if(pos.y > boundingRect.p[1].y) {
return false; return false;
}
//printf("pos [%s] boundingRect.p[0] [%s] boundingRect.p[1] [%s]\n",pos.getString().c_str(),boundingRect.p[0].getString().c_str(),boundingRect.p[1].getString().c_str());
} }
while(!quad.isInside(pos)); while(!quad.isInside(pos));
return true; return true;
} }
void PosQuadIterator::skipX(){ void PosQuadIterator::skipX() {
pos.x+= step; pos.x+= step;
} }

View File

@ -289,8 +289,10 @@ private:
Rect2i boundingRect; Rect2i boundingRect;
Vec2i pos; Vec2i pos;
int step; int step;
const Map *map;
public: public:
PosQuadIterator(const Quad2i &quad, int step=1); PosQuadIterator(const Map *map,const Quad2i &quad, int step=1);
bool next(); bool next();
void skipX(); void skipX();
const Vec2i &getPos(); const Vec2i &getPos();