2024-09-04 16:32:36 +02:00
|
|
|
/*
|
|
|
|
* VisitQueries.cpp, part of VCMI engine
|
|
|
|
*
|
|
|
|
* Authors: listed in file AUTHORS in main folder
|
|
|
|
*
|
|
|
|
* License: GNU General Public License v2.0 or later
|
|
|
|
* Full text of license available in license.txt file, in main folder
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include "StdInc.h"
|
|
|
|
#include "VisitQueries.h"
|
|
|
|
|
|
|
|
#include "../../lib/mapObjects/CGHeroInstance.h"
|
2024-09-15 22:09:06 +02:00
|
|
|
#include "../../lib/mapObjects/CGTownInstance.h"
|
|
|
|
#include "../../lib/mapObjects/TownBuildingInstance.h"
|
2024-09-04 16:54:09 +02:00
|
|
|
#include "../CGameHandler.h"
|
|
|
|
#include "QueriesProcessor.h"
|
2024-09-04 16:32:36 +02:00
|
|
|
|
2024-09-04 16:54:09 +02:00
|
|
|
VisitQuery::VisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero)
|
|
|
|
: CQuery(owner)
|
|
|
|
, visitedObject(Obj)
|
|
|
|
, visitingHero(Hero)
|
2024-09-04 16:32:36 +02:00
|
|
|
{
|
|
|
|
addPlayer(Hero->tempOwner);
|
|
|
|
}
|
|
|
|
|
2024-09-04 16:54:09 +02:00
|
|
|
bool VisitQuery::blocksPack(const CPack * pack) const
|
2024-09-04 16:32:36 +02:00
|
|
|
{
|
|
|
|
//During the visit itself ALL actions are blocked.
|
|
|
|
//(However, the visit may trigger a query above that'll pass some.)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-09-15 22:09:06 +02:00
|
|
|
void MapObjectVisitQuery::onExposure(QueryPtr topQuery)
|
2024-09-04 16:54:09 +02:00
|
|
|
{
|
|
|
|
//Object may have been removed and deleted.
|
|
|
|
if(gh->isValidObject(visitedObject))
|
|
|
|
topQuery->notifyObjectAboutRemoval(visitedObject, visitingHero);
|
|
|
|
|
|
|
|
owner->popIfTop(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
MapObjectVisitQuery::MapObjectVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero)
|
|
|
|
: VisitQuery(owner, Obj, Hero)
|
|
|
|
, removeObjectAfterVisit(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapObjectVisitQuery::onRemoval(PlayerColor color)
|
2024-09-04 16:32:36 +02:00
|
|
|
{
|
2024-09-04 16:54:09 +02:00
|
|
|
gh->objectVisitEnded(visitingHero, players.front());
|
2024-09-04 16:32:36 +02:00
|
|
|
|
|
|
|
//TODO or should it be destructor?
|
|
|
|
//Can object visit affect 2 players and what would be desired behavior?
|
|
|
|
if(removeObjectAfterVisit)
|
|
|
|
gh->removeObject(visitedObject, color);
|
|
|
|
}
|
|
|
|
|
2024-09-15 22:09:06 +02:00
|
|
|
TownBuildingVisitQuery::TownBuildingVisitQuery(CGameHandler * owner, const CGTownInstance * Obj, std::vector<const CGHeroInstance *> heroes, std::vector<BuildingID> buildingToVisit)
|
|
|
|
: VisitQuery(owner, Obj, heroes.front())
|
|
|
|
, visitedTown(Obj)
|
|
|
|
{
|
|
|
|
// generate in reverse order - first building-hero pair to handle must be in the end of vector
|
|
|
|
for (auto const * hero : boost::adaptors::reverse(heroes))
|
|
|
|
for (auto const & building : boost::adaptors::reverse(buildingToVisit))
|
|
|
|
visitedBuilding.push_back({ hero, building});
|
|
|
|
}
|
|
|
|
|
|
|
|
void TownBuildingVisitQuery::onExposure(QueryPtr topQuery)
|
2024-09-04 16:54:09 +02:00
|
|
|
{
|
2024-09-23 15:00:02 +02:00
|
|
|
topQuery->notifyObjectAboutRemoval(visitedObject, visitingHero);
|
|
|
|
|
2024-09-15 22:09:06 +02:00
|
|
|
onAdded(players.front());
|
2024-09-04 16:54:09 +02:00
|
|
|
}
|
|
|
|
|
2024-09-15 22:09:06 +02:00
|
|
|
void TownBuildingVisitQuery::onAdded(PlayerColor color)
|
2024-09-04 16:32:36 +02:00
|
|
|
{
|
2024-09-15 22:09:06 +02:00
|
|
|
while (!visitedBuilding.empty() && owner->topQuery(color).get() == this)
|
|
|
|
{
|
|
|
|
visitingHero = visitedBuilding.back().hero;
|
|
|
|
auto * building = visitedTown->rewardableBuildings.at(visitedBuilding.back().building);
|
|
|
|
building->onHeroVisit(visitingHero);
|
|
|
|
visitedBuilding.pop_back();
|
|
|
|
}
|
2024-09-04 16:32:36 +02:00
|
|
|
|
2024-09-15 22:09:06 +02:00
|
|
|
if (visitedBuilding.empty() && owner->topQuery(color).get() == this)
|
|
|
|
owner->popIfTop(*this);
|
2024-09-04 16:32:36 +02:00
|
|
|
}
|