1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Change cartographer tile reveal logic to match H3

This commit is contained in:
M 2022-12-30 15:09:09 +01:00
parent 486c9612b8
commit 23de4a188b
5 changed files with 70 additions and 11 deletions

View File

@ -67,7 +67,7 @@ void CPrivilegedInfoCallback::getTilesInRange(std::unordered_set<int3, ShashInt3
return;
}
if(radious == CBuilding::HEIGHT_SKYSHIP) //reveal entire map
getAllTiles (tiles, player, -1, 0);
getAllTiles (tiles, player, -1, MapTerrainFilterMode::NONE);
else
{
const TeamState * team = !player ? nullptr : gs->getPlayerTeam(*player);
@ -91,15 +91,15 @@ void CPrivilegedInfoCallback::getTilesInRange(std::unordered_set<int3, ShashInt3
}
}
void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3, ShashInt3> & tiles, boost::optional<PlayerColor> Player, int level, int surface) const
void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3, ShashInt3> & tiles, boost::optional<PlayerColor> Player, int level, MapTerrainFilterMode tileFilterMode) const
{
if(!!Player && *Player >= PlayerColor::PLAYER_LIMIT)
{
logGlobal->error("Illegal call to getAllTiles !");
return;
}
bool water = surface == 0 || surface == 2,
land = surface == 0 || surface == 1;
// bool water = surface == 0 || surface == 2,
// land = surface == 0 || surface == 1;
std::vector<int> floors;
if(level == -1)
@ -114,13 +114,32 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3, ShashInt3> &
for (auto zd : floors)
{
for (int xd = 0; xd < gs->map->width; xd++)
{
for (int yd = 0; yd < gs->map->height; yd++)
{
if ((getTile (int3 (xd,yd,zd))->terType->isWater() && water)
|| (getTile (int3 (xd,yd,zd))->terType->isLand() && land))
bool isTileEligible = false;
switch(tileFilterMode)
{
case MapTerrainFilterMode::NONE:
isTileEligible = true;
break;
case MapTerrainFilterMode::WATER:
isTileEligible = getTile (int3 (xd,yd,zd))->terType->isWater();
break;
case MapTerrainFilterMode::LAND:
isTileEligible = getTile (int3 (xd,yd,zd))->terType->isLand();
break;
case MapTerrainFilterMode::LAND_CARTOGRAPHER:
isTileEligible = getTile(int3 (xd,yd,zd))->terType->isSurfaceCartographerCompatible();
break;
case MapTerrainFilterMode::UNDERGROUND_CARTOGRAPHER:
isTileEligible = getTile(int3 (xd,yd,zd))->terType->isUndergroundCartographerCompatible();
break;
}
if (isTileEligible)
tiles.insert(int3(xd,yd,zd));
}
}

View File

@ -40,10 +40,22 @@ namespace scripting
class DLL_LINKAGE CPrivilegedInfoCallback : public CGameInfoCallback
{
public:
enum class MapTerrainFilterMode
{
NONE = 0,
LAND = 1,
WATER = 2,
LAND_CARTOGRAPHER = 3,
UNDERGROUND_CARTOGRAPHER = 4
};
CGameState * gameState();
void getFreeTiles (std::vector<int3> &tiles) const; //used for random spawns
void getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int mode = 0, int3::EDistanceFormula formula = int3::DIST_2D) const; //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only revealed
void getAllTiles (std::unordered_set<int3, ShashInt3> &tiles, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
//used for random spawns
void getFreeTiles (std::vector<int3> &tiles) const;
//mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only revealed
void getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int mode = 0, int3::EDistanceFormula formula = int3::DIST_2D) const;
//returns all tiles on given level (-1 - both levels, otherwise number of level)
void getAllTiles (std::unordered_set<int3, ShashInt3> &tiles, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int level=-1, MapTerrainFilterMode tileFilterMode = MapTerrainFilterMode::NONE) const;
void pickAllowedArtsSet(std::vector<const CArtifact*> &out, CRandomGenerator & rand); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
void getAllowedSpells(std::vector<SpellID> &out, ui16 level);

View File

@ -440,6 +440,16 @@ bool TerrainType::isUnderground() const
return passabilityType & PassabilityType::SUBTERRANEAN;
}
bool TerrainType::isSurfaceCartographerCompatible() const
{
return isLand() && id != Terrain::SUBTERRANEAN && id != Terrain::ROCK;
}
bool TerrainType::isUndergroundCartographerCompatible() const
{
return isLand() && id == Terrain::SUBTERRANEAN;
}
bool TerrainType::isTransitionRequired() const
{
return transitionRequired;

View File

@ -60,6 +60,8 @@ public:
bool isSurface() const;
bool isUnderground() const;
bool isTransitionRequired() const;
bool isSurfaceCartographerCompatible() const;
bool isUndergroundCartographerCompatible() const;
operator std::string() const;

View File

@ -2077,7 +2077,23 @@ void CCartographer::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answ
//subIDs of different types of cartographers:
//water = 0; land = 1; underground = 2;
cb->getAllTiles (fw.tiles, hero->tempOwner, subID - 1, !subID + 1); //reveal appropriate tiles
IGameCallback::MapTerrainFilterMode tileFilterMode = IGameCallback::MapTerrainFilterMode::NONE;
switch(subID)
{
case 0:
tileFilterMode = CPrivilegedInfoCallback::MapTerrainFilterMode::WATER;
break;
case 1:
tileFilterMode = CPrivilegedInfoCallback::MapTerrainFilterMode::LAND_CARTOGRAPHER;
break;
case 2:
tileFilterMode = CPrivilegedInfoCallback::MapTerrainFilterMode::UNDERGROUND_CARTOGRAPHER;
break;
}
cb->getAllTiles (fw.tiles, hero->tempOwner, -1, tileFilterMode); //reveal appropriate tiles
cb->sendAndApply (&fw);
cb->setObjProperty (id, CCartographer::OBJPROP_VISITED, hero->tempOwner.getNum());
}