mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-17 20:58:07 +02:00
Cartographer/Observatory is now configurable object
This commit is contained in:
parent
f3ed589e35
commit
98fd939ed6
13
Global.h
13
Global.h
@ -475,6 +475,19 @@ namespace vstd
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Elem, typename Predicate>
|
||||
void erase_if(std::unordered_set<Elem> &setContainer, Predicate pred)
|
||||
{
|
||||
auto itr = setContainer.begin();
|
||||
auto endItr = setContainer.end();
|
||||
while(itr != endItr)
|
||||
{
|
||||
auto tmpItr = itr++;
|
||||
if(pred(*tmpItr))
|
||||
setContainer.erase(tmpItr);
|
||||
}
|
||||
}
|
||||
|
||||
//works for map and std::map, maybe something else
|
||||
template<typename Key, typename Val, typename Predicate>
|
||||
void erase_if(std::map<Key, Val> &container, Predicate pred)
|
||||
|
@ -177,7 +177,7 @@ void ApplyClientNetPackVisitor::visitFoWChange(FoWChange & pack)
|
||||
}
|
||||
if(cl.getPlayerRelations(i.first, pack.player) != PlayerRelations::ENEMIES)
|
||||
{
|
||||
if(pack.mode)
|
||||
if(pack.mode == FoWChange::Mode::REVEAL)
|
||||
i.second->tileRevealed(pack.tiles);
|
||||
else
|
||||
i.second->tileHidden(pack.tiles);
|
||||
|
@ -156,70 +156,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
"redwoodObservatory" : {
|
||||
"index" :58,
|
||||
"handler" : "observatory",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"aiValue" : 750,
|
||||
"templates" :
|
||||
{
|
||||
"base" : { "animation" : "avxredw.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "VV", "VA"], "allowedTerrains":["grass", "swamp", "dirt", "sand", "lava", "rough"] },
|
||||
"snow" : { "animation" : "avxreds0.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "VV", "VA"], "allowedTerrains":["snow"] }
|
||||
},
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 750,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pillarOfFire" : {
|
||||
"index" :60,
|
||||
"handler" : "observatory",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"ambient" : ["LOOPFIRE"],
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"aiValue" : 750,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 750,
|
||||
"rarity" : 100
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"coverOfDarkness" : {
|
||||
"index" :15,
|
||||
"handler" : "observatory",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"object" : {
|
||||
"index" : 0,
|
||||
"aiValue" : 100,
|
||||
"rmg" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"whirlpool" : {
|
||||
"index" :111,
|
||||
"handler" : "whirlpool",
|
||||
|
@ -255,23 +255,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
// subtype: different revealed areas
|
||||
"cartographer" : {
|
||||
"index" :13,
|
||||
"handler": "cartographer",
|
||||
"lastReservedIndex" : 2,
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"water" : { "index" : 0, "aiValue" : 5000, "rmg" : { "zoneLimit" : 1, "value" : 5000, "rarity" : 20 } },
|
||||
"land" : { "index" : 1, "aiValue": 10000, "rmg" : { "zoneLimit" : 1, "value" : 10000, "rarity" : 20 } },
|
||||
"subterra" : { "index" : 2, "aiValue" : 7500, "rmg" : { "zoneLimit" : 1, "value" : 7500, "rarity" : 20 } }
|
||||
}
|
||||
},
|
||||
|
||||
// subtype: resource ID
|
||||
"mine" : {
|
||||
"index" :53,
|
||||
|
@ -66,4 +66,212 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"redwoodObservatory" : {
|
||||
"index" :58,
|
||||
"handler" : "configurable",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"redwoodObservatory" : {
|
||||
"index" : 0,
|
||||
"aiValue" : 750,
|
||||
"templates" :
|
||||
{
|
||||
"base" : { "animation" : "avxredw.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "VV", "VA"], "allowedTerrains":["grass", "swamp", "dirt", "sand", "lava", "rough"] },
|
||||
"snow" : { "animation" : "avxreds0.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "VV", "VA"], "allowedTerrains":["snow"] }
|
||||
},
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 750,
|
||||
"rarity" : 100
|
||||
},
|
||||
|
||||
"compatibilityIdentifiers" : [ "object" ],
|
||||
"visitMode" : "unlimited",
|
||||
"rewards" : [
|
||||
{
|
||||
"message" : 98,
|
||||
"revealTiles" : {
|
||||
"radius" : 20,
|
||||
"surface" : 1,
|
||||
"subterra" : 1,
|
||||
"water" : 1,
|
||||
"rock" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"pillarOfFire" : {
|
||||
"index" :60,
|
||||
"handler" : "configurable",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"ambient" : ["LOOPFIRE"],
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"pillarOfFire" : {
|
||||
"index" : 0,
|
||||
"aiValue" : 750,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 750,
|
||||
"rarity" : 100
|
||||
},
|
||||
|
||||
"compatibilityIdentifiers" : [ "object" ],
|
||||
"visitMode" : "unlimited",
|
||||
"rewards" : [
|
||||
{
|
||||
"message" : 99,
|
||||
"revealTiles" : {
|
||||
"radius" : 20,
|
||||
"surface" : 1,
|
||||
"subterra" : 1,
|
||||
"water" : 1,
|
||||
"rock" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"coverOfDarkness" : {
|
||||
"index" :15,
|
||||
"handler" : "configurable",
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"coverOfDarkness" : {
|
||||
"index" : 0,
|
||||
"aiValue" : 100,
|
||||
"rmg" : {
|
||||
},
|
||||
|
||||
"compatibilityIdentifiers" : [ "object" ],
|
||||
"visitMode" : "unlimited",
|
||||
"rewards" : [
|
||||
{
|
||||
"message" : 31,
|
||||
"revealTiles" : {
|
||||
"radius" : 20,
|
||||
"surface" : 1,
|
||||
"subterra" : 1,
|
||||
"water" : 1,
|
||||
"rock" : 1,
|
||||
"hide" : true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"cartographer" : {
|
||||
"index" :13,
|
||||
"handler": "configurable",
|
||||
"lastReservedIndex" : 2,
|
||||
"base" : {
|
||||
"sounds" : {
|
||||
"visit" : ["LIGHTHOUSE"]
|
||||
}
|
||||
},
|
||||
"types" : {
|
||||
"cartographerWater" : {
|
||||
"index" : 0,
|
||||
"aiValue" : 5000,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 5000,
|
||||
"rarity" : 20
|
||||
},
|
||||
"compatibilityIdentifiers" : [ "water" ],
|
||||
"visitMode" : "unlimited",
|
||||
"canRefuse" : true,
|
||||
"rewards" : [
|
||||
{
|
||||
"limiter" : { "resources" : { "gold" : 1000 } },
|
||||
"message" : 25,
|
||||
"resources" : {
|
||||
"gold" : -1000
|
||||
},
|
||||
"revealTiles" : {
|
||||
"water" : 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"onEmptyMessage" : 28,
|
||||
"onVisitedMessage" : 24
|
||||
},
|
||||
"cartographerLand" : {
|
||||
"index" : 1,
|
||||
"aiValue": 10000,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 10000,
|
||||
"rarity" : 2
|
||||
},
|
||||
"compatibilityIdentifiers" : [ "land" ],
|
||||
"visitMode" : "unlimited",
|
||||
"canRefuse" : true,
|
||||
"rewards" : [
|
||||
{
|
||||
"limiter" : { "resources" : { "gold" : 1000 } },
|
||||
"message" : 26,
|
||||
"resources" : {
|
||||
"gold" : -1000
|
||||
},
|
||||
"revealTiles" : {
|
||||
"surface" : 1,
|
||||
"water" : -1,
|
||||
"rock" : -1
|
||||
}
|
||||
}
|
||||
],
|
||||
"onEmptyMessage" : 28,
|
||||
"onVisitedMessage" : 24
|
||||
},
|
||||
"cartographerSubterranean" : {
|
||||
"index" : 2,
|
||||
"aiValue" : 7500,
|
||||
"rmg" : {
|
||||
"zoneLimit" : 1,
|
||||
"value" : 7500,
|
||||
"rarity" : 20
|
||||
},
|
||||
"compatibilityIdentifiers" : [ "subterra" ],
|
||||
"visitMode" : "unlimited",
|
||||
"canRefuse" : true,
|
||||
"rewards" : [
|
||||
{
|
||||
"limiter" : { "resources" : { "gold" : 1000 } },
|
||||
"message" : 27,
|
||||
"resources" : {
|
||||
"gold" : -1000
|
||||
},
|
||||
"revealTiles" : {
|
||||
"subterra" : 1,
|
||||
"water" : -1,
|
||||
"rock" : -1,
|
||||
"surface" : -1
|
||||
}
|
||||
}
|
||||
],
|
||||
"onEmptyMessage" : 28,
|
||||
"onVisitedMessage" : 24
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -607,7 +607,7 @@ EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, Bu
|
||||
{
|
||||
const TerrainTile *tile = getTile(t->bestLocation(), false);
|
||||
|
||||
if(!tile || tile->terType->isLand())
|
||||
if(!tile || !tile->terType->isWater())
|
||||
return EBuildingState::NO_WATER; //lack of water
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ void CPrivilegedInfoCallback::getTilesInRange(std::unordered_set<int3> & tiles,
|
||||
return;
|
||||
}
|
||||
if(radious == CBuilding::HEIGHT_SKYSHIP) //reveal entire map
|
||||
getAllTiles (tiles, player, -1, MapTerrainFilterMode::NONE);
|
||||
getAllTiles (tiles, player, -1, [](auto * tile){return true;});
|
||||
else
|
||||
{
|
||||
const TeamState * team = !player ? nullptr : gs->getPlayerTeam(*player);
|
||||
@ -112,7 +112,7 @@ void CPrivilegedInfoCallback::getTilesInRange(std::unordered_set<int3> & tiles,
|
||||
}
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std::optional<PlayerColor> Player, int level, MapTerrainFilterMode tileFilterMode) const
|
||||
void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std::optional<PlayerColor> Player, int level, std::function<bool(const TerrainTile *)> filter) const
|
||||
{
|
||||
if(!!Player && !Player->isValidPlayer())
|
||||
{
|
||||
@ -137,29 +137,9 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std:
|
||||
{
|
||||
for(int yd = 0; yd < gs->map->height; yd++)
|
||||
{
|
||||
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));
|
||||
int3 coordinates(xd, yd, zd);
|
||||
if (filter(getTile(coordinates)))
|
||||
tiles.insert(coordinates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,15 +43,6 @@ 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();
|
||||
|
||||
//used for random spawns
|
||||
@ -66,8 +57,7 @@ public:
|
||||
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> &tiles, std::optional<PlayerColor> player = std::optional<PlayerColor>(),
|
||||
int level = -1, MapTerrainFilterMode tileFilterMode = MapTerrainFilterMode::NONE) const;
|
||||
void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const;
|
||||
|
||||
//gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
||||
void pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const;
|
||||
|
@ -344,11 +344,17 @@ struct DLL_LINKAGE SetMovePoints : public CPackForClient
|
||||
|
||||
struct DLL_LINKAGE FoWChange : public CPackForClient
|
||||
{
|
||||
enum class Mode : uint8_t
|
||||
{
|
||||
HIDE,
|
||||
REVEAL
|
||||
};
|
||||
|
||||
void applyGs(CGameState * gs);
|
||||
|
||||
std::unordered_set<int3> tiles;
|
||||
PlayerColor player;
|
||||
ui8 mode = 0; //mode==0 - hide, mode==1 - reveal
|
||||
Mode mode;
|
||||
bool waitForDialogs = false;
|
||||
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
@ -924,8 +924,9 @@ void FoWChange::applyGs(CGameState *gs)
|
||||
TeamState * team = gs->getPlayerTeam(player);
|
||||
auto fogOfWarMap = team->fogOfWarMap;
|
||||
for(const int3 & t : tiles)
|
||||
(*fogOfWarMap)[t.z][t.x][t.y] = mode;
|
||||
if (mode == 0) //do not hide too much
|
||||
(*fogOfWarMap)[t.z][t.x][t.y] = mode != Mode::HIDE;
|
||||
|
||||
if (mode == Mode::HIDE) //do not hide too much
|
||||
{
|
||||
std::unordered_set<int3> tilesRevealed;
|
||||
for (auto & elem : gs->map->objects)
|
||||
|
@ -155,9 +155,14 @@ bool TerrainType::isWater() const
|
||||
return passabilityType & PassabilityType::WATER;
|
||||
}
|
||||
|
||||
bool TerrainType::isRock() const
|
||||
{
|
||||
return passabilityType & PassabilityType::ROCK;
|
||||
}
|
||||
|
||||
bool TerrainType::isPassable() const
|
||||
{
|
||||
return !(passabilityType & PassabilityType::ROCK);
|
||||
return !isRock();
|
||||
}
|
||||
|
||||
bool TerrainType::isSurface() const
|
||||
@ -170,16 +175,6 @@ 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;
|
||||
|
@ -84,12 +84,13 @@ public:
|
||||
|
||||
bool isLand() const;
|
||||
bool isWater() const;
|
||||
bool isRock() const;
|
||||
|
||||
bool isPassable() const;
|
||||
|
||||
bool isSurface() const;
|
||||
bool isUnderground() const;
|
||||
bool isTransitionRequired() const;
|
||||
bool isSurfaceCartographerCompatible() const;
|
||||
bool isUndergroundCartographerCompatible() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -71,7 +71,6 @@ CObjectClassesHandler::CObjectClassesHandler()
|
||||
SET_HANDLER("randomDwelling", CGDwelling);
|
||||
|
||||
SET_HANDLER("generic", CGObjectInstance);
|
||||
SET_HANDLER("cartographer", CCartographer);
|
||||
SET_HANDLER("artifact", CGArtifact);
|
||||
SET_HANDLER("borderGate", CGBorderGate);
|
||||
SET_HANDLER("borderGuard", CGBorderGuard);
|
||||
@ -84,7 +83,6 @@ CObjectClassesHandler::CObjectClassesHandler()
|
||||
SET_HANDLER("magi", CGMagi);
|
||||
SET_HANDLER("mine", CGMine);
|
||||
SET_HANDLER("obelisk", CGObelisk);
|
||||
SET_HANDLER("observatory", CGObservatory);
|
||||
SET_HANDLER("pandora", CGPandoraBox);
|
||||
SET_HANDLER("prison", CGHeroInstance);
|
||||
SET_HANDLER("questGuard", CGQuestGuard);
|
||||
|
@ -1068,7 +1068,7 @@ void CGTownInstance::onTownCaptured(const PlayerColor & winner) const
|
||||
setOwner(winner);
|
||||
FoWChange fw;
|
||||
fw.player = winner;
|
||||
fw.mode = 1;
|
||||
fw.mode = FoWChange::Mode::REVEAL;
|
||||
cb->getTilesInRange(fw.tiles, getSightCenter(), getSightRadius(), winner, 1);
|
||||
cb->sendAndApply(& fw);
|
||||
}
|
||||
|
@ -90,6 +90,5 @@ public:
|
||||
|
||||
// POSSIBLE
|
||||
// class DLL_LINKAGE CGSignBottle : public CGObjectInstance //signs and ocean bottles
|
||||
// class DLL_LINKAGE CGScholar : public CGObjectInstance
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -842,40 +842,6 @@ void CGArtifact::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
}
|
||||
}
|
||||
|
||||
void CGObservatory::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.player = h->tempOwner;
|
||||
switch (ID)
|
||||
{
|
||||
case Obj::REDWOOD_OBSERVATORY:
|
||||
case Obj::PILLAR_OF_FIRE:
|
||||
{
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT,98 + (ID==Obj::PILLAR_OF_FIRE));
|
||||
|
||||
FoWChange fw;
|
||||
fw.player = h->tempOwner;
|
||||
fw.mode = 1;
|
||||
cb->getTilesInRange (fw.tiles, pos, 20, h->tempOwner, 1);
|
||||
cb->sendAndApply (&fw);
|
||||
break;
|
||||
}
|
||||
case Obj::COVER_OF_DARKNESS:
|
||||
{
|
||||
iw.text.appendLocalString (EMetaText::ADVOB_TXT, 31);
|
||||
for (auto & player : cb->gameState()->players)
|
||||
{
|
||||
if (cb->getPlayerStatus(player.first) == EPlayerStatus::INGAME &&
|
||||
cb->getPlayerRelations(player.first, h->tempOwner) == PlayerRelations::ENEMIES)
|
||||
cb->changeFogOfWar(visitablePos(), 20, player.first, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
cb->showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
void CGShrine::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(spell == SpellID::NONE)
|
||||
@ -1175,7 +1141,7 @@ void CGMagi::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
FoWChange fw;
|
||||
fw.player = h->tempOwner;
|
||||
fw.mode = 1;
|
||||
fw.mode = FoWChange::Mode::REVEAL;
|
||||
fw.waitForDialogs = true;
|
||||
|
||||
for(const auto & it : eyelist[subID])
|
||||
@ -1321,79 +1287,6 @@ BoatId CGShipyard::getBoatType() const
|
||||
return createdBoat;
|
||||
}
|
||||
|
||||
void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
//if player has not bought map of this subtype yet and underground exist for stalagmite cartographer
|
||||
if (!wasVisited(h->getOwner()) && (subID != 2 || cb->gameState()->map->twoLevel))
|
||||
{
|
||||
if (cb->getResource(h->tempOwner, EGameResID::GOLD) >= 1000) //if he can afford a map
|
||||
{
|
||||
//ask if he wants to buy one
|
||||
int text=0;
|
||||
switch (subID)
|
||||
{
|
||||
case 0:
|
||||
text = 25;
|
||||
break;
|
||||
case 1:
|
||||
text = 26;
|
||||
break;
|
||||
case 2:
|
||||
text = 27;
|
||||
break;
|
||||
default:
|
||||
logGlobal->warn("Unrecognized subtype of cartographer");
|
||||
}
|
||||
assert(text);
|
||||
BlockingDialog bd (true, false);
|
||||
bd.player = h->getOwner();
|
||||
bd.text.appendLocalString (EMetaText::ADVOB_TXT, text);
|
||||
cb->showBlockingDialog (&bd);
|
||||
}
|
||||
else //if he cannot afford
|
||||
{
|
||||
h->showInfoDialog(28);
|
||||
}
|
||||
}
|
||||
else //if he already visited carographer
|
||||
{
|
||||
h->showInfoDialog(24);
|
||||
}
|
||||
}
|
||||
|
||||
void CCartographer::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
|
||||
{
|
||||
if(answer) //if hero wants to buy map
|
||||
{
|
||||
cb->giveResource(hero->tempOwner, EGameResID::GOLD, -1000);
|
||||
FoWChange fw;
|
||||
fw.mode = 1;
|
||||
fw.player = hero->tempOwner;
|
||||
|
||||
//subIDs of different types of cartographers:
|
||||
//water = 0; land = 1; underground = 2;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
void CGDenOfthieves::onHeroVisit (const CGHeroInstance * h) const
|
||||
{
|
||||
cb->showObjectWindow(this, EOpenWindowMode::THIEVES_GUILD, h, false);
|
||||
|
@ -314,17 +314,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGObservatory : public CGObjectInstance //Redwood observatory
|
||||
{
|
||||
public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGBoat : public CGObjectInstance, public CBonusSystemNode
|
||||
{
|
||||
public:
|
||||
@ -396,19 +385,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CCartographer : public CTeamVisited
|
||||
{
|
||||
///behaviour varies depending on surface and floor
|
||||
public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CTeamVisited&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGDenOfthieves : public CGObjectInstance
|
||||
{
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
|
@ -56,7 +56,6 @@ void registerTypesMapObjects1(Serializer &s)
|
||||
s.template registerType<CGMonolith, CGWhirlpool>();
|
||||
s.template registerType<CGObjectInstance, CGSignBottle>();
|
||||
s.template registerType<CGObjectInstance, CGScholar>();
|
||||
s.template registerType<CGObjectInstance, CGObservatory>();
|
||||
s.template registerType<CGObjectInstance, CGKeys>();
|
||||
s.template registerType<CGKeys, CGKeymasterTent>();
|
||||
s.template registerType<CGKeys, CGBorderGuard>(); s.template registerType<IQuestObject, CGBorderGuard>();
|
||||
@ -112,7 +111,6 @@ void registerTypesMapObjectTypes(Serializer &s)
|
||||
#define REGISTER_GENERIC_HANDLER(TYPENAME) s.template registerType<AObjectTypeHandler, CDefaultObjectTypeHandler<TYPENAME> >()
|
||||
|
||||
REGISTER_GENERIC_HANDLER(CGObjectInstance);
|
||||
REGISTER_GENERIC_HANDLER(CCartographer);
|
||||
REGISTER_GENERIC_HANDLER(CGArtifact);
|
||||
REGISTER_GENERIC_HANDLER(CGBlackMarket);
|
||||
REGISTER_GENERIC_HANDLER(CGBoat);
|
||||
@ -132,7 +130,6 @@ void registerTypesMapObjectTypes(Serializer &s)
|
||||
REGISTER_GENERIC_HANDLER(CGMarket);
|
||||
REGISTER_GENERIC_HANDLER(CGMine);
|
||||
REGISTER_GENERIC_HANDLER(CGObelisk);
|
||||
REGISTER_GENERIC_HANDLER(CGObservatory);
|
||||
REGISTER_GENERIC_HANDLER(CGPandoraBox);
|
||||
REGISTER_GENERIC_HANDLER(CGQuestGuard);
|
||||
REGISTER_GENERIC_HANDLER(CGResource);
|
||||
@ -177,7 +174,6 @@ void registerTypesMapObjects2(Serializer &s)
|
||||
|
||||
s.template registerType<CGObjectInstance, CTeamVisited>();
|
||||
s.template registerType<CTeamVisited, CGShrine>();
|
||||
s.template registerType<CTeamVisited, CCartographer>();
|
||||
s.template registerType<CTeamVisited, CGObelisk>();
|
||||
|
||||
//s.template registerType<CQuest>();
|
||||
|
@ -161,6 +161,20 @@ void Rewardable::Info::configureReward(Rewardable::Configuration & object, CRand
|
||||
reward.spellCast.second = source["spellCast"]["schoolLevel"].Integer();
|
||||
}
|
||||
|
||||
if (!source["revealTiles"].isNull())
|
||||
{
|
||||
auto const & entry = source["revealTiles"];
|
||||
|
||||
reward.revealTiles = RewardRevealTiles();
|
||||
reward.revealTiles->radius = JsonRandom::loadValue(entry["radius"], rng, variables);
|
||||
reward.revealTiles->hide = entry["hide"].Bool();
|
||||
|
||||
reward.revealTiles->scoreSurface = JsonRandom::loadValue(entry["surface"], rng, variables);
|
||||
reward.revealTiles->scoreSubterra = JsonRandom::loadValue(entry["subterra"], rng, variables);
|
||||
reward.revealTiles->scoreWater = JsonRandom::loadValue(entry["water"], rng, variables);
|
||||
reward.revealTiles->scoreRock = JsonRandom::loadValue(entry["rock"], rng, variables);
|
||||
}
|
||||
|
||||
for ( auto node : source["changeCreatures"].Struct() )
|
||||
{
|
||||
CreatureID from(VLC->identifiers()->getIdentifier(node.second.meta, "creature", node.first).value());
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "Interface.h"
|
||||
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../CSoundBase.h"
|
||||
#include "../NetPacks.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
@ -46,6 +47,52 @@ void Rewardable::Interface::grantRewardBeforeLevelup(IGameCallback * cb, const R
|
||||
|
||||
cb->giveResources(hero->tempOwner, info.reward.resources);
|
||||
|
||||
if (info.reward.revealTiles)
|
||||
{
|
||||
auto const & props = *info.reward.revealTiles;
|
||||
FoWChange fw;
|
||||
|
||||
if (props.hide)
|
||||
fw.mode = FoWChange::Mode::HIDE;
|
||||
else
|
||||
fw.mode = FoWChange::Mode::REVEAL;
|
||||
|
||||
fw.player = hero->tempOwner;
|
||||
|
||||
auto const functor = [&props](const TerrainTile * tile)
|
||||
{
|
||||
int score = 0;
|
||||
if (tile->terType->isSurface())
|
||||
score += props.scoreSurface;
|
||||
|
||||
if (tile->terType->isUnderground())
|
||||
score += props.scoreSubterra;
|
||||
|
||||
if (tile->terType->isWater())
|
||||
score += props.scoreWater;
|
||||
|
||||
if (tile->terType->isRock())
|
||||
score += props.scoreRock;
|
||||
|
||||
return score > 0;
|
||||
};
|
||||
|
||||
if (props.radius > 0)
|
||||
{
|
||||
cb->getTilesInRange(fw.tiles, hero->getSightCenter(), props.radius, hero->tempOwner, 1);
|
||||
vstd::erase_if(fw.tiles, [&](const int3 & coord){
|
||||
return functor(cb->getTile(coord));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
cb->getAllTiles(fw.tiles, hero->tempOwner, -1, functor);
|
||||
}
|
||||
|
||||
cb->sendAndApply(&fw);
|
||||
|
||||
}
|
||||
|
||||
for(const auto & entry : info.reward.secondary)
|
||||
{
|
||||
int current = hero->getSecSkillLevel(entry.first);
|
||||
|
@ -18,6 +18,11 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
void Rewardable::RewardRevealTiles::serializeJson(JsonSerializeFormat & handler)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
Rewardable::Reward::Reward()
|
||||
: heroExperience(0)
|
||||
, heroLevel(0)
|
||||
|
@ -27,6 +27,34 @@ namespace Rewardable
|
||||
struct Reward;
|
||||
using RewardsList = std::vector<std::shared_ptr<Rewardable::Reward>>;
|
||||
|
||||
struct RewardRevealTiles
|
||||
{
|
||||
/// Reveal distance, if not positive - reveal entire map
|
||||
int radius;
|
||||
/// Reveal score of terrains with "surface" flag set
|
||||
int scoreSurface;
|
||||
/// Reveal score of terrains with "subterra" flag set
|
||||
int scoreSubterra;
|
||||
/// Reveal score of terrains with "water" flag set
|
||||
int scoreWater;
|
||||
/// Reveal score of terrains with "rock" flag set
|
||||
int scoreRock;
|
||||
/// If set, then terrain will be instead hidden for all enemies (Cover of Darkness)
|
||||
bool hide;
|
||||
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & radius;
|
||||
h & scoreSurface;
|
||||
h & scoreSubterra;
|
||||
h & scoreWater;
|
||||
h & scoreRock;
|
||||
h & hide;
|
||||
}
|
||||
};
|
||||
|
||||
/// Reward that can be granted to a hero
|
||||
/// NOTE: eventually should replace seer hut rewards and events/pandoras
|
||||
struct DLL_LINKAGE Reward final
|
||||
@ -74,6 +102,8 @@ struct DLL_LINKAGE Reward final
|
||||
/// list of components that will be added to reward description. First entry in list will override displayed component
|
||||
std::vector<Component> extraComponents;
|
||||
|
||||
std::optional<RewardRevealTiles> revealTiles;
|
||||
|
||||
/// if set to true, object will be removed after granting reward
|
||||
bool removeObject;
|
||||
|
||||
@ -107,8 +137,8 @@ struct DLL_LINKAGE Reward final
|
||||
h & spells;
|
||||
h & creatures;
|
||||
h & creaturesChange;
|
||||
if(version >= 821)
|
||||
h & spellCast;
|
||||
h & revealTiles;
|
||||
h & spellCast;
|
||||
}
|
||||
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
@ -858,7 +858,7 @@ void CGameHandler::onNewTurn()
|
||||
if (player != PlayerColor::NEUTRAL) //do not reveal fow for neutral player
|
||||
{
|
||||
FoWChange fw;
|
||||
fw.mode = 1;
|
||||
fw.mode = FoWChange::Mode::REVEAL;
|
||||
fw.player = player;
|
||||
// find all hidden tiles
|
||||
const auto fow = getPlayerTeam(player)->fogOfWarMap;
|
||||
@ -2389,7 +2389,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
||||
// now when everything is built - reveal tiles for lookout tower
|
||||
FoWChange fw;
|
||||
fw.player = t->tempOwner;
|
||||
fw.mode = 1;
|
||||
fw.mode = FoWChange::Mode::REVEAL;
|
||||
getTilesInRange(fw.tiles, t->getSightCenter(), t->getSightRadius(), t->tempOwner, 1);
|
||||
sendAndApply(&fw);
|
||||
|
||||
@ -4135,7 +4135,7 @@ void CGameHandler::changeFogOfWar(std::unordered_set<int3> &tiles, PlayerColor p
|
||||
FoWChange fow;
|
||||
fow.tiles = tiles;
|
||||
fow.player = player;
|
||||
fow.mode = hide? 0 : 1;
|
||||
fow.mode = hide ? FoWChange::Mode::HIDE : FoWChange::Mode::REVEAL;
|
||||
sendAndApply(&fow);
|
||||
}
|
||||
|
||||
|
@ -346,7 +346,7 @@ void PlayerMessageProcessor::cheatDefeat(PlayerColor player)
|
||||
void PlayerMessageProcessor::cheatMapReveal(PlayerColor player, bool reveal)
|
||||
{
|
||||
FoWChange fc;
|
||||
fc.mode = reveal;
|
||||
fc.mode = reveal ? FoWChange::Mode::REVEAL : FoWChange::Mode::HIDE;
|
||||
fc.player = player;
|
||||
const auto & fowMap = gameHandler->gameState()->getPlayerTeam(player)->fogOfWarMap;
|
||||
const auto & mapSize = gameHandler->gameState()->getMapSize();
|
||||
@ -356,7 +356,7 @@ void PlayerMessageProcessor::cheatMapReveal(PlayerColor player, bool reveal)
|
||||
for(int z = 0; z < mapSize.z; z++)
|
||||
for(int x = 0; x < mapSize.x; x++)
|
||||
for(int y = 0; y < mapSize.y; y++)
|
||||
if(!(*fowMap)[z][x][y] || !fc.mode)
|
||||
if(!(*fowMap)[z][x][y] || fc.mode == FoWChange::Mode::HIDE)
|
||||
hlp_tab[lastUnc++] = int3(x, y, z);
|
||||
|
||||
fc.tiles.insert(hlp_tab, hlp_tab + lastUnc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user