- 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) {
//printf("In getAdjacentUnits...\n");
bool result = false;
Map *map = aiInterface->getMap();
Vec2i unitPos = unit->getPos();

View File

@ -69,6 +69,8 @@ PathFinder::~PathFinder(){
}
TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck) {
//printf("PathFinder::findPath...\n");
if(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
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout) {
//printf("PathFinder::aStar...\n");
Chrono chrono;
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 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()){
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 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);
}
}
@ -1150,7 +1150,7 @@ void Game::mouseDoubleClickLeft(int x, int y) {
const Metrics &metrics= Metrics::getInstance();
//display panel
if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()){
if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()) {
int xd= x - metrics.getDisplayX();
int yd= y - metrics.getDisplayY();
if(gui.mouseValid(xd, yd)){

View File

@ -177,7 +177,6 @@ void GameCamera::update(){
}
Quad2i GameCamera::computeVisibleQuad() const {
if(MaxVisibleQuadItemCache != 0) {
std::map<float, std::map<float, std::map<Vec3f, Quad2i> > >::const_iterator iterFind = cacheVisibleQuad.find(fov);
if(iterFind != cacheVisibleQuad.end()) {
@ -190,7 +189,6 @@ Quad2i GameCamera::computeVisibleQuad() const {
}
}
}
float nearDist = 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);
@ -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 p4(static_cast<int>(p.x + v2.x * farDist), static_cast<int>(p.y + v2.y * farDist));
Quad2i result;
if (hAng >= 135 && hAng <= 225) {
result = Quad2i(p1, p2, p3, p4);
if(MaxVisibleQuadItemCache != 0 &&
(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 &&
(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 &&
(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 &&
(MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) {
cacheVisibleQuad[fov][hAng][pos] = Quad2i(p4, p3, p2, p1);
if(result.p[0].x < -1000) {
int ii = 0;
}
return Quad2i(p4, p3, p2, p1);
return result;
}
void GameCamera::switchState(){

View File

@ -4756,7 +4756,7 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
quadCache.clearNonVolatileCacheData();
PosQuadIterator pqi(visibleQuad, Map::cellScale);
PosQuadIterator pqi(map,visibleQuad, Map::cellScale);
while(pqi.next()) {
const Vec2i &pos= pqi.getPos();
if(map->isInside(pos)) {
@ -4784,7 +4784,7 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
Quad2i scaledQuad = visibleQuad / Map::cellScale;
PosQuadIterator pqis(scaledQuad);
PosQuadIterator pqis(map,scaledQuad);
while(pqis.next()) {
const Vec2i &pos= pqis.getPos();
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){
//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));
}
if(header.version2.cameraHeight>0)
if(header.version2.cameraHeight > 0 && header.version2.cameraHeight < 5000)
{
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 {
for(int i = -1; i <= size; ++i) {
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();
if(r != NULL) {
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);
while (iter.more()) {
Vec2i cur = iter.next();
if (isInside(cur)) {
if (isInside(cur) && isInsideSurface(toSurfCoords(cur))) {
Resource *r = getSurfaceCell(toSurfCoords(cur))->getResource();
if (r && r->getType() == rt) {
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 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(isFreeCell(Vec2i(i, j), field) == false) {
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 j = -1; j <= ut->getSize(); ++j) {
Vec2i currPos = pos + Vec2i(i, j);
if(isInside(currPos) == true) {
if(isInside(currPos) == true && isInsideSurface(toSurfCoords(currPos)) == true) {
//Cell *unitCell = getCell(currPos);
//if(unitCell == testCell) {
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 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) {
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 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)) {
return true;
}
@ -1197,7 +1198,7 @@ void Map::computeNearSubmerged(){
for(int k=-1; k<=2; ++k){
for(int l=-1; l<=2; ++l){
Vec2i pos= Vec2i(i+k, j+l);
if(isInsideSurface(pos)){
if(isInsideSurface(pos) && isInsideSurface(toSurfCoords(pos))) {
if(getSubmerged(getSurfaceCell(pos)))
anySubmerged= true;
}
@ -1274,9 +1275,9 @@ bool PosCircularIterator::next(){
return false;
}
#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
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
//while(!(pos.dist(center) <= radius && map->isInside(pos)));
@ -1292,7 +1293,9 @@ const Vec2i &PosCircularIterator::getPos(){
// 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->boundingRect= quad.computeBoundingRect();
this->step= step;
@ -1300,25 +1303,29 @@ PosQuadIterator::PosQuadIterator(const Quad2i &quad, int step){
--pos.x;
pos.x= (pos.x/step)*step;
pos.y= (pos.y/step)*step;
//map->clampPos(pos);
}
bool PosQuadIterator::next(){
bool PosQuadIterator::next() {
do{
pos.x+= step;
if(pos.x > boundingRect.p[1].x){
pos.x= (boundingRect.p[0].x/step)*step;
pos.y+= step;
do {
pos.x += step;
if(pos.x > boundingRect.p[1].x) {
pos.x = (boundingRect.p[0].x / step) * step;
pos.y += step;
}
if(pos.y>boundingRect.p[1].y)
if(pos.y > boundingRect.p[1].y) {
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));
return true;
}
void PosQuadIterator::skipX(){
void PosQuadIterator::skipX() {
pos.x+= step;
}

View File

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