mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-30 23:18:08 +02:00
Added per-team tracking of scouted state of an object
This commit is contained in:
parent
785036836c
commit
cb5df096c1
@ -153,6 +153,8 @@ public:
|
||||
//TODO: boost::array, bool if possible
|
||||
boost::multi_array<ui8, 3> fogOfWarMap; //[z][x][y] true - visible, false - hidden
|
||||
|
||||
std::set<ObjectInstanceID> scoutedObjects;
|
||||
|
||||
TeamState();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
@ -173,6 +175,9 @@ public:
|
||||
|
||||
h & fogOfWarMap;
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
|
||||
if (h.version >= Handler::Version::TEAM_STATE_SCOUTED_OBJECTS)
|
||||
h & scoutedObjects;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -137,7 +137,7 @@ bool CBank::wasVisited (PlayerColor player) const
|
||||
|
||||
void CBank::onHeroVisit(const CGHeroInstance * h) const
|
||||
{
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_TEAM, id, h->id);
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_PLAYER, id, h->id);
|
||||
cb->sendAndApply(&cov);
|
||||
|
||||
if(!bankConfig && (ID.toEnum() == Obj::CREATURE_BANK || ID.toEnum() == Obj::DRAGON_UTOPIA))
|
||||
|
@ -108,24 +108,30 @@ bool CRewardableObject::guardedPresently() const
|
||||
return stacksCount() > 0;
|
||||
}
|
||||
|
||||
void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const
|
||||
void CRewardableObject::onHeroVisit(const CGHeroInstance *hero) const
|
||||
{
|
||||
if(!wasScouted(hero->getOwner()))
|
||||
{
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_SCOUTED, id, hero->id);
|
||||
cb->sendAndApply(&cov);
|
||||
}
|
||||
|
||||
if (guardedPresently())
|
||||
{
|
||||
auto guardedIndexes = getAvailableRewards(h, Rewardable::EEventType::EVENT_GUARDED);
|
||||
auto guardedIndexes = getAvailableRewards(hero, Rewardable::EEventType::EVENT_GUARDED);
|
||||
auto guardedReward = configuration.info.at(guardedIndexes.at(0));
|
||||
|
||||
// ask player to confirm attack
|
||||
BlockingDialog bd(true, false);
|
||||
bd.player = h->getOwner();
|
||||
bd.player = hero->getOwner();
|
||||
bd.text = guardedReward.message;
|
||||
bd.components = getPopupComponents(h->getOwner());
|
||||
bd.components = getPopupComponents(hero->getOwner());
|
||||
|
||||
cb->showBlockingDialog(&bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
doHeroVisit(h);
|
||||
doHeroVisit(hero);
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,7 +198,7 @@ void CRewardableObject::doHeroVisit(const CGHeroInstance *h) const
|
||||
|
||||
if(!objectRemovalPossible && getAvailableRewards(h, Rewardable::EEventType::EVENT_FIRST_VISIT).empty())
|
||||
{
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_TEAM, id, h->id);
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_PLAYER, id, h->id);
|
||||
cb->sendAndApply(&cov);
|
||||
}
|
||||
}
|
||||
@ -202,7 +208,7 @@ void CRewardableObject::doHeroVisit(const CGHeroInstance *h) const
|
||||
|
||||
if (!wasVisited(h->getOwner()))
|
||||
{
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_TEAM, id, h->id);
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_PLAYER, id, h->id);
|
||||
cb->sendAndApply(&cov);
|
||||
}
|
||||
|
||||
@ -236,27 +242,6 @@ void CRewardableObject::blockingDialogAnswered(const CGHeroInstance * hero, int3
|
||||
}
|
||||
else
|
||||
{
|
||||
if(answer == 0)
|
||||
{
|
||||
switch(configuration.visitMode)
|
||||
{
|
||||
case Rewardable::VISIT_UNLIMITED:
|
||||
case Rewardable::VISIT_BONUS:
|
||||
case Rewardable::VISIT_HERO:
|
||||
case Rewardable::VISIT_LIMITER:
|
||||
{
|
||||
// workaround for object with refusable reward not getting marked as visited
|
||||
// TODO: better solution that would also work for player-visitable objects
|
||||
if(!wasScouted(hero->getOwner()))
|
||||
{
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_TEAM, id, hero->id);
|
||||
cb->sendAndApply(&cov);
|
||||
}
|
||||
}
|
||||
}
|
||||
return; // player refused
|
||||
}
|
||||
|
||||
if(answer > 0 && answer - 1 < configuration.info.size())
|
||||
{
|
||||
auto list = getAvailableRewards(hero, Rewardable::EEventType::EVENT_FIRST_VISIT);
|
||||
@ -274,7 +259,7 @@ void CRewardableObject::markAsVisited(const CGHeroInstance * hero) const
|
||||
{
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_CLEARED, true);
|
||||
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD, id, hero->id);
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_HERO, id, hero->id);
|
||||
cb->sendAndApply(&cov);
|
||||
}
|
||||
|
||||
@ -330,7 +315,7 @@ bool CRewardableObject::wasVisited(PlayerColor player) const
|
||||
|
||||
bool CRewardableObject::wasScouted(PlayerColor player) const
|
||||
{
|
||||
return vstd::contains(cb->getPlayerState(player)->visitedObjects, ObjectInstanceID(id));
|
||||
return vstd::contains(cb->getPlayerTeam(player)->scoutedObjects, ObjectInstanceID(id));
|
||||
}
|
||||
|
||||
bool CRewardableObject::wasVisited(const CGHeroInstance * h) const
|
||||
@ -418,9 +403,6 @@ std::vector<Component> CRewardableObject::getPopupComponentsImpl(PlayerColor pla
|
||||
if (!wasScouted(player))
|
||||
return {};
|
||||
|
||||
if (!configuration.showScoutedPreview)
|
||||
return {};
|
||||
|
||||
if (guardedPresently())
|
||||
{
|
||||
if (!VLC->settings()->getBoolean(EGameSettings::BANKS_SHOW_GUARDS_COMPOSITION))
|
||||
@ -442,6 +424,9 @@ std::vector<Component> CRewardableObject::getPopupComponentsImpl(PlayerColor pla
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!configuration.showScoutedPreview)
|
||||
return {};
|
||||
|
||||
auto rewardIndices = getAvailableRewards(hero, Rewardable::EEventType::EVENT_FIRST_VISIT);
|
||||
if (rewardIndices.empty() && !configuration.info.empty())
|
||||
{
|
||||
|
@ -1035,32 +1035,32 @@ void ChangeObjPos::applyGs(CGameState *gs)
|
||||
void ChangeObjectVisitors::applyGs(CGameState *gs)
|
||||
{
|
||||
switch (mode) {
|
||||
case VISITOR_ADD:
|
||||
case VISITOR_ADD_HERO:
|
||||
gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->scoutedObjects.insert(object);
|
||||
gs->getHero(hero)->visitedObjects.insert(object);
|
||||
gs->getPlayerState(gs->getHero(hero)->tempOwner)->visitedObjects.insert(object);
|
||||
break;
|
||||
case VISITOR_ADD_TEAM:
|
||||
{
|
||||
TeamState *ts = gs->getPlayerTeam(gs->getHero(hero)->tempOwner);
|
||||
for(const auto & color : ts->players)
|
||||
{
|
||||
gs->getPlayerState(color)->visitedObjects.insert(object);
|
||||
}
|
||||
}
|
||||
case VISITOR_ADD_PLAYER:
|
||||
gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->scoutedObjects.insert(object);
|
||||
for(const auto & color : gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->players)
|
||||
gs->getPlayerState(color)->visitedObjects.insert(object);
|
||||
|
||||
break;
|
||||
case VISITOR_CLEAR:
|
||||
// remove visit info from all heroes, including those that are not present on map
|
||||
for (CGHeroInstance * hero : gs->map->allHeroes)
|
||||
{
|
||||
if (hero)
|
||||
{
|
||||
hero->visitedObjects.erase(object); // remove visit info from all heroes, including those that are not present on map
|
||||
}
|
||||
}
|
||||
hero->visitedObjects.erase(object);
|
||||
|
||||
for(auto &elem : gs->players)
|
||||
{
|
||||
elem.second.visitedObjects.erase(object);
|
||||
}
|
||||
|
||||
for(auto &elem : gs->teams)
|
||||
elem.second.scoutedObjects.erase(object);
|
||||
|
||||
break;
|
||||
case VISITOR_SCOUTED:
|
||||
gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->scoutedObjects.insert(object);
|
||||
|
||||
break;
|
||||
case VISITOR_GLOBAL:
|
||||
@ -1069,9 +1069,6 @@ void ChangeObjectVisitors::applyGs(CGameState *gs)
|
||||
gs->getPlayerState(gs->getHero(hero)->tempOwner)->visitedObjectsGlobal.insert({objectPtr->ID, objectPtr->subID});
|
||||
break;
|
||||
}
|
||||
case VISITOR_REMOVE:
|
||||
gs->getHero(hero)->visitedObjects.erase(object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1216,11 +1216,11 @@ struct DLL_LINKAGE ChangeObjectVisitors : public CPackForClient
|
||||
{
|
||||
enum VisitMode
|
||||
{
|
||||
VISITOR_ADD, // mark hero as one that have visited this object
|
||||
VISITOR_ADD_TEAM, // mark team as one that have visited this object
|
||||
VISITOR_GLOBAL, // mark player as one that have visited object of this type
|
||||
VISITOR_REMOVE, // unmark visitor, reversed to ADD
|
||||
VISITOR_CLEAR // clear all visitors from this object (object reset)
|
||||
VISITOR_ADD_HERO, // mark hero as one that have visited this object
|
||||
VISITOR_ADD_PLAYER, // mark player as one that have visited this object instance
|
||||
VISITOR_GLOBAL, // mark player as one that have visited object of this type
|
||||
VISITOR_SCOUTED, // marks targeted team as having scouted this object
|
||||
VISITOR_CLEAR, // clear all visitors from this object (object reset)
|
||||
};
|
||||
VisitMode mode = VISITOR_CLEAR; // uses VisitMode enum
|
||||
ObjectInstanceID object;
|
||||
|
@ -59,6 +59,7 @@ enum class ESerializationVersion : int32_t
|
||||
CHRONICLES_SUPPORT, // 860 - support for heroes chronicles
|
||||
PER_MAP_GAME_SETTINGS, // 861 - game settings are now stored per-map
|
||||
CAMPAIGN_OUTRO_SUPPORT, // 862 - support for campaign outro video
|
||||
REWARDABLE_BANKS, // 863 - team state contains list of scouted objects, coast visitable rewardable objects
|
||||
|
||||
CURRENT = CAMPAIGN_OUTRO_SUPPORT
|
||||
CURRENT = REWARDABLE_BANKS
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user