mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Add proper visitation checks for netpacks
This commit is contained in:
@@ -2418,6 +2418,7 @@ bool CGameHandler::recruitCreatures(ObjectInstanceID objid, ObjectInstanceID dst
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
COMPLAIN_RET_FALSE_IF(isVisitActiveForHero(dwelling, hero), "Cannot recruit: can only recruit by visiting hero!");
|
||||||
COMPLAIN_RET_FALSE_IF(!hero || hero->getOwner() != player, "Cannot recruit: can only recruit to owned hero!");
|
COMPLAIN_RET_FALSE_IF(!hero || hero->getOwner() != player, "Cannot recruit: can only recruit to owned hero!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4084,8 +4085,46 @@ void CGameHandler::changeFogOfWar(std::unordered_set<int3> &tiles, PlayerColor p
|
|||||||
sendAndApply(&fow);
|
sendAndApply(&fow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGameHandler::isVisitActiveForAny(const CGObjectInstance *obj)
|
||||||
|
{
|
||||||
|
for (auto const & query : queries->allQueries())
|
||||||
|
{
|
||||||
|
auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(query);
|
||||||
|
if (visit && visit->visitedObject == obj)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGameHandler::isVisitActiveForPlayer(const CGObjectInstance *obj, PlayerColor player)
|
||||||
|
{
|
||||||
|
for (auto const & query : queries->allQueries())
|
||||||
|
{
|
||||||
|
auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(query);
|
||||||
|
if (visit && visit->visitedObject == obj && visit->visitingHero->getOwner() == player)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGameHandler::isVisitActiveForHero(const CGObjectInstance *obj, const CGHeroInstance *hero)
|
||||||
|
{
|
||||||
|
for (auto const & query : queries->allQueries())
|
||||||
|
{
|
||||||
|
auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(query);
|
||||||
|
if (visit && visit->visitedObject == obj && visit->visitingHero == hero)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero)
|
bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero)
|
||||||
{
|
{
|
||||||
|
assert(isVisitActiveForHero(obj, hero));
|
||||||
|
// Check top query of targeted player:
|
||||||
|
// If top query is NOT visit to targeted object then we assume that
|
||||||
|
// visitation query is covered by other query that must be answered first
|
||||||
|
|
||||||
if (auto topQuery = queries->topQuery(hero->getOwner()))
|
if (auto topQuery = queries->topQuery(hero->getOwner()))
|
||||||
if (auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(topQuery))
|
if (auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(topQuery))
|
||||||
return !(visit->visitedObject == obj && visit->visitingHero == hero);
|
return !(visit->visitedObject == obj && visit->visitingHero == hero);
|
||||||
|
@@ -153,6 +153,9 @@ public:
|
|||||||
|
|
||||||
void castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) override;
|
void castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) override;
|
||||||
|
|
||||||
|
bool isVisitActiveForAny(const CGObjectInstance *obj);
|
||||||
|
bool isVisitActiveForPlayer(const CGObjectInstance *obj, PlayerColor player);
|
||||||
|
bool isVisitActiveForHero(const CGObjectInstance *obj, const CGHeroInstance *hero);
|
||||||
bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) override;
|
bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) override;
|
||||||
void setObjProperty(ObjectInstanceID objid, int prop, si64 val) override;
|
void setObjProperty(ObjectInstanceID objid, int prop, si64 val) override;
|
||||||
void showInfoDialog(InfoWindow * iw) override;
|
void showInfoDialog(InfoWindow * iw) override;
|
||||||
|
@@ -174,6 +174,9 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
|
|||||||
|
|
||||||
if(mapObject->ID == Obj::TAVERN)
|
if(mapObject->ID == Obj::TAVERN)
|
||||||
{
|
{
|
||||||
|
if (!gameHandler->isVisitActiveForPlayer(mapObject, player) && gameHandler->complain("Can't buy hero in tavern you are not visiting!"))
|
||||||
|
return false;
|
||||||
|
|
||||||
if(gameHandler->getTile(mapObject->visitablePos())->visitableObjects.back() != mapObject && gameHandler->complain("Tavern entry must be unoccupied!"))
|
if(gameHandler->getTile(mapObject->visitablePos())->visitableObjects.back() != mapObject && gameHandler->complain("Tavern entry must be unoccupied!"))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user