1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-14 02:33:51 +02:00

Merge pull request #1351 from dydzio0614/cartographer-logic-fix

Change cartographer tile reveal logic to match H3
This commit is contained in:
Ivan Savenko 2023-01-01 12:57:24 +02:00 committed by GitHub
commit 71bedf130f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 86 additions and 21 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,13 @@ 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;
std::vector<int> floors;
if(level == -1)
@ -112,16 +110,35 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3, ShashInt3> &
else
floors.push_back(level);
for (auto zd : floors)
for(auto zd: floors)
{
for (int xd = 0; xd < gs->map->width; xd++)
for(int xd = 0; xd < gs->map->width; xd++)
{
for (int yd = 0; yd < gs->map->height; yd++)
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))
tiles.insert(int3(xd,yd,zd));
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,11 +40,31 @@ namespace scripting
class DLL_LINKAGE CPrivilegedInfoCallback : public CGameInfoCallback
{
public:
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
void pickAllowedArtsSet(std::vector<const CArtifact*> &out, CRandomGenerator & rand); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
enum class MapTerrainFilterMode
{
NONE = 0,
LAND = 1,
WATER = 2,
LAND_CARTOGRAPHER = 3,
UNDERGROUND_CARTOGRAPHER = 4
};
CGameState *gameState();
//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);
template<typename Saver>

View File

@ -440,6 +440,16 @@ bool TerrainType::isUnderground() const
return passabilityType & PassabilityType::SUBTERRANEAN;
}
bool TerrainType::isSurfaceCartographerCompatible() const
{
return isSurface();
}
bool TerrainType::isUndergroundCartographerCompatible() const
{
return isLand() && isPassable() && !isSurface();
}
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

@ -2068,18 +2068,34 @@ void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
void CCartographer::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
{
if (answer) //if hero wants to buy map
if(answer) //if hero wants to buy map
{
cb->giveResource (hero->tempOwner, Res::GOLD, -1000);
cb->giveResource(hero->tempOwner, Res::GOLD, -1000);
FoWChange fw;
fw.mode = 1;
fw.player = hero->tempOwner;
//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
cb->sendAndApply (&fw);
cb->setObjProperty (id, CCartographer::OBJPROP_VISITED, hero->tempOwner.getNum());
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());
}
}