From a65befaa083692b5f77999e8f62f7cfe700864ca Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Mon, 3 Jul 2017 21:09:27 +0300 Subject: [PATCH] Moved town portal logic to mechanics class --- client/CPlayerInterface.cpp | 4 +- client/windows/CSpellWindow.cpp | 66 --------- client/windows/GUIClasses.cpp | 20 +++ client/windows/GUIClasses.h | 5 + lib/spells/AdventureSpellMechanics.cpp | 181 +++++++++++++++++++------ lib/spells/AdventureSpellMechanics.h | 8 +- lib/spells/CSpellHandler.cpp | 2 +- lib/spells/CSpellHandler.h | 2 +- lib/spells/ISpellMechanics.h | 8 +- server/CGameHandler.cpp | 16 ++- server/CQuery.cpp | 57 ++------ server/CQuery.h | 32 +---- server/NetPacksServer.cpp | 10 +- 13 files changed, 212 insertions(+), 199 deletions(-) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 66fadefff..6f57114d8 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1208,8 +1208,6 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component cb->sendQueryReply(reply, askID); }; - CComponent * localIcon = new CComponent(icon); - const std::string localTitle = title.toString(); const std::string localDescription = description.toString(); @@ -1219,7 +1217,7 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component for(auto item : objects) tempList.push_back(item.getNum()); - CObjectListWindow * wnd = new CObjectListWindow(tempList, localIcon, localTitle, localDescription, selectCallback); + CObjectListWindow * wnd = new CObjectListWindow(tempList, icon, localTitle, localDescription, selectCallback); wnd->onExit = cancelCallback; GH.pushInt(wnd); } diff --git a/client/windows/CSpellWindow.cpp b/client/windows/CSpellWindow.cpp index 89461a0fa..3ddea1708 100644 --- a/client/windows/CSpellWindow.cpp +++ b/client/windows/CSpellWindow.cpp @@ -641,78 +641,12 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState) delete owner; }); - if(mySpell->id == SpellID::TOWN_PORTAL) - { - //special case - //todo: move to mechanics - - std::vector Towns = owner->myInt->cb->getTownsInfo(false); - - vstd::erase_if(Towns, [this](const CGTownInstance * t) - { - const auto relations = owner->myInt->cb->getPlayerRelations(t->tempOwner, owner->myInt->playerID); - return relations == PlayerRelations::ENEMIES; - }); - - if (Towns.empty()) - { - owner->myInt->showInfoDialog(CGI->generaltexth->allTexts[124]); - return; - } - - const int movementCost = (h->getSpellSchoolLevel(mySpell) >= 3) ? 200 : 300; - - if(h->movement < movementCost) - { - owner->myInt->showInfoDialog(CGI->generaltexth->allTexts[125]); - return; - } - - if (h->getSpellSchoolLevel(mySpell) < 2) //not advanced or expert - teleport to nearest available city - { - owner->myInt->cb->castSpell(h, mySpell->id, int3());// - town->getVisitableOffset()); - } - else - { //let the player choose - std::vector availableTowns; - for(auto & Town : Towns) - { - const CGTownInstance *t = Town; - if (t->visitingHero == nullptr) //empty town and this is - { - availableTowns.push_back(t->id.getNum());//add to the list - } - } - - auto castTownPortal = [h](int townId) - { - const CGTownInstance * dest = LOCPLINT->cb->getTown(ObjectInstanceID(townId)); - LOCPLINT->cb->castSpell(h, SpellID::TOWN_PORTAL, dest->visitablePos()); - }; - - if (availableTowns.empty()) - owner->myInt->showInfoDialog(CGI->generaltexth->allTexts[124]); - else - GH.pushInt (new CObjectListWindow(availableTowns, - new CAnimImage("SPELLSCR",mySpell->id), - CGI->generaltexth->jktexts[40], CGI->generaltexth->jktexts[41], - castTownPortal)); - } - return; - } - if(mySpell->getTargetType() == CSpell::LOCATION) - { adventureInt->enterCastingMode(mySpell); - } else if(mySpell->getTargetType() == CSpell::NO_TARGET) - { owner->myInt->cb->castSpell(h, mySpell->id); - } else - { logGlobal->error("Invalid spell target type"); - } } } } diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 23ee97b9c..40ee6e7aa 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -1744,6 +1744,26 @@ CObjectListWindow::CObjectListWindow(const std::vector &_items, CIntObject init(titlePic, _title, _descr); } +CObjectListWindow::CObjectListWindow(const std::vector &_items, const Component & titlePic, std::string _title, std::string _descr, + std::function Callback): + CWindowObject(PLAYER_COLORED, "TPGATE"), + onSelect(Callback), + selected(0) +{ + items.reserve(_items.size()); + for(int id : _items) + { + items.push_back(std::make_pair(id, CGI->mh->map->objects[id]->getObjectName())); + } + + OBJ_CONSTRUCTION_CAPTURING_ALL; + + CComponent * icon = new CComponent(titlePic); + + init(icon, _title, _descr); +} + + CObjectListWindow::CObjectListWindow(const std::vector &_items, CIntObject * titlePic, std::string _title, std::string _descr, std::function Callback): CWindowObject(PLAYER_COLORED, "TPGATE"), diff --git a/client/windows/GUIClasses.h b/client/windows/GUIClasses.h index 21715626b..fffdbbfa0 100644 --- a/client/windows/GUIClasses.h +++ b/client/windows/GUIClasses.h @@ -33,6 +33,7 @@ class CToggleButton; class CToggleGroup; class CVolumeSlider; class CGStatusBar; +struct Component; /// Recruitment window where you can recruit creatures class CRecruitmentWindow : public CWindowObject @@ -177,6 +178,10 @@ public: ///item names will be taken from map objects CObjectListWindow(const std::vector &_items, CIntObject * titlePic, std::string _title, std::string _descr, std::function Callback); + + CObjectListWindow(const std::vector &_items, const Component & titlePic, std::string _title, std::string _descr, + std::function Callback); + CObjectListWindow(const std::vector &_items, CIntObject * titlePic, std::string _title, std::string _descr, std::function Callback); diff --git a/lib/spells/AdventureSpellMechanics.cpp b/lib/spells/AdventureSpellMechanics.cpp index 1bd9036b8..6888bbef1 100644 --- a/lib/spells/AdventureSpellMechanics.cpp +++ b/lib/spells/AdventureSpellMechanics.cpp @@ -25,7 +25,7 @@ AdventureSpellMechanics::AdventureSpellMechanics(const CSpell * s): { } -bool AdventureSpellMechanics::adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const +bool AdventureSpellMechanics::adventureCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const { if(!owner->isAdventureSpell()) { @@ -55,29 +55,12 @@ bool AdventureSpellMechanics::adventureCast(const SpellCastEnvironment * env, Ad return false; } - { - AdvmapSpellCast asc; - asc.caster = caster; - asc.spellID = owner->id; - env->sendAndApply(&asc); - } + ESpellCastResult result = beginCast(env, parameters); - switch(applyAdventureEffects(env, parameters)) - { - case ESpellCastResult::OK: - { - SetMana sm; - sm.hid = caster->id; - sm.absolute = false; - sm.val = -cost; - env->sendAndApply(&sm); - return true; - } - break; - case ESpellCastResult::CANCEL: - return true; - } - return false; + if(result == ESpellCastResult::OK) + performCast(env, parameters); + + return result != ESpellCastResult::ERROR; } ESpellCastResult AdventureSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const @@ -109,6 +92,42 @@ ESpellCastResult AdventureSpellMechanics::applyAdventureEffects(const SpellCastE } } +ESpellCastResult AdventureSpellMechanics::beginCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const +{ + return ESpellCastResult::OK; +} + +void AdventureSpellMechanics::performCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const +{ + AdvmapSpellCast asc; + asc.caster = parameters.caster; + asc.spellID = owner->id; + env->sendAndApply(&asc); + + ESpellCastResult result = applyAdventureEffects(env, parameters); + endCast(env, parameters, result); +} + +void AdventureSpellMechanics::endCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const ESpellCastResult result) const +{ + const int cost = parameters.caster->getSpellCost(owner); + + switch(result) + { + case ESpellCastResult::OK: + { + SetMana sm; + sm.hid = parameters.caster->id; + sm.absolute = false; + sm.val = -cost; + env->sendAndApply(&sm); + } + break; + default: + break; + } +} + ///SummonBoatMechanics SummonBoatMechanics::SummonBoatMechanics(const CSpell * s): AdventureSpellMechanics(s) @@ -308,7 +327,7 @@ TownPortalMechanics::TownPortalMechanics(const CSpell * s): ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const { const CGTownInstance * destination = nullptr; - const int movementCost = GameConstants::BASE_MOVEMENT_COST * ((parameters.caster->getSpellSchoolLevel(owner) >= 3) ? 2 : 3); + const int moveCost = movementCost(parameters); if(parameters.caster->getSpellSchoolLevel(owner) < 2) { @@ -316,24 +335,12 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvir destination = findNearestTown(env, parameters, pool); if(nullptr == destination) - { - InfoWindow iw; - iw.player = parameters.caster->tempOwner; - iw.text.addTxt(MetaString::GENERAL_TXT, 124); - env->sendAndApply(&iw); - return ESpellCastResult::CANCEL; - } + return ESpellCastResult::ERROR; - if(parameters.caster->movement < movementCost) - { - InfoWindow iw; - iw.player = parameters.caster->tempOwner; - iw.text.addTxt(MetaString::GENERAL_TXT, 125); - env->sendAndApply(&iw); - return ESpellCastResult::CANCEL; - } + if(parameters.caster->movement < moveCost) + return ESpellCastResult::ERROR; - if (destination->visitingHero) + if(destination->visitingHero) { InfoWindow iw; iw.player = parameters.caster->tempOwner; @@ -367,7 +374,7 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvir return ESpellCastResult::ERROR; } - if(parameters.caster->movement < movementCost) + if(parameters.caster->movement < moveCost) { env->complain("This hero has not enough movement points!"); return ESpellCastResult::ERROR; @@ -385,16 +392,99 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvir return ESpellCastResult::ERROR; } - if(env->moveHero(parameters.caster->id, destination->visitablePos() + parameters.caster->getVisitableOffset(), 1)) + if(env->moveHero(parameters.caster->id, destination->visitablePos() + parameters.caster->getVisitableOffset(), true)) { SetMovePoints smp; smp.hid = parameters.caster->id; - smp.val = std::max(0, parameters.caster->movement - movementCost); + smp.val = std::max(0, parameters.caster->movement - moveCost); env->sendAndApply(&smp); } return ESpellCastResult::OK; } +ESpellCastResult TownPortalMechanics::beginCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const +{ + std::vector towns = getPossibleTowns(env, parameters); + + if(towns.empty()) + { + InfoWindow iw; + iw.player = parameters.caster->tempOwner; + iw.text.addTxt(MetaString::GENERAL_TXT, 124); + env->sendAndApply(&iw); + return ESpellCastResult::CANCEL; + } + + const int moveCost = movementCost(parameters); + + if(parameters.caster->movement < moveCost) + { + InfoWindow iw; + iw.player = parameters.caster->tempOwner; + iw.text.addTxt(MetaString::GENERAL_TXT, 125); + env->sendAndApply(&iw); + return ESpellCastResult::CANCEL; + } + + if(!parameters.pos.valid() && parameters.caster->getSpellSchoolLevel(owner) >= 2) + { + auto queryCallback = [=](const JsonNode & reply) -> void + { + if(reply.getType() == JsonNode::DATA_INTEGER) + { + ObjectInstanceID townId(reply.Integer()); + + const CGObjectInstance * o = env->getCb()->getObj(townId, true); + if(o == nullptr) + { + env->complain("Invalid object instance selected"); + return; + } + + if(!dynamic_cast(o)) + { + env->complain("Object instance is not town"); + return; + } + + AdventureSpellCastParameters p; + p.caster = parameters.caster; + p.pos = o->visitablePos(); + performCast(env, p); + } + }; + + MapObjectSelectDialog request; + + for(auto t : towns) + { + if (t->visitingHero == nullptr) //empty town + request.objects.push_back(t->id); + } + + if(request.objects.empty()) + { + InfoWindow iw; + iw.player = parameters.caster->tempOwner; + iw.text.addTxt(MetaString::GENERAL_TXT, 124); + env->sendAndApply(&iw); + return ESpellCastResult::CANCEL; + } + + request.player = parameters.caster->getOwner(); + request.title.addTxt(MetaString::JK_TXT, 40); + request.description.addTxt(MetaString::JK_TXT, 41); + request.icon.id = Component::SPELL; + request.icon.subtype = owner->id.toEnum(); + + env->genericQuery(&request, request.player, queryCallback); + + return ESpellCastResult::PENDING; + } + + return ESpellCastResult::OK; +} + const CGTownInstance * TownPortalMechanics::findNearestTown(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const std::vector & pool) const { if(pool.empty()) @@ -432,6 +522,11 @@ std::vector TownPortalMechanics::getPossibleTowns(const return ret; } +int TownPortalMechanics::movementCost(const AdventureSpellCastParameters & parameters) const +{ + return GameConstants::BASE_MOVEMENT_COST * ((parameters.caster->getSpellSchoolLevel(owner) >= 3) ? 2 : 3); +} + ///ViewMechanics ViewMechanics::ViewMechanics(const CSpell * s): AdventureSpellMechanics(s) diff --git a/lib/spells/AdventureSpellMechanics.h b/lib/spells/AdventureSpellMechanics.h index 75dd21243..186d3b120 100644 --- a/lib/spells/AdventureSpellMechanics.h +++ b/lib/spells/AdventureSpellMechanics.h @@ -18,6 +18,7 @@ enum class ESpellCastResult { OK, CANCEL,//cast failed but it is not an error + PENDING, ERROR//internal error occurred }; @@ -26,10 +27,13 @@ class DLL_LINKAGE AdventureSpellMechanics : public IAdventureSpellMechanics public: AdventureSpellMechanics(const CSpell * s); - bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override final; + bool adventureCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override final; protected: ///actual adventure cast implementation virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const; + virtual ESpellCastResult beginCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const; + void performCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const; + void endCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const ESpellCastResult result) const; }; class DLL_LINKAGE SummonBoatMechanics : public AdventureSpellMechanics @@ -62,8 +66,10 @@ public: TownPortalMechanics(const CSpell * s); protected: ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override; + ESpellCastResult beginCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override; private: const CGTownInstance * findNearestTown(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const std::vector & pool) const; + int movementCost(const AdventureSpellCastParameters & parameters) const; std::vector getPossibleTowns(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const; }; diff --git a/lib/spells/CSpellHandler.cpp b/lib/spells/CSpellHandler.cpp index fc76ca561..9144ac663 100644 --- a/lib/spells/CSpellHandler.cpp +++ b/lib/spells/CSpellHandler.cpp @@ -118,7 +118,7 @@ void CSpell::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) co mechanics->applyBattle(battle, packet); } -bool CSpell::adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const +bool CSpell::adventureCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const { assert(env); diff --git a/lib/spells/CSpellHandler.h b/lib/spells/CSpellHandler.h index 03fc8f26e..73f57392e 100644 --- a/lib/spells/CSpellHandler.h +++ b/lib/spells/CSpellHandler.h @@ -306,7 +306,7 @@ public: ///Server logic. Has write access to GameState via packets. ///May be executed on client side by (future) non-cheat-proof scripts. - bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const; + bool adventureCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const; void battleCast(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters) const; public: diff --git a/lib/spells/ISpellMechanics.h b/lib/spells/ISpellMechanics.h index 6120b9d8f..c139f525d 100644 --- a/lib/spells/ISpellMechanics.h +++ b/lib/spells/ISpellMechanics.h @@ -13,6 +13,8 @@ #include "CSpellHandler.h" #include "../battle/BattleHex.h" +struct Query; + ///callback to be provided by server class DLL_LINKAGE SpellCastEnvironment { @@ -26,7 +28,9 @@ public: virtual const CMap * getMap() const = 0; virtual const CGameInfoCallback * getCb() const = 0; - virtual bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const =0; //TODO: remove + virtual bool moveHero(ObjectInstanceID hid, int3 dst, bool teleporting) const = 0; //TODO: remove + + virtual void genericQuery(Query * request, PlayerColor color, std::function callback) const = 0;//TODO: type safety on query, use generic query packet when implemented }; ///all parameters of particular cast event @@ -140,7 +144,7 @@ public: IAdventureSpellMechanics(const CSpell * s); virtual ~IAdventureSpellMechanics() = default; - virtual bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const = 0; + virtual bool adventureCast(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const = 0; static std::unique_ptr createMechanics(const CSpell * s); protected: diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 6de80e18b..6c1a1cdc7 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -71,7 +71,8 @@ public: void complain(const std::string & problem) const override; const CMap * getMap() const override; const CGameInfoCallback * getCb() const override; - bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const override; + bool moveHero(ObjectInstanceID hid, int3 dst, bool teleporting) const override; + void genericQuery(Query * request, PlayerColor color, std::function callback) const override; private: mutable CGameHandler * gh; }; @@ -6516,13 +6517,20 @@ const CGameInfoCallback * ServerSpellCastEnvironment::getCb() const return gh; } - const CMap * ServerSpellCastEnvironment::getMap() const { return gh->gameState()->map; } -bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker) const +bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, bool teleporting) const { - return gh->moveHero(hid, dst, teleporting, false, asker); + return gh->moveHero(hid, dst, teleporting, false); +} + +void ServerSpellCastEnvironment::genericQuery(Query * request, PlayerColor color, std::function callback) const +{ + auto query = std::make_shared(&gh->queries, color, callback); + request->queryID = query->queryID; + gh->queries.addQuery(query); + gh->sendAndApply(request); } diff --git a/server/CQuery.cpp b/server/CQuery.cpp index f72991aa8..4972f3dca 100644 --- a/server/CQuery.cpp +++ b/server/CQuery.cpp @@ -3,7 +3,6 @@ #include "CGameHandler.h" #include "../lib/battle/BattleInfo.h" #include "../lib/mapObjects/MiscObjects.h" -#include "../lib/spells/ISpellMechanics.h" boost::mutex Queries::mx; @@ -86,6 +85,7 @@ void CQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) cons void CQuery::onExposure(QueryPtr topQuery) { + logGlobal->trace("Exposed query with id %d", queryID); owner->popQuery(*this); } @@ -472,66 +472,29 @@ void CHeroMovementQuery::onAdding(PlayerColor color) gh->sendAndApply(&pb); } -CMapObjectSelectQuery::CMapObjectSelectQuery(Queries * Owner): - CQuery(Owner) +CGenericQuery::CGenericQuery(Queries * Owner, PlayerColor color, std::function Callback): + CQuery(Owner), callback(Callback) { - + addPlayer(color); } -bool CMapObjectSelectQuery::blocksPack(const CPack * pack) const +bool CGenericQuery::blocksPack(const CPack * pack) const { return blockAllButReply(pack); } -bool CMapObjectSelectQuery::endsByPlayerAnswer() const +bool CGenericQuery::endsByPlayerAnswer() const { return true; } -void CMapObjectSelectQuery::setReply(const JsonNode & reply) +void CGenericQuery::onExposure(QueryPtr topQuery) { - //TODO: + //do nothing } -CSpellQuery::CSpellQuery(Queries * Owner, const SpellCastEnvironment * SpellEnv): - CQuery(Owner), spellEnv(SpellEnv) +void CGenericQuery::setReply(const JsonNode & reply) { - -} - -AdventureSpellCastQuery::AdventureSpellCastQuery(Queries * Owner, const SpellCastEnvironment * SpellEnv, const CSpell * Spell, const CGHeroInstance * Caster, const int3 & Position): - CSpellQuery(Owner, SpellEnv), spell(Spell), caster(Caster), position(Position), requiresPositions(false) -{ - assert(owner); - assert(spellEnv); - assert(spell); - assert(caster); - - addPlayer(caster->getOwner()); -} - -bool AdventureSpellCastQuery::blocksPack(const CPack * pack) const -{ - return true; -} - -void AdventureSpellCastQuery::onAdded(PlayerColor color) -{ - //TODO: destination select request - -} - -void AdventureSpellCastQuery::onExposure(QueryPtr topQuery) -{ - CQuery::onExposure(topQuery); -} - -void AdventureSpellCastQuery::onRemoval(PlayerColor color) -{ - AdventureSpellCastParameters p; - p.caster = caster; - p.pos = position; - - spell->adventureCast(spellEnv, p); + callback(reply); } diff --git a/server/CQuery.h b/server/CQuery.h index 9bd7b3bbe..90cc7e858 100644 --- a/server/CQuery.h +++ b/server/CQuery.h @@ -175,39 +175,17 @@ public: CommanderLevelUp clu; }; -class CMapObjectSelectQuery : public CQuery +class CGenericQuery : public CQuery { public: - CMapObjectSelectQuery(Queries * Owner); + CGenericQuery(Queries * Owner, PlayerColor color, std::function Callback); bool blocksPack(const CPack * pack) const override; bool endsByPlayerAnswer() const override; - void setReply(const JsonNode & reply) override; -}; - -class CSpellQuery : public CQuery -{ -public: - CSpellQuery(Queries * Owner, const SpellCastEnvironment * SpellEnv); -protected: - const SpellCastEnvironment * spellEnv; -}; - -class AdventureSpellCastQuery : public CSpellQuery -{ -public: - AdventureSpellCastQuery(Queries * Owner, const SpellCastEnvironment * SpellEnv, const CSpell * Spell, const CGHeroInstance * Caster, const int3 & Position); - - bool blocksPack(const CPack * pack) const override; - - void onAdded(PlayerColor color) override; void onExposure(QueryPtr topQuery) override; - void onRemoval(PlayerColor color) override; - - const CSpell * spell; - const CGHeroInstance * caster; - int3 position; - bool requiresPositions; + void setReply(const JsonNode & reply) override; +private: + std::function callback; }; class Queries diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index 40df1c33e..279f56c52 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -9,6 +9,8 @@ #include "../lib/battle/BattleInfo.h" #include "../lib/battle/BattleAction.h" #include "../lib/serializer/Connection.h" +#include "../lib/spells/CSpellHandler.h" +#include "../lib/spells/ISpellMechanics.h" #define PLAYER_OWNS(id) (gh->getPlayerAt(c)==gh->getOwner(id)) @@ -286,11 +288,11 @@ bool CastAdvSpell::applyGh(CGameHandler * gh) if(!h) ERROR_AND_RETURN; - auto query = std::make_shared(&gh->queries, gh->spellEnv, s, h, pos); + AdventureSpellCastParameters p; + p.caster = h; + p.pos = pos; - gh->queries.addQuery(query); - gh->queries.popIfTop(query);//if we already can perform cast do it now - return true; + return s->adventureCast(gh->spellEnv, p); } bool PlayerMessage::applyGh( CGameHandler *gh )