mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Split map object visit from town building visit. Removes side effects
from building visit
This commit is contained in:
parent
81af66d35b
commit
d34b4a141e
@ -179,7 +179,6 @@
|
|||||||
"period" : 7,
|
"period" : 7,
|
||||||
"visitors" : true
|
"visitors" : true
|
||||||
},
|
},
|
||||||
"visitMode" : "hero", // Should be 'once' to match (somewhat buggy) H3 logic
|
|
||||||
"visitMode" : "once",
|
"visitMode" : "once",
|
||||||
"rewards" : [
|
"rewards" : [
|
||||||
{
|
{
|
||||||
|
@ -2178,8 +2178,7 @@ bool CGameHandler::visitTownBuilding(ObjectInstanceID tid, BuildingID bid)
|
|||||||
|
|
||||||
if (hero && t->town->buildings.at(bid)->manualHeroVisit)
|
if (hero && t->town->buildings.at(bid)->manualHeroVisit)
|
||||||
{
|
{
|
||||||
// FIXME: query might produce unintended side effects, double check
|
auto visitQuery = std::make_shared<TownBuildingVisitQuery>(this, t, hero, bid);
|
||||||
auto visitQuery = std::make_shared<CObjectVisitQuery>(this, t, hero);
|
|
||||||
queries->addQuery(visitQuery);
|
queries->addQuery(visitQuery);
|
||||||
building->onHeroVisit(hero);
|
building->onHeroVisit(hero);
|
||||||
queries->popIfTop(visitQuery);
|
queries->popIfTop(visitQuery);
|
||||||
@ -3208,7 +3207,7 @@ void CGameHandler::objectVisited(const CGObjectInstance * obj, const CGHeroInsta
|
|||||||
throw std::runtime_error("Can not visit object that is being visited");
|
throw std::runtime_error("Can not visit object that is being visited");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CObjectVisitQuery> visitQuery;
|
std::shared_ptr<MapObjectVisitQuery> visitQuery;
|
||||||
|
|
||||||
auto startVisit = [&](ObjectVisitStarted & event)
|
auto startVisit = [&](ObjectVisitStarted & event)
|
||||||
{
|
{
|
||||||
@ -3227,7 +3226,7 @@ void CGameHandler::objectVisited(const CGObjectInstance * obj, const CGHeroInsta
|
|||||||
visitedObject = visitedTown;
|
visitedObject = visitedTown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visitQuery = std::make_shared<CObjectVisitQuery>(this, visitedObject, h);
|
visitQuery = std::make_shared<MapObjectVisitQuery>(this, visitedObject, h);
|
||||||
queries->addQuery(visitQuery); //TODO real visit pos
|
queries->addQuery(visitQuery); //TODO real visit pos
|
||||||
|
|
||||||
HeroVisit hv;
|
HeroVisit hv;
|
||||||
@ -3246,11 +3245,11 @@ void CGameHandler::objectVisited(const CGObjectInstance * obj, const CGHeroInsta
|
|||||||
queries->popIfTop(visitQuery); //visit ends here if no queries were created
|
queries->popIfTop(visitQuery); //visit ends here if no queries were created
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::objectVisitEnded(const CObjectVisitQuery & query)
|
void CGameHandler::objectVisitEnded(const CGHeroInstance *h, PlayerColor player)
|
||||||
{
|
{
|
||||||
using events::ObjectVisitEnded;
|
using events::ObjectVisitEnded;
|
||||||
|
|
||||||
logGlobal->debug("%s visit ends.\n", query.visitingHero->nodeName());
|
logGlobal->debug("%s visit ends.\n", h->nodeName());
|
||||||
|
|
||||||
auto endVisit = [&](ObjectVisitEnded & event)
|
auto endVisit = [&](ObjectVisitEnded & event)
|
||||||
{
|
{
|
||||||
@ -3263,7 +3262,7 @@ void CGameHandler::objectVisitEnded(const CObjectVisitQuery & query)
|
|||||||
|
|
||||||
//TODO: ObjectVisitEnded should also have id of visited object,
|
//TODO: ObjectVisitEnded should also have id of visited object,
|
||||||
//but this requires object being deleted only by `removeAfterVisit()` but not `removeObject()`
|
//but this requires object being deleted only by `removeAfterVisit()` but not `removeObject()`
|
||||||
ObjectVisitEnded::defaultExecute(serverEventBus.get(), endVisit, query.players.front(), query.visitingHero->id);
|
ObjectVisitEnded::defaultExecute(serverEventBus.get(), endVisit, player, h->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameHandler::buildBoat(ObjectInstanceID objid, PlayerColor playerID)
|
bool CGameHandler::buildBoat(ObjectInstanceID objid, PlayerColor playerID)
|
||||||
@ -3874,7 +3873,7 @@ void CGameHandler::removeAfterVisit(const CGObjectInstance *object)
|
|||||||
//If the object is being visited, there must be a matching query
|
//If the object is being visited, there must be a matching query
|
||||||
for (const auto &query : queries->allQueries())
|
for (const auto &query : queries->allQueries())
|
||||||
{
|
{
|
||||||
if (auto someVistQuery = std::dynamic_pointer_cast<CObjectVisitQuery>(query))
|
if (auto someVistQuery = std::dynamic_pointer_cast<MapObjectVisitQuery>(query))
|
||||||
{
|
{
|
||||||
if (someVistQuery->visitedObject == object)
|
if (someVistQuery->visitedObject == object)
|
||||||
{
|
{
|
||||||
@ -3938,7 +3937,7 @@ const CGHeroInstance * CGameHandler::getVisitingHero(const CGObjectInstance *obj
|
|||||||
|
|
||||||
for(const auto & query : queries->allQueries())
|
for(const auto & query : queries->allQueries())
|
||||||
{
|
{
|
||||||
auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(query);
|
auto visit = std::dynamic_pointer_cast<const VisitQuery>(query);
|
||||||
if (visit && visit->visitedObject == obj)
|
if (visit && visit->visitedObject == obj)
|
||||||
return visit->visitingHero;
|
return visit->visitingHero;
|
||||||
}
|
}
|
||||||
@ -3951,7 +3950,7 @@ const CGObjectInstance * CGameHandler::getVisitingObject(const CGHeroInstance *h
|
|||||||
|
|
||||||
for(const auto & query : queries->allQueries())
|
for(const auto & query : queries->allQueries())
|
||||||
{
|
{
|
||||||
auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(query);
|
auto visit = std::dynamic_pointer_cast<const VisitQuery>(query);
|
||||||
if (visit && visit->visitingHero == hero)
|
if (visit && visit->visitingHero == hero)
|
||||||
return visit->visitedObject;
|
return visit->visitedObject;
|
||||||
}
|
}
|
||||||
@ -3968,7 +3967,7 @@ bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, con
|
|||||||
// visitation query is covered by other query that must be answered first
|
// 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 VisitQuery>(topQuery))
|
||||||
return !(visit->visitedObject == obj && visit->visitingHero == hero);
|
return !(visit->visitedObject == obj && visit->visitingHero == hero);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -232,7 +232,7 @@ public:
|
|||||||
|
|
||||||
bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
|
bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
|
||||||
void objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h );
|
void objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h );
|
||||||
void objectVisitEnded(const CObjectVisitQuery &query);
|
void objectVisitEnded(const CGHeroInstance *h, PlayerColor player);
|
||||||
bool dig(const CGHeroInstance *h);
|
bool dig(const CGHeroInstance *h);
|
||||||
void moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging);
|
void moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging);
|
||||||
|
|
||||||
|
@ -10,34 +10,26 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "VisitQueries.h"
|
#include "VisitQueries.h"
|
||||||
|
|
||||||
#include "QueriesProcessor.h"
|
|
||||||
#include "../CGameHandler.h"
|
|
||||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||||
|
#include "../CGameHandler.h"
|
||||||
|
#include "QueriesProcessor.h"
|
||||||
|
|
||||||
CObjectVisitQuery::CObjectVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero):
|
VisitQuery::VisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero)
|
||||||
CQuery(owner), visitedObject(Obj), visitingHero(Hero), removeObjectAfterVisit(false)
|
: CQuery(owner)
|
||||||
|
, visitedObject(Obj)
|
||||||
|
, visitingHero(Hero)
|
||||||
{
|
{
|
||||||
addPlayer(Hero->tempOwner);
|
addPlayer(Hero->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CObjectVisitQuery::blocksPack(const CPack *pack) const
|
bool VisitQuery::blocksPack(const CPack * pack) const
|
||||||
{
|
{
|
||||||
//During the visit itself ALL actions are blocked.
|
//During the visit itself ALL actions are blocked.
|
||||||
//(However, the visit may trigger a query above that'll pass some.)
|
//(However, the visit may trigger a query above that'll pass some.)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObjectVisitQuery::onRemoval(PlayerColor color)
|
void VisitQuery::onExposure(QueryPtr topQuery)
|
||||||
{
|
|
||||||
gh->objectVisitEnded(*this);
|
|
||||||
|
|
||||||
//TODO or should it be destructor?
|
|
||||||
//Can object visit affect 2 players and what would be desired behavior?
|
|
||||||
if(removeObjectAfterVisit)
|
|
||||||
gh->removeObject(visitedObject, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CObjectVisitQuery::onExposure(QueryPtr topQuery)
|
|
||||||
{
|
{
|
||||||
//Object may have been removed and deleted.
|
//Object may have been removed and deleted.
|
||||||
if(gh->isValidObject(visitedObject))
|
if(gh->isValidObject(visitedObject))
|
||||||
@ -45,3 +37,30 @@ void CObjectVisitQuery::onExposure(QueryPtr topQuery)
|
|||||||
|
|
||||||
owner->popIfTop(*this);
|
owner->popIfTop(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapObjectVisitQuery::MapObjectVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero)
|
||||||
|
: VisitQuery(owner, Obj, Hero)
|
||||||
|
, removeObjectAfterVisit(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapObjectVisitQuery::onRemoval(PlayerColor color)
|
||||||
|
{
|
||||||
|
gh->objectVisitEnded(visitingHero, players.front());
|
||||||
|
|
||||||
|
//TODO or should it be destructor?
|
||||||
|
//Can object visit affect 2 players and what would be desired behavior?
|
||||||
|
if(removeObjectAfterVisit)
|
||||||
|
gh->removeObject(visitedObject, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
TownBuildingVisitQuery::TownBuildingVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero, BuildingID buildingToVisit)
|
||||||
|
: VisitQuery(owner, Obj, Hero)
|
||||||
|
, visitedBuilding(buildingToVisit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TownBuildingVisitQuery::onRemoval(PlayerColor color)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -13,17 +13,35 @@
|
|||||||
|
|
||||||
//Created when hero visits object.
|
//Created when hero visits object.
|
||||||
//Removed when query above is resolved (or immediately after visit if no queries were created)
|
//Removed when query above is resolved (or immediately after visit if no queries were created)
|
||||||
class CObjectVisitQuery : public CQuery
|
class VisitQuery : public CQuery
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
VisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const CGObjectInstance *visitedObject;
|
const CGObjectInstance *visitedObject;
|
||||||
const CGHeroInstance *visitingHero;
|
const CGHeroInstance *visitingHero;
|
||||||
|
|
||||||
|
bool blocksPack(const CPack *pack) const final;
|
||||||
|
void onExposure(QueryPtr topQuery) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MapObjectVisitQuery final : public VisitQuery
|
||||||
|
{
|
||||||
|
public:
|
||||||
bool removeObjectAfterVisit;
|
bool removeObjectAfterVisit;
|
||||||
|
|
||||||
CObjectVisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero);
|
MapObjectVisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero);
|
||||||
|
|
||||||
bool blocksPack(const CPack *pack) const override;
|
void onRemoval(PlayerColor color) final;
|
||||||
void onRemoval(PlayerColor color) override;
|
};
|
||||||
void onExposure(QueryPtr topQuery) override;
|
|
||||||
|
class TownBuildingVisitQuery final : public VisitQuery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BuildingID visitedBuilding;
|
||||||
|
|
||||||
|
TownBuildingVisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero, BuildingID buildingToVisit);
|
||||||
|
|
||||||
|
void onRemoval(PlayerColor color) final;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user