/** ** Regenerate forest. ** ** @param pos Map tile pos */ void CMap::RegenerateForestTile(const Vec2i &pos) { Assert(Map.Info.IsPointOnMap(pos)); CMapField &mf = *this->Field(pos); if (mf.getGraphicTile() != this->Tileset->getRemovedTreeTile()) { return; } // Increment each value of no wood. // If grown up, place new wood. // FIXME: a better looking result would be fine // Allow general updates to any tiletype that regrows const unsigned int occupedFlag = (MapFieldWall | MapFieldUnpassable | MapFieldLandUnit | MapFieldBuilding); ++mf.Value; if (mf.Value < ForestRegeneration) { return; } mf.Value = ForestRegeneration; if ((mf.Flags & occupedFlag) || pos.y == 0) { return; } const Vec2i offset(0, -1); CMapField &topMf = *(&mf - this->Info.MapWidth); if (topMf.getGraphicTile() == this->Tileset->getRemovedTreeTile() && topMf.Value >= ForestRegeneration && !(topMf.Flags & occupedFlag)) { DebugPrint("Real place wood\n"); topMf.setTileIndex(*Map.Tileset, Map.Tileset->getTopOneTreeTile(), 0); topMf.setGraphicTile(Map.Tileset->getTopOneTreeTile()); topMf.playerInfo.SeenTile = topMf.getGraphicTile(); topMf.Value = 0; topMf.Flags |= MapFieldForest | MapFieldUnpassable; UI.Minimap.UpdateSeenXY(pos + offset); UI.Minimap.UpdateXY(pos + offset); mf.setTileIndex(*Map.Tileset, Map.Tileset->getBottomOneTreeTile(), 0); mf.setGraphicTile(Map.Tileset->getBottomOneTreeTile()); mf.playerInfo.SeenTile = mf.getGraphicTile(); mf.Value = 0; mf.Flags |= MapFieldForest | MapFieldUnpassable; UI.Minimap.UpdateSeenXY(pos); UI.Minimap.UpdateXY(pos); if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) { MarkSeenTile(mf); } if (Map.Field(pos + offset)->playerInfo.IsTeamVisible(*ThisPlayer)) { MarkSeenTile(topMf); } FixNeighbors(MapFieldForest, 0, pos + offset); FixNeighbors(MapFieldForest, 0, pos); } }
/** ** Remove wood from the map. ** ** @param type TileType to clear ** @param pos Map tile-position. */ void CMap::ClearTile(unsigned short type, const Vec2i &pos) { int removedtile; int flags; unsigned int index = getIndex(pos); CMapField &mf = *this->Field(index); // Select Table to lookup switch (type) { case MapFieldForest: removedtile = this->Tileset.RemovedTree; flags = (MapFieldForest | MapFieldUnpassable); break; case MapFieldRocks: removedtile = this->Tileset.RemovedRock; flags = (MapFieldRocks | MapFieldUnpassable); break; default: removedtile = flags = 0; } mf.Tile = removedtile; mf.Flags &= ~flags; mf.Value = 0; UI.Minimap.UpdateXY(pos); FixNeighbors(type, 0, pos); //maybe isExplored if (IsTileVisible(*ThisPlayer, index) > 0) { UI.Minimap.UpdateSeenXY(pos); MarkSeenTile(pos); } }
/** ** Reveal the entire map. */ void CMap::Reveal() { // Mark every explored tile as visible. 1 turns into 2. Vec2i pos; for (pos.x = 0; pos.x < this->Info.MapWidth; ++pos.x) { for (pos.y = 0; pos.y < this->Info.MapHeight; ++pos.y) { for (int p = 0; p < PlayerMax; ++p) { if (!this->Field(pos)->Visible[p]) { this->Field(pos)->Visible[p] = 1; } } MarkSeenTile(pos); } } // Global seen recount. Simple and effective. for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) { CUnit &unit = **it; // Reveal neutral buildings. Gold mines:) if (unit.Player->Type == PlayerNeutral) { for (int p = 0; p < PlayerMax; ++p) { if (Players[p].Type != PlayerNobody && (!(unit.Seen.ByPlayer & (1 << p)))) { UnitGoesOutOfFog(unit, Players[p]); UnitGoesUnderFog(unit, Players[p]); } } } UnitCountSeen(unit); } }
/** ** Reveal the entire map. */ void CMap::Reveal() { // Mark every explored tile as visible. 1 turns into 2. for (int i = 0; i != this->Info.MapWidth * this->Info.MapHeight; ++i) { CMapField &mf = *this->Field(i); CMapFieldPlayerInfo &playerInfo = mf.playerInfo; for (int p = 0; p < PlayerMax; ++p) { playerInfo.Visible[p] = std::max<unsigned short>(1, playerInfo.Visible[p]); } MarkSeenTile(mf); } // Global seen recount. Simple and effective. for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) { CUnit &unit = **it; // Reveal neutral buildings. Gold mines:) if (unit.Player->Type == PlayerNeutral) { for (int p = 0; p < PlayerMax; ++p) { if (Players[p].Type != PlayerNobody && (!(unit.Seen.ByPlayer & (1 << p)))) { UnitGoesOutOfFog(unit, Players[p]); UnitGoesUnderFog(unit, Players[p]); } } } UnitCountSeen(unit); } }
/** ** Regenerate forest. ** ** @param pos Map tile pos */ void CMap::RegenerateForestTile(const Vec2i &pos) { Assert(Map.Info.IsPointOnMap(pos)); CMapField &mf = *this->Field(pos); if (mf.Tile != this->Tileset.RemovedTree) { return; } // Increment each value of no wood. // If grown up, place new wood. // FIXME: a better looking result would be fine // Allow general updates to any tiletype that regrows const unsigned int occupedFlag = (MapFieldWall | MapFieldUnpassable | MapFieldLandUnit | MapFieldBuilding); ++mf.Value; if (mf.Value < ForestRegeneration) { return; } mf.Value = ForestRegeneration; if ((mf.Flags & occupedFlag) || pos.y == 0) { return; } CMapField &topMf = *(&mf - this->Info.MapWidth); if (topMf.Tile == this->Tileset.RemovedTree && topMf.Value >= ForestRegeneration && !(topMf.Flags & occupedFlag)) { DebugPrint("Real place wood\n"); topMf.Tile = this->Tileset.TopOneTree; topMf.Value = 0; topMf.Flags |= MapFieldForest | MapFieldUnpassable; mf.Tile = this->Tileset.BotOneTree; mf.Value = 0; mf.Flags |= MapFieldForest | MapFieldUnpassable; if (Map.IsFieldVisible(*ThisPlayer, pos)) { MarkSeenTile(pos); } const Vec2i offset(0, -1); if (Map.IsFieldVisible(*ThisPlayer, pos + offset)) { MarkSeenTile(pos); } } }
/// Remove rock from the map. void CMap::ClearRockTile(const Vec2i &pos) { CMapField &mf = *this->Field(pos); mf.setGraphicTile(this->Tileset->getRemovedRockTile()); mf.Flags &= ~(MapFieldRocks | MapFieldUnpassable); mf.Value = 0; UI.Minimap.UpdateXY(pos); FixNeighbors(MapFieldRocks, 0, pos); //maybe isExplored if (mf.playerInfo.IsExplored(*ThisPlayer)) { UI.Minimap.UpdateSeenXY(pos); MarkSeenTile(mf); } }
/** ** Correct the seen wood field, depending on the surrounding. ** ** @param type type fo tile to update ** @param seen 1 if updating seen value, 0 for real ** @param pos Map tile-position. */ void CMap::FixTile(unsigned short type, int seen, const Vec2i &pos) { // Outside of map or no wood. if (!Info.IsPointOnMap(pos)) { return; } unsigned int index = getIndex(pos); CMapField *mf = this->Field(index); if (seen && !Tileset.IsSeenTile(type, mf->SeenTile)) { return; } else if (!seen && !(mf->Flags & type)) { return; } // Select Table to lookup int *lookuptable; int removedtile; int flags; switch (type) { case MapFieldForest: lookuptable = this->Tileset.WoodTable; removedtile = this->Tileset.RemovedTree; flags = (MapFieldForest | MapFieldUnpassable); break; case MapFieldRocks: lookuptable = this->Tileset.RockTable; removedtile = this->Tileset.RemovedRock; flags = (MapFieldRocks | MapFieldUnpassable); break; default: lookuptable = NULL; removedtile = 0; flags = 0; } // // Find out what each tile has with respect to wood, or grass. // int tile = 0; int ttup; int ttdown; int ttleft; int ttright; if (pos.y - 1 < 0) { ttup = 15; //Assign trees in all directions } else { CMapField *new_mf = (mf - this->Info.MapWidth); if (seen) { ttup = this->Tileset.MixedLookupTable[new_mf->SeenTile]; } else { ttup = this->Tileset.MixedLookupTable[new_mf->Tile]; } } if (pos.x + 1 >= this->Info.MapWidth) { ttright = 15; //Assign trees in all directions } else { CMapField *new_mf = (mf + 1); if (seen) { ttright = this->Tileset.MixedLookupTable[new_mf->SeenTile]; } else { ttright = this->Tileset.MixedLookupTable[new_mf->Tile]; } } if (pos.y + 1 >= this->Info.MapHeight) { ttdown = 15; //Assign trees in all directions } else { CMapField *new_mf = (mf + this->Info.MapWidth); if (seen) { ttdown = this->Tileset.MixedLookupTable[new_mf->SeenTile]; } else { ttdown = this->Tileset.MixedLookupTable[new_mf->Tile]; } } if (pos.x - 1 < 0) { ttleft = 15; //Assign trees in all directions } else { CMapField *new_mf = (mf - 1); if (seen) { ttleft = this->Tileset.MixedLookupTable[new_mf->SeenTile]; } else { ttleft = this->Tileset.MixedLookupTable[new_mf->Tile]; } } // // Check each of the corners to ensure it has both connecting // ?**? // *mm* // *mm* // ?**? // * // * type asterixs must match for wood to be present tile += ((ttup & 0x01) && (ttleft & 0x04)) * 8; tile += ((ttup & 0x02) && (ttright & 0x08)) * 4; tile += ((ttright & 0x01) && (ttdown & 0x04)) * 2; tile += ((ttleft & 0x02) && (ttdown & 0x08)) * 1; //Test if we have top tree, or bottom tree, they are special if ((ttdown & 0x10) && 1) { tile |= ((ttleft & 0x06) && 1) * 1; tile |= ((ttright & 0x09) && 1) * 2; } if ((ttup & 0x20) && 1) { tile |= ((ttleft & 0x06) && 1) * 8; tile |= ((ttright & 0x09) && 1) * 4; } tile = lookuptable[tile]; //If tile is -1, then we should check if we are to draw just one tree //Check for tile about, or below or both... if (tile == -1) { tile = 16; tile += ((ttup & 0x01) || (ttup & 0x02)) * 1; tile += ((ttdown & 0x04) || (ttdown & 0x08)) * 2; tile = lookuptable[tile]; } //Update seen tile. if (tile == -1) { // No valid wood remove it. if (seen) { mf->SeenTile = removedtile; this->FixNeighbors(type, seen, pos); } else { mf->Tile = removedtile; mf->Flags &= ~flags; mf->Value = 0; UI.Minimap.UpdateXY(pos); } } else if (seen && this->Tileset.MixedLookupTable[mf->SeenTile] == this->Tileset.MixedLookupTable[tile]) { //Same Type return; } else { if (seen) { mf->SeenTile = tile; } else { mf->Tile = tile; } } //maybe isExplored if (IsTileVisible(*ThisPlayer, index) > 0) { UI.Minimap.UpdateSeenXY(pos); if (!seen) { MarkSeenTile(pos); } } }
/** ** Correct the seen wood field, depending on the surrounding. ** ** @param type type of tile to update ** @param seen 1 if updating seen value, 0 for real ** @param pos Map tile-position. */ void CMap::FixTile(unsigned short type, int seen, const Vec2i &pos) { Assert(type == MapFieldForest || type == MapFieldRocks); // Outside of map or no wood. if (!Info.IsPointOnMap(pos)) { return; } unsigned int index = getIndex(pos); CMapField &mf = *this->Field(index); if (!((type == MapFieldForest && Tileset->isAWoodTile(mf.playerInfo.SeenTile)) || (type == MapFieldRocks && Tileset->isARockTile(mf.playerInfo.SeenTile)))) { if (seen) { return; } } if (!seen && !(mf.getFlag() & type)) { return; } // Select Table to lookup int removedtile; int flags; if (type == MapFieldForest) { removedtile = this->Tileset->getRemovedTreeTile(); flags = (MapFieldForest | MapFieldUnpassable); } else { // (type == MapFieldRocks) removedtile = this->Tileset->getRemovedRockTile(); flags = (MapFieldRocks | MapFieldUnpassable); } // Find out what each tile has with respect to wood, or grass. int ttup; int ttdown; int ttleft; int ttright; if (pos.y - 1 < 0) { ttup = -1; //Assign trees in all directions } else { const CMapField &new_mf = *(&mf - this->Info.MapWidth); ttup = seen ? new_mf.playerInfo.SeenTile : new_mf.getGraphicTile(); } if (pos.x + 1 >= this->Info.MapWidth) { ttright = -1; //Assign trees in all directions } else { const CMapField &new_mf = *(&mf + 1); ttright = seen ? new_mf.playerInfo.SeenTile : new_mf.getGraphicTile(); } if (pos.y + 1 >= this->Info.MapHeight) { ttdown = -1; //Assign trees in all directions } else { const CMapField &new_mf = *(&mf + this->Info.MapWidth); ttdown = seen ? new_mf.playerInfo.SeenTile : new_mf.getGraphicTile(); } if (pos.x - 1 < 0) { ttleft = -1; //Assign trees in all directions } else { const CMapField &new_mf = *(&mf - 1); ttleft = seen ? new_mf.playerInfo.SeenTile : new_mf.getGraphicTile(); } int tile = this->Tileset->getTileBySurrounding(type, ttup, ttright, ttdown, ttleft); //Update seen tile. if (tile == -1) { // No valid wood remove it. if (seen) { mf.playerInfo.SeenTile = removedtile; this->FixNeighbors(type, seen, pos); } else { mf.setGraphicTile(removedtile); mf.Flags &= ~flags; mf.Value = 0; UI.Minimap.UpdateXY(pos); } } else if (seen && this->Tileset->isEquivalentTile(tile, mf.playerInfo.SeenTile)) { //Same Type return; } else { if (seen) { mf.playerInfo.SeenTile = tile; } else { mf.setGraphicTile(tile); } } //maybe isExplored if (mf.playerInfo.IsExplored(*ThisPlayer)) { UI.Minimap.UpdateSeenXY(pos); if (!seen) { MarkSeenTile(mf); } } }