mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-03 13:01:33 +02:00
Wait for queries generated by town building visit to end before visiting
next building
This commit is contained in:
parent
1d7a89c79b
commit
bff2e064fc
@ -1171,7 +1171,6 @@ void CGameHandler::heroVisitCastle(const CGTownInstance * obj, const CGHeroInsta
|
||||
sendAndApply(&vc);
|
||||
}
|
||||
visitCastleObjects(obj, hero);
|
||||
giveSpells (obj, hero);
|
||||
|
||||
if (obj->visitingHero && obj->garrisonHero)
|
||||
useScholarSkill(obj->visitingHero->id, obj->garrisonHero->id);
|
||||
@ -1180,10 +1179,27 @@ void CGameHandler::heroVisitCastle(const CGTownInstance * obj, const CGHeroInsta
|
||||
|
||||
void CGameHandler::visitCastleObjects(const CGTownInstance * t, const CGHeroInstance * h)
|
||||
{
|
||||
std::vector<const CGHeroInstance * > visitors;
|
||||
visitors.push_back(h);
|
||||
visitCastleObjects(t, visitors);
|
||||
}
|
||||
|
||||
void CGameHandler::visitCastleObjects(const CGTownInstance * t, std::vector<const CGHeroInstance * > visitors)
|
||||
{
|
||||
std::vector<BuildingID> buildingsToVisit;
|
||||
for (auto const & hero : visitors)
|
||||
giveSpells (t, hero);
|
||||
|
||||
for (auto & building : t->rewardableBuildings)
|
||||
{
|
||||
if (!t->town->buildings.at(building.first)->manualHeroVisit)
|
||||
building.second->onHeroVisit(h);
|
||||
buildingsToVisit.push_back(building.first);
|
||||
}
|
||||
|
||||
if (!buildingsToVisit.empty())
|
||||
{
|
||||
auto visitQuery = std::make_shared<TownBuildingVisitQuery>(this, t, visitors, buildingsToVisit);
|
||||
queries->addQuery(visitQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2144,10 +2160,15 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
||||
|
||||
if (!force)
|
||||
{
|
||||
if(t->garrisonHero) //garrison hero first - consistent with original H3 Mana Vortex and Battle Scholar Academy levelup windows order
|
||||
objectVisited(t, t->garrisonHero);
|
||||
if(t->visitingHero)
|
||||
objectVisited(t, t->visitingHero);
|
||||
//garrison hero first - consistent with original H3 Mana Vortex and Battle Scholar Academy levelup windows order
|
||||
std::vector<const CGHeroInstance *> visitors;
|
||||
if (t->garrisonHero)
|
||||
visitors.push_back(t->garrisonHero);
|
||||
if (t->visitingHero)
|
||||
visitors.push_back(t->visitingHero);
|
||||
|
||||
if (!visitors.empty())
|
||||
visitCastleObjects(t, visitors);
|
||||
}
|
||||
|
||||
checkVictoryLossConditionsForPlayer(t->tempOwner);
|
||||
@ -2173,19 +2194,15 @@ bool CGameHandler::visitTownBuilding(ObjectInstanceID tid, BuildingID bid)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t->rewardableBuildings.count(bid))
|
||||
if (t->rewardableBuildings.count(bid) && t->visitingHero && t->town->buildings.at(bid)->manualHeroVisit)
|
||||
{
|
||||
auto & hero = t->visitingHero;
|
||||
auto * building = t->rewardableBuildings.at(bid);
|
||||
|
||||
if (hero && t->town->buildings.at(bid)->manualHeroVisit)
|
||||
{
|
||||
auto visitQuery = std::make_shared<TownBuildingVisitQuery>(this, t, hero, bid);
|
||||
queries->addQuery(visitQuery);
|
||||
building->onHeroVisit(hero);
|
||||
queries->popIfTop(visitQuery);
|
||||
return true;
|
||||
}
|
||||
std::vector<BuildingID> buildingsToVisit;
|
||||
std::vector<const CGHeroInstance*> visitors;
|
||||
buildingsToVisit.push_back(bid);
|
||||
visitors.push_back(t->visitingHero);
|
||||
auto visitQuery = std::make_shared<TownBuildingVisitQuery>(this, t, visitors, buildingsToVisit);
|
||||
queries->addQuery(visitQuery);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -182,6 +182,7 @@ public:
|
||||
void visitObjectOnTile(const TerrainTile &t, const CGHeroInstance * h);
|
||||
bool teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui8 source, PlayerColor asker = PlayerColor::NEUTRAL);
|
||||
void visitCastleObjects(const CGTownInstance * obj, const CGHeroInstance * hero) override;
|
||||
void visitCastleObjects(const CGTownInstance * obj, std::vector<const CGHeroInstance * > visitors);
|
||||
void levelUpHero(const CGHeroInstance * hero, SecondarySkill skill);//handle client respond and send one more request if needed
|
||||
void levelUpHero(const CGHeroInstance * hero);//initial call - check if hero have remaining levelups & handle them
|
||||
void levelUpCommander (const CCommanderInstance * c, int skill); //secondary skill 1 to 6, special skill : skill - 100
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "VisitQueries.h"
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
#include "../../lib/mapObjects/TownBuildingInstance.h"
|
||||
#include "../CGameHandler.h"
|
||||
#include "QueriesProcessor.h"
|
||||
|
||||
@ -29,7 +31,7 @@ bool VisitQuery::blocksPack(const CPack * pack) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void VisitQuery::onExposure(QueryPtr topQuery)
|
||||
void MapObjectVisitQuery::onExposure(QueryPtr topQuery)
|
||||
{
|
||||
//Object may have been removed and deleted.
|
||||
if(gh->isValidObject(visitedObject))
|
||||
@ -54,13 +56,31 @@ void MapObjectVisitQuery::onRemoval(PlayerColor color)
|
||||
gh->removeObject(visitedObject, color);
|
||||
}
|
||||
|
||||
TownBuildingVisitQuery::TownBuildingVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero, BuildingID buildingToVisit)
|
||||
: VisitQuery(owner, Obj, Hero)
|
||||
, visitedBuilding(buildingToVisit)
|
||||
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::onRemoval(PlayerColor color)
|
||||
void TownBuildingVisitQuery::onExposure(QueryPtr topQuery)
|
||||
{
|
||||
|
||||
onAdded(players.front());
|
||||
}
|
||||
|
||||
void TownBuildingVisitQuery::onAdded(PlayerColor color)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
if (visitedBuilding.empty() && owner->topQuery(color).get() == this)
|
||||
owner->popIfTop(*this);
|
||||
}
|
||||
|
@ -11,19 +11,22 @@
|
||||
|
||||
#include "CQuery.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
class CGTownInstance;
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
//Created when hero visits object.
|
||||
//Removed when query above is resolved (or immediately after visit if no queries were created)
|
||||
class VisitQuery : public CQuery
|
||||
{
|
||||
protected:
|
||||
VisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero);
|
||||
VisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero);
|
||||
|
||||
public:
|
||||
const CGObjectInstance *visitedObject;
|
||||
const CGHeroInstance *visitingHero;
|
||||
const CGObjectInstance * visitedObject;
|
||||
const CGHeroInstance * visitingHero;
|
||||
|
||||
bool blocksPack(const CPack *pack) const final;
|
||||
void onExposure(QueryPtr topQuery) final;
|
||||
bool blocksPack(const CPack * pack) const final;
|
||||
};
|
||||
|
||||
class MapObjectVisitQuery final : public VisitQuery
|
||||
@ -31,17 +34,26 @@ class MapObjectVisitQuery final : public VisitQuery
|
||||
public:
|
||||
bool removeObjectAfterVisit;
|
||||
|
||||
MapObjectVisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero);
|
||||
MapObjectVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero);
|
||||
|
||||
void onRemoval(PlayerColor color) final;
|
||||
void onExposure(QueryPtr topQuery) final;
|
||||
};
|
||||
|
||||
class TownBuildingVisitQuery final : public VisitQuery
|
||||
{
|
||||
struct BuildingVisit
|
||||
{
|
||||
const CGHeroInstance * hero;
|
||||
BuildingID building;
|
||||
};
|
||||
|
||||
const CGTownInstance * visitedTown;
|
||||
std::vector<BuildingVisit> visitedBuilding;
|
||||
|
||||
public:
|
||||
BuildingID visitedBuilding;
|
||||
TownBuildingVisitQuery(CGameHandler * owner, const CGTownInstance * Obj, std::vector<const CGHeroInstance *> heroes, std::vector<BuildingID> buildingToVisit);
|
||||
|
||||
TownBuildingVisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero, BuildingID buildingToVisit);
|
||||
|
||||
void onRemoval(PlayerColor color) final;
|
||||
void onAdded(PlayerColor color) final;
|
||||
void onExposure(QueryPtr topQuery) final;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user