Skip to content

Commit

Permalink
Added healing of building on load, fixes issue #44.
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanemagnenat committed Apr 30, 2023
1 parent 8cb7023 commit b8a38e1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
32 changes: 22 additions & 10 deletions src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ bool Game::load(GAGCore::InputStream *stream)
return true;
}

bool Game::checkBuildingsDoNotOverlap() {
bool Game::checkBuildingsDoNotOverlapAndHealMissing() {
std::vector<Uint16> buildings(map.getW()*map.getH(), NOGBID);
for (int ti=0; ti<mapHeader.getNumberOfTeams(); ti++)
{
Expand All @@ -1005,12 +1005,24 @@ bool Game::checkBuildingsDoNotOverlap() {
const auto type = building->type;
const auto w = type->width;
const auto h = type->height;
const auto gid = building->gid;
for (int yi=y; yi<y+h; yi++)
for (int xi=x; xi<x+w; xi++)
{
// check for overlap
const auto index = map.coordToIndex(xi, yi);
checkInvariant(buildings[index]==NOGBID);
buildings[index] = building->gid;
buildings[index] = gid;
// heal missing cells
if (map.getCase(xi, yi).building != gid)
{
std::cerr << "Missing map cell GBID at " << xi << "," << yi
<< " for team " << ti
<< " building " << bi
<< " (" << building->type->type << "), healing!"
<< std::endl;
map.getCase(xi, yi).building = gid;
}
}
}
}
Expand All @@ -1024,7 +1036,7 @@ bool Game::integrity(void)
checkInvariant(teams[i]->integrity());

///Check that buildings do not overlap, as a pre-condition for healing
checkInvariant(checkBuildingsDoNotOverlap());
checkInvariant(checkBuildingsDoNotOverlapAndHealMissing());

///Check that all ID do point to existing objects
for (int y=0; y<map.getH(); y++)
Expand All @@ -1038,24 +1050,24 @@ bool Game::integrity(void)
int bid = Building::GIDtoID(c.building);
const auto building = teams[tid]->myBuildings[bid];
checkInvariant(building);
#define assertBuildingCoord(expr, coordL, coordH) \
#define healBuildingOutsideCoord(expr, coordL, coordH) \
if (!(expr)) { \
std::cerr << "Invalid coordinate " << #coordH << "=" << coordL \
<< " for team " << tid \
<< " building " << bid \
<< " (" << building->type->type << ")" \
<< " with " << #coordH \
<< " span [" << building->pos ## coordH << ":" << buildingEnd ## coordH << "[" \
<< " span [" << building->pos ## coordH << ":" << buildingEnd ## coordH << "[, healing!" \
<< std::endl; \
return false; \
map.getCase(x, y).building = NOGBID; \
}

const auto buildingEndX = building->posX + building->type->width;
assertBuildingCoord(x >= building->posX || x < (buildingEndX & map.wMask), x, X);
assertBuildingCoord(x < buildingEndX, x, X);
healBuildingOutsideCoord(x >= building->posX || x < (buildingEndX & map.wMask), x, X);
healBuildingOutsideCoord(x < buildingEndX, x, X);
const auto buildingEndY = building->posY + building->type->height;
assertBuildingCoord(y >= building->posY || y < (buildingEndY & map.hMask), y, Y);
assertBuildingCoord(y < buildingEndY, y, Y);
healBuildingOutsideCoord(y >= building->posY || y < (buildingEndY & map.hMask), y, Y);
healBuildingOutsideCoord(y < buildingEndY, y, Y);
}
if (c.groundUnit != NOGUID)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Game.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class Game

private:
/// Return whether there is no overlap between any buildings
bool checkBuildingsDoNotOverlap();
bool checkBuildingsDoNotOverlapAndHealMissing();
void drawPointBar(int x, int y, BarOrientation orientation, int maxLength, int actLength, Uint8 r, Uint8 g, Uint8 b, int barWidth=2)
{
drawPointBar(x, y, orientation, maxLength, actLength, 0, r, g, b, r, g, b, barWidth);
Expand Down

0 comments on commit b8a38e1

Please sign in to comment.