mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Queries refactoring
* Moved SUMMON_BOAT special case to mechanics * Partially moved Town portal logic to mechanics class * Added generic query reply to CCallback * Redesigned Queries so that base API do not depends on CGameHandler * Got rid of CGameHandler::castSpellRequest * Removed CGameHandler::castSpell * Added new Query type for town portal dialog (not used yet)
This commit is contained in:
parent
f463dc2fa3
commit
3d1a84875e
@ -38,3 +38,8 @@ void CEmptyAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance
|
|||||||
{
|
{
|
||||||
cb->selectionMade(0, queryID);
|
cb->selectionMade(0, queryID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEmptyAI::showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects)
|
||||||
|
{
|
||||||
|
cb->selectionMade(0, askID);
|
||||||
|
}
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override;
|
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override;
|
||||||
void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
||||||
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override;
|
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override;
|
||||||
|
void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NAME "EmptyAI 0.1"
|
#define NAME "EmptyAI 0.1"
|
||||||
|
@ -701,6 +701,14 @@ void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *do
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VCAI::showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects)
|
||||||
|
{
|
||||||
|
status.addQuery(askID, "Map object select query");
|
||||||
|
requestActionASAP([=]{ answerQuery(askID, 0); });
|
||||||
|
|
||||||
|
//TODO: Town portal destination selection goes here
|
||||||
|
}
|
||||||
|
|
||||||
void VCAI::saveGame(BinarySerializer & h, const int version)
|
void VCAI::saveGame(BinarySerializer & h, const int version)
|
||||||
{
|
{
|
||||||
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
||||||
|
@ -194,6 +194,7 @@ public:
|
|||||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||||
virtual void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
virtual void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
||||||
|
void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects) override;
|
||||||
virtual void saveGame(BinarySerializer & h, const int version) override; //saving
|
virtual void saveGame(BinarySerializer & h, const int version) override; //saving
|
||||||
virtual void loadGame(BinaryDeserializer & h, const int version) override; //loading
|
virtual void loadGame(BinaryDeserializer & h, const int version) override; //loading
|
||||||
virtual void finish() override;
|
virtual void finish() override;
|
||||||
|
@ -45,15 +45,22 @@ bool CCallback::moveHero(const CGHeroInstance *h, int3 dst, bool transit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int CCallback::selectionMade(int selection, QueryID queryID)
|
int CCallback::selectionMade(int selection, QueryID queryID)
|
||||||
|
{
|
||||||
|
JsonNode reply(JsonNode::DATA_INTEGER);
|
||||||
|
reply.Integer() = selection;
|
||||||
|
return sendQueryReply(reply, queryID);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CCallback::sendQueryReply(const JsonNode & reply, QueryID queryID)
|
||||||
{
|
{
|
||||||
ASSERT_IF_CALLED_WITH_PLAYER
|
ASSERT_IF_CALLED_WITH_PLAYER
|
||||||
if(queryID == QueryID(-1))
|
if(queryID == QueryID(-1))
|
||||||
{
|
{
|
||||||
logGlobal->errorStream() << "Cannot answer the query -1!";
|
logGlobal->errorStream() << "Cannot answer the query -1!";
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryReply pack(queryID,selection);
|
QueryReply pack(queryID,reply);
|
||||||
pack.player = *player;
|
pack.player = *player;
|
||||||
return sendRequest(&pack);
|
return sendRequest(&pack);
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
virtual void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
|
virtual void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
|
||||||
|
|
||||||
virtual int selectionMade(int selection, QueryID queryID) =0;
|
virtual int selectionMade(int selection, QueryID queryID) =0;
|
||||||
|
virtual int sendQueryReply(const JsonNode & reply, QueryID queryID) =0;
|
||||||
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
|
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||||
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//joins first stack to the second (creatures must be same type)
|
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2)=0;//joins first stack to the second (creatures must be same type)
|
||||||
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) =0; //first goes to the second
|
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) =0; //first goes to the second
|
||||||
@ -121,6 +122,7 @@ public:
|
|||||||
bool moveHero(const CGHeroInstance *h, int3 dst, bool transit = false) override; //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
bool moveHero(const CGHeroInstance *h, int3 dst, bool transit = false) override; //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||||
bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where);
|
bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where);
|
||||||
int selectionMade(int selection, QueryID queryID) override;
|
int selectionMade(int selection, QueryID queryID) override;
|
||||||
|
int sendQueryReply(const JsonNode & reply, QueryID queryID) override;
|
||||||
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) override;
|
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) override;
|
||||||
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) override; //first goes to the second
|
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) override; //first goes to the second
|
||||||
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) override; //first goes to the second
|
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2) override; //first goes to the second
|
||||||
|
@ -1191,6 +1191,39 @@ void CPlayerInterface::showTeleportDialog(TeleportChannelID channel, TTeleportEx
|
|||||||
cb->selectionMade(choosenExit, askID);
|
cb->selectionMade(choosenExit, askID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects)
|
||||||
|
{
|
||||||
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
|
|
||||||
|
auto selectCallback = [=](int selection)
|
||||||
|
{
|
||||||
|
JsonNode reply(JsonNode::DATA_INTEGER);
|
||||||
|
reply.Integer() = selection;
|
||||||
|
cb->sendQueryReply(reply, askID);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto cancelCallback = [=]()
|
||||||
|
{
|
||||||
|
JsonNode reply(JsonNode::DATA_NULL);
|
||||||
|
cb->sendQueryReply(reply, askID);
|
||||||
|
};
|
||||||
|
|
||||||
|
CComponent * localIcon = new CComponent(icon);
|
||||||
|
|
||||||
|
const std::string localTitle = title.toString();
|
||||||
|
const std::string localDescription = description.toString();
|
||||||
|
|
||||||
|
std::vector<int> tempList;
|
||||||
|
tempList.reserve(objects.size());
|
||||||
|
|
||||||
|
for(auto item : objects)
|
||||||
|
tempList.push_back(item.getNum());
|
||||||
|
|
||||||
|
CObjectListWindow * wnd = new CObjectListWindow(tempList, localIcon, localTitle, localDescription, selectCallback);
|
||||||
|
wnd->onExit = cancelCallback;
|
||||||
|
GH.pushInt(wnd);
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayerInterface::tileRevealed(const std::unordered_set<int3, ShashInt3> &pos)
|
void CPlayerInterface::tileRevealed(const std::unordered_set<int3, ShashInt3> &pos)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
|
@ -166,6 +166,7 @@ public:
|
|||||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||||
void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
||||||
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override;
|
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override;
|
||||||
|
void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects) override;
|
||||||
void showPuzzleMap() override;
|
void showPuzzleMap() override;
|
||||||
void viewWorldMap() override;
|
void viewWorldMap() override;
|
||||||
void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) override;
|
void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) override;
|
||||||
|
@ -592,6 +592,11 @@ void TeleportDialog::applyCl(CClient *cl)
|
|||||||
CALL_ONLY_THAT_INTERFACE(hero->tempOwner,showTeleportDialog,channel,exits,impassable,queryID);
|
CALL_ONLY_THAT_INTERFACE(hero->tempOwner,showTeleportDialog,channel,exits,impassable,queryID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapObjectSelectDialog::applyCl(CClient * cl)
|
||||||
|
{
|
||||||
|
CALL_ONLY_THAT_INTERFACE(player, showMapObjectSelectDialog, queryID, icon, title, description, objects);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleStart::applyFirstCl(CClient *cl)
|
void BattleStart::applyFirstCl(CClient *cl)
|
||||||
{
|
{
|
||||||
//Cannot use the usual macro because curB is not set yet
|
//Cannot use the usual macro because curB is not set yet
|
||||||
|
@ -646,7 +646,6 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
|||||||
//special case
|
//special case
|
||||||
//todo: move to mechanics
|
//todo: move to mechanics
|
||||||
|
|
||||||
std::vector <int> availableTowns;
|
|
||||||
std::vector <const CGTownInstance*> Towns = owner->myInt->cb->getTownsInfo(false);
|
std::vector <const CGTownInstance*> Towns = owner->myInt->cb->getTownsInfo(false);
|
||||||
|
|
||||||
vstd::erase_if(Towns, [this](const CGTownInstance * t)
|
vstd::erase_if(Towns, [this](const CGTownInstance * t)
|
||||||
@ -671,31 +670,11 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
|||||||
|
|
||||||
if (h->getSpellSchoolLevel(mySpell) < 2) //not advanced or expert - teleport to nearest available city
|
if (h->getSpellSchoolLevel(mySpell) < 2) //not advanced or expert - teleport to nearest available city
|
||||||
{
|
{
|
||||||
auto nearest = Towns.cbegin(); //nearest town's iterator
|
owner->myInt->cb->castSpell(h, mySpell->id, int3());// - town->getVisitableOffset());
|
||||||
si32 dist = owner->myInt->cb->getTown((*nearest)->id)->pos.dist2dSQ(h->pos);
|
|
||||||
|
|
||||||
for (auto i = nearest + 1; i != Towns.cend(); ++i)
|
|
||||||
{
|
|
||||||
const CGTownInstance * dest = owner->myInt->cb->getTown((*i)->id);
|
|
||||||
si32 curDist = dest->pos.dist2dSQ(h->pos);
|
|
||||||
|
|
||||||
if (curDist < dist)
|
|
||||||
{
|
|
||||||
nearest = i;
|
|
||||||
dist = curDist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*nearest)->visitingHero)
|
|
||||||
owner->myInt->showInfoDialog(CGI->generaltexth->allTexts[123]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const CGTownInstance * town = owner->myInt->cb->getTown((*nearest)->id);
|
|
||||||
owner->myInt->cb->castSpell(h, mySpell->id, town->visitablePos());// - town->getVisitableOffset());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //let the player choose
|
{ //let the player choose
|
||||||
|
std::vector <int> availableTowns;
|
||||||
for(auto & Town : Towns)
|
for(auto & Town : Towns)
|
||||||
{
|
{
|
||||||
const CGTownInstance *t = Town;
|
const CGTownInstance *t = Town;
|
||||||
@ -722,18 +701,6 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mySpell->id == SpellID::SUMMON_BOAT)
|
|
||||||
{
|
|
||||||
//special case
|
|
||||||
//todo: move to mechanics
|
|
||||||
int3 pos = h->bestLocation();
|
|
||||||
if(pos.x < 0)
|
|
||||||
{
|
|
||||||
owner->myInt->showInfoDialog(CGI->generaltexth->allTexts[334]); //There is no place to put the boat.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mySpell->getTargetType() == CSpell::LOCATION)
|
if(mySpell->getTargetType() == CSpell::LOCATION)
|
||||||
{
|
{
|
||||||
adventureInt->enterCastingMode(mySpell);
|
adventureInt->enterCastingMode(mySpell);
|
||||||
|
@ -1767,7 +1767,7 @@ void CObjectListWindow::init(CIntObject * titlePic, std::string _title, std::str
|
|||||||
|
|
||||||
ok = new CButton(Point(15, 402), "IOKAY.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::elementSelected, this), SDLK_RETURN);
|
ok = new CButton(Point(15, 402), "IOKAY.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::elementSelected, this), SDLK_RETURN);
|
||||||
ok->block(true);
|
ok->block(true);
|
||||||
exit = new CButton( Point(228, 402), "ICANCEL.DEF", CButton::tooltip(), std::bind(&CGuiHandler::popIntTotally,&GH, this), SDLK_ESCAPE);
|
exit = new CButton( Point(228, 402), "ICANCEL.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::exitPressed, this), SDLK_ESCAPE);
|
||||||
|
|
||||||
if (titlePic)
|
if (titlePic)
|
||||||
{
|
{
|
||||||
@ -1796,6 +1796,14 @@ void CObjectListWindow::elementSelected()
|
|||||||
toCall(where);//and send selected object
|
toCall(where);//and send selected object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CObjectListWindow::exitPressed()
|
||||||
|
{
|
||||||
|
std::function<void()> toCall = onExit;//save
|
||||||
|
GH.popIntTotally(this);//then destroy window
|
||||||
|
if(toCall)
|
||||||
|
toCall();
|
||||||
|
}
|
||||||
|
|
||||||
void CObjectListWindow::changeSelection(size_t which)
|
void CObjectListWindow::changeSelection(size_t which)
|
||||||
{
|
{
|
||||||
ok->block(false);
|
ok->block(false);
|
||||||
|
@ -166,8 +166,12 @@ class CObjectListWindow : public CWindowObject
|
|||||||
std::vector< std::pair<int, std::string> > items;//all items present in list
|
std::vector< std::pair<int, std::string> > items;//all items present in list
|
||||||
|
|
||||||
void init(CIntObject * titlePic, std::string _title, std::string _descr);
|
void init(CIntObject * titlePic, std::string _title, std::string _descr);
|
||||||
|
void exitPressed();
|
||||||
public:
|
public:
|
||||||
size_t selected;//index of currently selected item
|
size_t selected;//index of currently selected item
|
||||||
|
|
||||||
|
std::function<void()> onExit;//optional exit callback
|
||||||
|
|
||||||
/// Callback will be called when OK button is pressed, returns id of selected item. initState = initially selected item
|
/// Callback will be called when OK button is pressed, returns id of selected item. initState = initially selected item
|
||||||
/// Image can be nullptr
|
/// Image can be nullptr
|
||||||
///item names will be taken from map objects
|
///item names will be taken from map objects
|
||||||
|
@ -98,6 +98,7 @@ public:
|
|||||||
// all stacks operations between these objects become allowed, interface has to call onEnd when done
|
// all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) = 0;
|
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) = 0;
|
||||||
virtual void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) = 0;
|
virtual void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) = 0;
|
||||||
|
virtual void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects) = 0;
|
||||||
virtual void finish(){}; //if for some reason we want to end
|
virtual void finish(){}; //if for some reason we want to end
|
||||||
|
|
||||||
virtual void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions){};
|
virtual void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions){};
|
||||||
|
@ -146,6 +146,9 @@ void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst
|
|||||||
case COLOR:
|
case COLOR:
|
||||||
vec = &VLC->generaltexth->capColors;
|
vec = &VLC->generaltexth->capColors;
|
||||||
break;
|
break;
|
||||||
|
case JK_TXT:
|
||||||
|
vec = &VLC->generaltexth->jktexts;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
logGlobal->errorStream() << "Failed string substitution because type is " << type;
|
logGlobal->errorStream() << "Failed string substitution because type is " << type;
|
||||||
dst = "#@#";
|
dst = "#@#";
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "NetPacksBase.h"
|
#include "NetPacksBase.h"
|
||||||
|
|
||||||
#include "battle/BattleAction.h"
|
#include "battle/BattleAction.h"
|
||||||
|
#include "JsonNode.h"
|
||||||
#include "mapObjects/CGHeroInstance.h"
|
#include "mapObjects/CGHeroInstance.h"
|
||||||
#include "ConstTransitivePtr.h"
|
#include "ConstTransitivePtr.h"
|
||||||
#include "int3.h"
|
#include "int3.h"
|
||||||
@ -1141,12 +1142,6 @@ struct BlockingDialog : public Query
|
|||||||
soundID = 0;
|
soundID = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void addResourceComponents(TResources resources)
|
|
||||||
{
|
|
||||||
for(TResources::nziterator i(resources); i.valid(); i++)
|
|
||||||
components.push_back(Component(Component::RESOURCE, i->resType, i->resVal, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & queryID & text & components & player & flags & soundID;
|
h & queryID & text & components & player & flags & soundID;
|
||||||
@ -1205,6 +1200,24 @@ struct TeleportDialog : public Query
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MapObjectSelectDialog : public Query
|
||||||
|
{
|
||||||
|
PlayerColor player;
|
||||||
|
Component icon;
|
||||||
|
MetaString title;
|
||||||
|
MetaString description;
|
||||||
|
std::vector<ObjectInstanceID> objects;
|
||||||
|
|
||||||
|
MapObjectSelectDialog(){};
|
||||||
|
|
||||||
|
void applyCl(CClient * cl);
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler & h, const int version)
|
||||||
|
{
|
||||||
|
h & queryID & player & icon & title & description & objects;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct BattleInfo;
|
struct BattleInfo;
|
||||||
struct BattleStart : public CPackForClient
|
struct BattleStart : public CPackForClient
|
||||||
{
|
{
|
||||||
@ -2058,16 +2071,16 @@ struct BuildBoat : public CPackForServer
|
|||||||
|
|
||||||
struct QueryReply : public CPackForServer
|
struct QueryReply : public CPackForServer
|
||||||
{
|
{
|
||||||
QueryReply():answer(0){};
|
QueryReply(){};
|
||||||
QueryReply(QueryID QID, ui32 Answer):qid(QID),answer(Answer){};
|
QueryReply(QueryID QID, const JsonNode & Reply):qid(QID), reply(Reply){};
|
||||||
QueryID qid;
|
QueryID qid;
|
||||||
ui32 answer; //hero and artifact id
|
|
||||||
PlayerColor player;
|
PlayerColor player;
|
||||||
|
JsonNode reply;
|
||||||
|
|
||||||
bool applyGh(CGameHandler *gh);
|
bool applyGh(CGameHandler *gh);
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & qid & answer & player;
|
h & qid & player & reply;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,11 +44,11 @@ private:
|
|||||||
enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER, TREPLACE_PLUSNUMBER};
|
enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER, TREPLACE_PLUSNUMBER};
|
||||||
public:
|
public:
|
||||||
enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES,
|
enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES,
|
||||||
MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES, CREGENS4, COLOR, ART_DESCR};
|
MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES, CREGENS4, COLOR, ART_DESCR, JK_TXT};
|
||||||
|
|
||||||
std::vector<ui8> message; //vector of EMessage
|
std::vector<ui8> message; //vector of EMessage
|
||||||
|
|
||||||
std::vector<std::pair<ui8,ui32> > localStrings; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID]->first; 10 - objh->mines[ID]->second; 11 - objh->advobtxt
|
std::vector<std::pair<ui8,ui32> > localStrings;
|
||||||
std::vector<std::string> exactStrings;
|
std::vector<std::string> exactStrings;
|
||||||
std::vector<si32> numbers;
|
std::vector<si32> numbers;
|
||||||
|
|
||||||
|
@ -290,6 +290,7 @@ void registerTypesClientPacks2(Serializer &s)
|
|||||||
s.template registerType<Query, GarrisonDialog>();
|
s.template registerType<Query, GarrisonDialog>();
|
||||||
s.template registerType<Query, ExchangeDialog>();
|
s.template registerType<Query, ExchangeDialog>();
|
||||||
s.template registerType<Query, TeleportDialog>();
|
s.template registerType<Query, TeleportDialog>();
|
||||||
|
s.template registerType<Query, MapObjectSelectDialog>();
|
||||||
|
|
||||||
s.template registerType<CPackForClient, CGarrisonOperationPack>();
|
s.template registerType<CPackForClient, CGarrisonOperationPack>();
|
||||||
s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
|
s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
|
||||||
|
@ -20,6 +20,11 @@
|
|||||||
#include "../CPlayerState.h"
|
#include "../CPlayerState.h"
|
||||||
|
|
||||||
///AdventureSpellMechanics
|
///AdventureSpellMechanics
|
||||||
|
AdventureSpellMechanics::AdventureSpellMechanics(const CSpell * s):
|
||||||
|
IAdventureSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool AdventureSpellMechanics::adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
|
bool AdventureSpellMechanics::adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
if(!owner->isAdventureSpell())
|
if(!owner->isAdventureSpell())
|
||||||
@ -75,7 +80,7 @@ bool AdventureSpellMechanics::adventureCast(const SpellCastEnvironment * env, Ad
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastResult AdventureSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
|
ESpellCastResult AdventureSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
if(owner->hasEffects())
|
if(owner->hasEffects())
|
||||||
{
|
{
|
||||||
@ -105,9 +110,25 @@ ESpellCastResult AdventureSpellMechanics::applyAdventureEffects(const SpellCastE
|
|||||||
}
|
}
|
||||||
|
|
||||||
///SummonBoatMechanics
|
///SummonBoatMechanics
|
||||||
ESpellCastResult SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
|
SummonBoatMechanics::SummonBoatMechanics(const CSpell * s):
|
||||||
|
AdventureSpellMechanics(s)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ESpellCastResult SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
|
{
|
||||||
|
int3 summonPos = parameters.caster->bestLocation();
|
||||||
|
if(summonPos.x < 0)
|
||||||
|
{
|
||||||
|
InfoWindow iw;
|
||||||
|
iw.player = parameters.caster->tempOwner;
|
||||||
|
iw.text.addTxt(MetaString::GENERAL_TXT, 334);//There is no place to put the boat.
|
||||||
|
env->sendAndApply(&iw);
|
||||||
|
return ESpellCastResult::CANCEL;
|
||||||
|
}
|
||||||
|
|
||||||
const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
|
const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
|
||||||
|
|
||||||
//check if spell works at all
|
//check if spell works at all
|
||||||
if(env->getRandomGenerator().nextInt(99) >= owner->getPower(schoolLevel)) //power is % chance of success
|
if(env->getRandomGenerator().nextInt(99) >= owner->getPower(schoolLevel)) //power is % chance of success
|
||||||
{
|
{
|
||||||
@ -122,13 +143,6 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvir
|
|||||||
//try to find unoccupied boat to summon
|
//try to find unoccupied boat to summon
|
||||||
const CGBoat * nearest = nullptr;
|
const CGBoat * nearest = nullptr;
|
||||||
double dist = 0;
|
double dist = 0;
|
||||||
int3 summonPos = parameters.caster->bestLocation();
|
|
||||||
if(summonPos.x < 0)
|
|
||||||
{
|
|
||||||
env->complain("There is no water tile available!");
|
|
||||||
return ESpellCastResult::ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const CGObjectInstance * obj : env->getMap()->objects)
|
for(const CGObjectInstance * obj : env->getMap()->objects)
|
||||||
{
|
{
|
||||||
if(obj && obj->ID == Obj::BOAT)
|
if(obj && obj->ID == Obj::BOAT)
|
||||||
@ -150,7 +164,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvir
|
|||||||
{
|
{
|
||||||
ChangeObjPos cop;
|
ChangeObjPos cop;
|
||||||
cop.objid = nearest->id;
|
cop.objid = nearest->id;
|
||||||
cop.nPos = summonPos + int3(1,0,0);;
|
cop.nPos = summonPos + int3(1,0,0);
|
||||||
cop.flags = 1;
|
cop.flags = 1;
|
||||||
env->sendAndApply(&cop);
|
env->sendAndApply(&cop);
|
||||||
}
|
}
|
||||||
@ -166,14 +180,19 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvir
|
|||||||
NewObject no;
|
NewObject no;
|
||||||
no.ID = Obj::BOAT;
|
no.ID = Obj::BOAT;
|
||||||
no.subID = parameters.caster->getBoatType();
|
no.subID = parameters.caster->getBoatType();
|
||||||
no.pos = summonPos + int3(1,0,0);;
|
no.pos = summonPos + int3(1,0,0);
|
||||||
env->sendAndApply(&no);
|
env->sendAndApply(&no);
|
||||||
}
|
}
|
||||||
return ESpellCastResult::OK;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///ScuttleBoatMechanics
|
///ScuttleBoatMechanics
|
||||||
ESpellCastResult ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const
|
ScuttleBoatMechanics::ScuttleBoatMechanics(const CSpell * s):
|
||||||
|
AdventureSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ESpellCastResult ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
|
const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
|
||||||
//check if spell works at all
|
//check if spell works at all
|
||||||
@ -208,7 +227,12 @@ ESpellCastResult ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
///DimensionDoorMechanics
|
///DimensionDoorMechanics
|
||||||
ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const
|
DimensionDoorMechanics::DimensionDoorMechanics(const CSpell * s):
|
||||||
|
AdventureSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
if(!env->getMap()->isInTheMap(parameters.pos))
|
if(!env->getMap()->isInTheMap(parameters.pos))
|
||||||
{
|
{
|
||||||
@ -276,67 +300,92 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(const SpellCastEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
///TownPortalMechanics
|
///TownPortalMechanics
|
||||||
ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters& parameters) const
|
TownPortalMechanics::TownPortalMechanics(const CSpell * s):
|
||||||
|
AdventureSpellMechanics(s)
|
||||||
{
|
{
|
||||||
if (!env->getMap()->isInTheMap(parameters.pos))
|
}
|
||||||
{
|
|
||||||
env->complain("Destination tile not present!");
|
|
||||||
return ESpellCastResult::ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
TerrainTile tile = env->getMap()->getTile(parameters.pos);
|
ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
if (tile.visitableObjects.empty() || tile.visitableObjects.back()->ID != Obj::TOWN)
|
{
|
||||||
{
|
const CGTownInstance * destination = nullptr;
|
||||||
env->complain("Town not found for Town Portal!");
|
const int movementCost = GameConstants::BASE_MOVEMENT_COST * ((parameters.caster->getSpellSchoolLevel(owner) >= 3) ? 2 : 3);
|
||||||
return ESpellCastResult::ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGTownInstance * town = static_cast<CGTownInstance*>(tile.visitableObjects.back());
|
if(parameters.caster->getSpellSchoolLevel(owner) < 2)
|
||||||
|
{
|
||||||
|
std::vector <const CGTownInstance*> pool = getPossibleTowns(env, parameters);
|
||||||
|
destination = findNearestTown(env, parameters, pool);
|
||||||
|
|
||||||
const auto relations = env->getCb()->getPlayerRelations(town->tempOwner, parameters.caster->tempOwner);
|
if(nullptr == destination)
|
||||||
|
|
||||||
if(relations == PlayerRelations::ENEMIES)
|
|
||||||
{
|
|
||||||
env->complain("Can't teleport to enemy!");
|
|
||||||
return ESpellCastResult::ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (town->visitingHero)
|
|
||||||
{
|
|
||||||
env->complain("Can't teleport to occupied town!");
|
|
||||||
return ESpellCastResult::ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameters.caster->getSpellSchoolLevel(owner) < 2)
|
|
||||||
{
|
|
||||||
si32 dist = town->pos.dist2dSQ(parameters.caster->pos);
|
|
||||||
ObjectInstanceID nearest = town->id; //nearest town's ID
|
|
||||||
for(const CGTownInstance * currTown : env->getCb()->getPlayer(parameters.caster->tempOwner)->towns)
|
|
||||||
{
|
{
|
||||||
si32 currDist = currTown->pos.dist2dSQ(parameters.caster->pos);
|
InfoWindow iw;
|
||||||
if (currDist < dist)
|
iw.player = parameters.caster->tempOwner;
|
||||||
{
|
iw.text.addTxt(MetaString::GENERAL_TXT, 124);
|
||||||
nearest = currTown->id;
|
env->sendAndApply(&iw);
|
||||||
dist = currDist;
|
return ESpellCastResult::CANCEL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (town->id != nearest)
|
|
||||||
|
if(parameters.caster->movement < movementCost)
|
||||||
{
|
{
|
||||||
env->complain("This hero can only teleport to nearest town!");
|
InfoWindow iw;
|
||||||
|
iw.player = parameters.caster->tempOwner;
|
||||||
|
iw.text.addTxt(MetaString::GENERAL_TXT, 125);
|
||||||
|
env->sendAndApply(&iw);
|
||||||
|
return ESpellCastResult::CANCEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destination->visitingHero)
|
||||||
|
{
|
||||||
|
InfoWindow iw;
|
||||||
|
iw.player = parameters.caster->tempOwner;
|
||||||
|
iw.text.addTxt(MetaString::GENERAL_TXT, 123);
|
||||||
|
env->sendAndApply(&iw);
|
||||||
|
return ESpellCastResult::CANCEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(env->getMap()->isInTheMap(parameters.pos))
|
||||||
|
{
|
||||||
|
const TerrainTile & tile = env->getMap()->getTile(parameters.pos);
|
||||||
|
if(tile.visitableObjects.empty() || tile.visitableObjects.back()->ID != Obj::TOWN)
|
||||||
|
{
|
||||||
|
env->complain("No town at destination tile");
|
||||||
return ESpellCastResult::ERROR;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destination = dynamic_cast<CGTownInstance*>(tile.visitableObjects.back());
|
||||||
|
|
||||||
|
if(nullptr == destination)
|
||||||
|
{
|
||||||
|
env->complain("[Internal error] invalid town object");
|
||||||
|
return ESpellCastResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto relations = env->getCb()->getPlayerRelations(destination->tempOwner, parameters.caster->tempOwner);
|
||||||
|
|
||||||
|
if(relations == PlayerRelations::ENEMIES)
|
||||||
|
{
|
||||||
|
env->complain("Can't teleport to enemy!");
|
||||||
|
return ESpellCastResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(parameters.caster->movement < movementCost)
|
||||||
|
{
|
||||||
|
env->complain("This hero has not enough movement points!");
|
||||||
|
return ESpellCastResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(destination->visitingHero)
|
||||||
|
{
|
||||||
|
env->complain("Can't teleport to occupied town!");
|
||||||
|
return ESpellCastResult::ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
const int movementCost = GameConstants::BASE_MOVEMENT_COST * ((parameters.caster->getSpellSchoolLevel(owner) >= 3) ? 2 : 3);
|
|
||||||
|
|
||||||
if(parameters.caster->movement < movementCost)
|
|
||||||
{
|
{
|
||||||
env->complain("This hero has not enough movement points!");
|
env->complain("Invalid destination tile");
|
||||||
return ESpellCastResult::ERROR;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(env->moveHero(parameters.caster->id, town->visitablePos() + parameters.caster->getVisitableOffset() ,1))
|
if(env->moveHero(parameters.caster->id, destination->visitablePos() + parameters.caster->getVisitableOffset(), 1))
|
||||||
{
|
{
|
||||||
SetMovePoints smp;
|
SetMovePoints smp;
|
||||||
smp.hid = parameters.caster->id;
|
smp.hid = parameters.caster->id;
|
||||||
@ -346,7 +395,50 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvir
|
|||||||
return ESpellCastResult::OK;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastResult ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
|
const CGTownInstance * TownPortalMechanics::findNearestTown(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const std::vector <const CGTownInstance *> & pool) const
|
||||||
|
{
|
||||||
|
if(pool.empty())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto nearest = pool.cbegin(); //nearest town's iterator
|
||||||
|
si32 dist = (*nearest)->pos.dist2dSQ(parameters.caster->pos);
|
||||||
|
|
||||||
|
for (auto i = nearest + 1; i != pool.cend(); ++i)
|
||||||
|
{
|
||||||
|
si32 curDist = (*i)->pos.dist2dSQ(parameters.caster->pos);
|
||||||
|
|
||||||
|
if (curDist < dist)
|
||||||
|
{
|
||||||
|
nearest = i;
|
||||||
|
dist = curDist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *nearest;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <const CGTownInstance*> TownPortalMechanics::getPossibleTowns(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
|
{
|
||||||
|
std::vector <const CGTownInstance*> ret;
|
||||||
|
|
||||||
|
const TeamState * team = env->getCb()->getPlayerTeam(parameters.caster->getOwner());
|
||||||
|
|
||||||
|
for(const auto & color : team->players)
|
||||||
|
{
|
||||||
|
for(auto currTown : env->getCb()->getPlayer(color)->towns)
|
||||||
|
{
|
||||||
|
ret.push_back(currTown.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
///ViewMechanics
|
||||||
|
ViewMechanics::ViewMechanics(const CSpell * s):
|
||||||
|
AdventureSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ESpellCastResult ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
ShowWorldViewEx pack;
|
ShowWorldViewEx pack;
|
||||||
|
|
||||||
@ -373,13 +465,25 @@ ESpellCastResult ViewMechanics::applyAdventureEffects(const SpellCastEnvironment
|
|||||||
return ESpellCastResult::OK;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///ViewAirMechanics
|
||||||
|
ViewAirMechanics::ViewAirMechanics(const CSpell * s):
|
||||||
|
ViewMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
|
bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
|
||||||
{
|
{
|
||||||
return (obj->ID == Obj::ARTIFACT) || (spellLevel>1 && obj->ID == Obj::HERO) || (spellLevel>2 && obj->ID == Obj::TOWN);
|
return (obj->ID == Obj::ARTIFACT) || (spellLevel > 1 && obj->ID == Obj::HERO) || (spellLevel > 2 && obj->ID == Obj::TOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
///ViewEarthMechanics
|
||||||
|
ViewEarthMechanics::ViewEarthMechanics(const CSpell * s):
|
||||||
|
ViewMechanics(s)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViewEarthMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
|
bool ViewEarthMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
|
||||||
{
|
{
|
||||||
return (obj->ID == Obj::RESOURCE) || (spellLevel>1 && obj->ID == Obj::MINE);
|
return (obj->ID == Obj::RESOURCE) || (spellLevel > 1 && obj->ID == Obj::MINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include "ISpellMechanics.h"
|
#include "ISpellMechanics.h"
|
||||||
|
|
||||||
|
class CGTownInstance;
|
||||||
|
|
||||||
enum class ESpellCastResult
|
enum class ESpellCastResult
|
||||||
{
|
{
|
||||||
OK,
|
OK,
|
||||||
@ -19,62 +21,65 @@ enum class ESpellCastResult
|
|||||||
ERROR//internal error occurred
|
ERROR//internal error occurred
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE AdventureSpellMechanics: public IAdventureSpellMechanics
|
class DLL_LINKAGE AdventureSpellMechanics : public IAdventureSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AdventureSpellMechanics(CSpell * s): IAdventureSpellMechanics(s){};
|
AdventureSpellMechanics(const CSpell * s);
|
||||||
|
|
||||||
bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override final;
|
bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override final;
|
||||||
protected:
|
protected:
|
||||||
///actual adventure cast implementation
|
///actual adventure cast implementation
|
||||||
virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const;
|
virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE SummonBoatMechanics : public AdventureSpellMechanics
|
class DLL_LINKAGE SummonBoatMechanics : public AdventureSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SummonBoatMechanics(CSpell * s): AdventureSpellMechanics(s){};
|
SummonBoatMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
|
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE ScuttleBoatMechanics : public AdventureSpellMechanics
|
class DLL_LINKAGE ScuttleBoatMechanics : public AdventureSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScuttleBoatMechanics(CSpell * s): AdventureSpellMechanics(s){};
|
ScuttleBoatMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
|
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE DimensionDoorMechanics : public AdventureSpellMechanics
|
class DLL_LINKAGE DimensionDoorMechanics : public AdventureSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DimensionDoorMechanics(CSpell * s): AdventureSpellMechanics(s){};
|
DimensionDoorMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
|
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE TownPortalMechanics : public AdventureSpellMechanics
|
class DLL_LINKAGE TownPortalMechanics : public AdventureSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TownPortalMechanics(CSpell * s): AdventureSpellMechanics(s){};
|
TownPortalMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
|
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
|
||||||
|
private:
|
||||||
|
const CGTownInstance * findNearestTown(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const std::vector <const CGTownInstance*> & pool) const;
|
||||||
|
std::vector <const CGTownInstance*> getPossibleTowns(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE ViewMechanics : public AdventureSpellMechanics
|
class DLL_LINKAGE ViewMechanics : public AdventureSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewMechanics(CSpell * s): AdventureSpellMechanics(s){};
|
ViewMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
|
ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
|
||||||
virtual bool filterObject(const CGObjectInstance * obj, const int spellLevel) const = 0;
|
virtual bool filterObject(const CGObjectInstance * obj, const int spellLevel) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE ViewAirMechanics : public ViewMechanics
|
class DLL_LINKAGE ViewAirMechanics : public ViewMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewAirMechanics(CSpell * s): ViewMechanics(s){};
|
ViewAirMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;
|
bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;
|
||||||
};
|
};
|
||||||
@ -82,7 +87,7 @@ protected:
|
|||||||
class DLL_LINKAGE ViewEarthMechanics : public ViewMechanics
|
class DLL_LINKAGE ViewEarthMechanics : public ViewMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewEarthMechanics(CSpell * s): ViewMechanics(s){};
|
ViewEarthMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;
|
bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
#include "../mapObjects/CGTownInstance.h"
|
#include "../mapObjects/CGTownInstance.h"
|
||||||
|
|
||||||
///HealingSpellMechanics
|
///HealingSpellMechanics
|
||||||
|
HealingSpellMechanics::HealingSpellMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void HealingSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void HealingSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
EHealLevel healLevel = getHealLevel(parameters.effectLevel);
|
EHealLevel healLevel = getHealLevel(parameters.effectLevel);
|
||||||
@ -48,6 +53,11 @@ int HealingSpellMechanics::calculateHealedHP(const SpellCastEnvironment* env, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
///AntimagicMechanics
|
///AntimagicMechanics
|
||||||
|
AntimagicMechanics::AntimagicMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
{
|
{
|
||||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||||
@ -74,6 +84,11 @@ void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast
|
|||||||
}
|
}
|
||||||
|
|
||||||
///ChainLightningMechanics
|
///ChainLightningMechanics
|
||||||
|
ChainLightningMechanics::ChainLightningMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const CStack *> ChainLightningMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
std::vector<const CStack *> ChainLightningMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||||
{
|
{
|
||||||
std::vector<const CStack *> res;
|
std::vector<const CStack *> res;
|
||||||
@ -111,6 +126,11 @@ std::vector<const CStack *> ChainLightningMechanics::calculateAffectedStacks(con
|
|||||||
}
|
}
|
||||||
|
|
||||||
///CloneMechanics
|
///CloneMechanics
|
||||||
|
CloneMechanics::CloneMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
const CStack * clonedStack = nullptr;
|
const CStack * clonedStack = nullptr;
|
||||||
@ -180,10 +200,14 @@ ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const ISpel
|
|||||||
}
|
}
|
||||||
|
|
||||||
///CureMechanics
|
///CureMechanics
|
||||||
|
CureMechanics::CureMechanics(const CSpell * s):
|
||||||
|
HealingSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void CureMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
void CureMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
{
|
{
|
||||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||||
|
|
||||||
doDispell(battle, packet, dispellSelector);
|
doDispell(battle, packet, dispellSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +236,11 @@ ESpellCastProblem::ESpellCastProblem CureMechanics::isImmuneByStack(const ISpell
|
|||||||
}
|
}
|
||||||
|
|
||||||
///DispellMechanics
|
///DispellMechanics
|
||||||
|
DispellMechanics::DispellMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
{
|
{
|
||||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||||
@ -261,6 +290,11 @@ void DispellMechanics::applyBattleEffects(const SpellCastEnvironment * env, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
///EarthquakeMechanics
|
///EarthquakeMechanics
|
||||||
|
EarthquakeMechanics::EarthquakeMechanics(const CSpell * s):
|
||||||
|
SpecialSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void EarthquakeMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void EarthquakeMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
if(nullptr == parameters.cb->battleGetDefendedTown())
|
if(nullptr == parameters.cb->battleGetDefendedTown())
|
||||||
@ -391,6 +425,11 @@ bool EarthquakeMechanics::requiresCreatureTarget() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///HypnotizeMechanics
|
///HypnotizeMechanics
|
||||||
|
HypnotizeMechanics::HypnotizeMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
{
|
{
|
||||||
//todo: maybe do not resist on passive cast
|
//todo: maybe do not resist on passive cast
|
||||||
@ -407,6 +446,11 @@ ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const I
|
|||||||
}
|
}
|
||||||
|
|
||||||
///ObstacleMechanics
|
///ObstacleMechanics
|
||||||
|
ObstacleMechanics::ObstacleMechanics(const CSpell * s):
|
||||||
|
SpecialSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem ObstacleMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem ObstacleMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||||
{
|
{
|
||||||
const auto side = cb->playerToSide(ctx.caster->getOwner());
|
const auto side = cb->playerToSide(ctx.caster->getOwner());
|
||||||
@ -479,6 +523,11 @@ void ObstacleMechanics::placeObstacle(const SpellCastEnvironment * env, const Ba
|
|||||||
}
|
}
|
||||||
|
|
||||||
///PatchObstacleMechanics
|
///PatchObstacleMechanics
|
||||||
|
PatchObstacleMechanics::PatchObstacleMechanics(const CSpell * s):
|
||||||
|
ObstacleMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void PatchObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void PatchObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> availableTiles;
|
std::vector<BattleHex> availableTiles;
|
||||||
@ -498,6 +547,11 @@ void PatchObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env
|
|||||||
}
|
}
|
||||||
|
|
||||||
///LandMineMechanics
|
///LandMineMechanics
|
||||||
|
LandMineMechanics::LandMineMechanics(const CSpell * s):
|
||||||
|
PatchObstacleMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem LandMineMechanics::canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const
|
ESpellCastProblem::ESpellCastProblem LandMineMechanics::canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const
|
||||||
{
|
{
|
||||||
//LandMine are useless if enemy has native stack and can see mines, check for LandMine damage immunity is done in general way by CSpell
|
//LandMine are useless if enemy has native stack and can see mines, check for LandMine damage immunity is done in general way by CSpell
|
||||||
@ -526,6 +580,11 @@ void LandMineMechanics::setupObstacle(SpellCreatedObstacle * obstacle) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///QuicksandMechanics
|
///QuicksandMechanics
|
||||||
|
QuicksandMechanics::QuicksandMechanics(const CSpell * s):
|
||||||
|
PatchObstacleMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool QuicksandMechanics::requiresCreatureTarget() const
|
bool QuicksandMechanics::requiresCreatureTarget() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -539,6 +598,11 @@ void QuicksandMechanics::setupObstacle(SpellCreatedObstacle * obstacle) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///WallMechanics
|
///WallMechanics
|
||||||
|
WallMechanics::WallMechanics(const CSpell * s):
|
||||||
|
ObstacleMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<BattleHex> WallMechanics::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes) const
|
std::vector<BattleHex> WallMechanics::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes) const
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> ret;
|
std::vector<BattleHex> ret;
|
||||||
@ -576,6 +640,11 @@ std::vector<BattleHex> WallMechanics::rangeInHexes(BattleHex centralHex, ui8 sch
|
|||||||
}
|
}
|
||||||
|
|
||||||
///FireWallMechanics
|
///FireWallMechanics
|
||||||
|
FireWallMechanics::FireWallMechanics(const CSpell * s):
|
||||||
|
WallMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool FireWallMechanics::requiresCreatureTarget() const
|
bool FireWallMechanics::requiresCreatureTarget() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -604,6 +673,11 @@ void FireWallMechanics::setupObstacle(SpellCreatedObstacle * obstacle) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///ForceFieldMechanics
|
///ForceFieldMechanics
|
||||||
|
ForceFieldMechanics::ForceFieldMechanics(const CSpell * s):
|
||||||
|
WallMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool ForceFieldMechanics::requiresCreatureTarget() const
|
bool ForceFieldMechanics::requiresCreatureTarget() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -629,6 +703,11 @@ void ForceFieldMechanics::setupObstacle(SpellCreatedObstacle * obstacle) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///RemoveObstacleMechanics
|
///RemoveObstacleMechanics
|
||||||
|
RemoveObstacleMechanics::RemoveObstacleMechanics(const CSpell * s):
|
||||||
|
SpecialSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void RemoveObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void RemoveObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
if(auto obstacleToRemove = parameters.cb->battleGetObstacleOnPos(parameters.getFirstDestinationHex(), false))
|
if(auto obstacleToRemove = parameters.cb->battleGetObstacleOnPos(parameters.getFirstDestinationHex(), false))
|
||||||
@ -705,6 +784,11 @@ bool RemoveObstacleMechanics::requiresCreatureTarget() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///RisingSpellMechanics
|
///RisingSpellMechanics
|
||||||
|
RisingSpellMechanics::RisingSpellMechanics(const CSpell * s):
|
||||||
|
HealingSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
HealingSpellMechanics::EHealLevel RisingSpellMechanics::getHealLevel(int effectLevel) const
|
HealingSpellMechanics::EHealLevel RisingSpellMechanics::getHealLevel(int effectLevel) const
|
||||||
{
|
{
|
||||||
//this may be even distinct class
|
//this may be even distinct class
|
||||||
@ -715,6 +799,11 @@ HealingSpellMechanics::EHealLevel RisingSpellMechanics::getHealLevel(int effectL
|
|||||||
}
|
}
|
||||||
|
|
||||||
///SacrificeMechanics
|
///SacrificeMechanics
|
||||||
|
SacrificeMechanics::SacrificeMechanics(const CSpell * s):
|
||||||
|
RisingSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem SacrificeMechanics::canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const
|
ESpellCastProblem::ESpellCastProblem SacrificeMechanics::canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const
|
||||||
{
|
{
|
||||||
if(mode == ECastingMode::AFTER_ATTACK_CASTING || mode == ECastingMode::SPELL_LIKE_ATTACK || mode == ECastingMode::MAGIC_MIRROR)
|
if(mode == ECastingMode::AFTER_ATTACK_CASTING || mode == ECastingMode::SPELL_LIKE_ATTACK || mode == ECastingMode::MAGIC_MIRROR)
|
||||||
@ -800,6 +889,11 @@ bool SacrificeMechanics::requiresCreatureTarget() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///SpecialRisingSpellMechanics
|
///SpecialRisingSpellMechanics
|
||||||
|
SpecialRisingSpellMechanics::SpecialRisingSpellMechanics(const CSpell * s):
|
||||||
|
RisingSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||||
{
|
{
|
||||||
//find alive possible target
|
//find alive possible target
|
||||||
@ -861,6 +955,11 @@ ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::isImmuneByStac
|
|||||||
}
|
}
|
||||||
|
|
||||||
///SummonMechanics
|
///SummonMechanics
|
||||||
|
SummonMechanics::SummonMechanics(const CSpell * s, CreatureID cre):
|
||||||
|
SpecialSpellMechanics(s), creatureToSummon(cre)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem SummonMechanics::canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const
|
ESpellCastProblem::ESpellCastProblem SummonMechanics::canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const
|
||||||
{
|
{
|
||||||
if(mode == ECastingMode::AFTER_ATTACK_CASTING || mode == ECastingMode::SPELL_LIKE_ATTACK || mode == ECastingMode::MAGIC_MIRROR)
|
if(mode == ECastingMode::AFTER_ATTACK_CASTING || mode == ECastingMode::SPELL_LIKE_ATTACK || mode == ECastingMode::MAGIC_MIRROR)
|
||||||
@ -911,6 +1010,11 @@ bool SummonMechanics::requiresCreatureTarget() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///TeleportMechanics
|
///TeleportMechanics
|
||||||
|
TeleportMechanics::TeleportMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void TeleportMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void TeleportMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
if(parameters.destinations.size() == 2)
|
if(parameters.destinations.size() == 2)
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
TRUE_RESURRECT
|
TRUE_RESURRECT
|
||||||
};
|
};
|
||||||
|
|
||||||
HealingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
HealingSpellMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
virtual int calculateHealedHP(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
virtual int calculateHealedHP(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
||||||
@ -35,15 +35,14 @@ protected:
|
|||||||
class DLL_LINKAGE AntimagicMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE AntimagicMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AntimagicMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
AntimagicMechanics(const CSpell * s);
|
||||||
|
|
||||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE ChainLightningMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE ChainLightningMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChainLightningMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
ChainLightningMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||||
};
|
};
|
||||||
@ -51,7 +50,7 @@ protected:
|
|||||||
class DLL_LINKAGE CloneMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE CloneMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CloneMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
CloneMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
@ -60,11 +59,9 @@ protected:
|
|||||||
class DLL_LINKAGE CureMechanics : public HealingSpellMechanics
|
class DLL_LINKAGE CureMechanics : public HealingSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CureMechanics(CSpell * s): HealingSpellMechanics(s){};
|
CureMechanics(const CSpell * s);
|
||||||
|
|
||||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
|
|
||||||
EHealLevel getHealLevel(int effectLevel) const override final;
|
EHealLevel getHealLevel(int effectLevel) const override final;
|
||||||
private:
|
private:
|
||||||
static bool dispellSelector(const Bonus * b);
|
static bool dispellSelector(const Bonus * b);
|
||||||
@ -73,9 +70,8 @@ private:
|
|||||||
class DLL_LINKAGE DispellMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE DispellMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DispellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
DispellMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
|
|
||||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
@ -84,7 +80,7 @@ protected:
|
|||||||
class DLL_LINKAGE EarthquakeMechanics : public SpecialSpellMechanics
|
class DLL_LINKAGE EarthquakeMechanics : public SpecialSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EarthquakeMechanics(CSpell * s): SpecialSpellMechanics(s){};
|
EarthquakeMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
@ -94,14 +90,14 @@ protected:
|
|||||||
class DLL_LINKAGE HypnotizeMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE HypnotizeMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HypnotizeMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
HypnotizeMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE ObstacleMechanics : public SpecialSpellMechanics
|
class DLL_LINKAGE ObstacleMechanics : public SpecialSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ObstacleMechanics(CSpell * s): SpecialSpellMechanics(s){};
|
ObstacleMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||||
protected:
|
protected:
|
||||||
static bool isHexAviable(const CBattleInfoCallback * cb, const BattleHex & hex, const bool mustBeClear);
|
static bool isHexAviable(const CBattleInfoCallback * cb, const BattleHex & hex, const bool mustBeClear);
|
||||||
@ -112,7 +108,7 @@ protected:
|
|||||||
class PatchObstacleMechanics : public ObstacleMechanics
|
class PatchObstacleMechanics : public ObstacleMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PatchObstacleMechanics(CSpell * s): ObstacleMechanics(s){};
|
PatchObstacleMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
};
|
};
|
||||||
@ -120,7 +116,7 @@ protected:
|
|||||||
class DLL_LINKAGE LandMineMechanics : public PatchObstacleMechanics
|
class DLL_LINKAGE LandMineMechanics : public PatchObstacleMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LandMineMechanics(CSpell * s): PatchObstacleMechanics(s){};
|
LandMineMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
@ -130,7 +126,7 @@ protected:
|
|||||||
class DLL_LINKAGE QuicksandMechanics : public PatchObstacleMechanics
|
class DLL_LINKAGE QuicksandMechanics : public PatchObstacleMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuicksandMechanics(CSpell * s): PatchObstacleMechanics(s){};
|
QuicksandMechanics(const CSpell * s);
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
void setupObstacle(SpellCreatedObstacle * obstacle) const override;
|
void setupObstacle(SpellCreatedObstacle * obstacle) const override;
|
||||||
@ -139,14 +135,14 @@ protected:
|
|||||||
class DLL_LINKAGE WallMechanics : public ObstacleMechanics
|
class DLL_LINKAGE WallMechanics : public ObstacleMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WallMechanics(CSpell * s): ObstacleMechanics(s){};
|
WallMechanics(const CSpell * s);
|
||||||
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = nullptr) const override;
|
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = nullptr) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE FireWallMechanics : public WallMechanics
|
class DLL_LINKAGE FireWallMechanics : public WallMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FireWallMechanics(CSpell * s): WallMechanics(s){};
|
FireWallMechanics(const CSpell * s);
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
@ -156,7 +152,7 @@ protected:
|
|||||||
class DLL_LINKAGE ForceFieldMechanics : public WallMechanics
|
class DLL_LINKAGE ForceFieldMechanics : public WallMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ForceFieldMechanics(CSpell * s): WallMechanics(s){};
|
ForceFieldMechanics(const CSpell * s);
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
@ -166,7 +162,7 @@ protected:
|
|||||||
class DLL_LINKAGE RemoveObstacleMechanics : public SpecialSpellMechanics
|
class DLL_LINKAGE RemoveObstacleMechanics : public SpecialSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RemoveObstacleMechanics(CSpell * s): SpecialSpellMechanics(s){};
|
RemoveObstacleMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
@ -180,16 +176,14 @@ private:
|
|||||||
class DLL_LINKAGE RisingSpellMechanics : public HealingSpellMechanics
|
class DLL_LINKAGE RisingSpellMechanics : public HealingSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RisingSpellMechanics(CSpell * s): HealingSpellMechanics(s){};
|
RisingSpellMechanics(const CSpell * s);
|
||||||
|
|
||||||
EHealLevel getHealLevel(int effectLevel) const override;
|
EHealLevel getHealLevel(int effectLevel) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE SacrificeMechanics : public RisingSpellMechanics
|
class DLL_LINKAGE SacrificeMechanics : public RisingSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SacrificeMechanics(CSpell * s): RisingSpellMechanics(s){};
|
SacrificeMechanics(const CSpell * s);
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
@ -201,7 +195,7 @@ protected:
|
|||||||
class DLL_LINKAGE SpecialRisingSpellMechanics : public RisingSpellMechanics
|
class DLL_LINKAGE SpecialRisingSpellMechanics : public RisingSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpecialRisingSpellMechanics(CSpell * s): RisingSpellMechanics(s){};
|
SpecialRisingSpellMechanics(const CSpell * s);
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
};
|
};
|
||||||
@ -209,8 +203,7 @@ public:
|
|||||||
class DLL_LINKAGE SummonMechanics : public SpecialSpellMechanics
|
class DLL_LINKAGE SummonMechanics : public SpecialSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SummonMechanics(CSpell * s, CreatureID cre): SpecialSpellMechanics(s), creatureToSummon(cre){};
|
SummonMechanics(const CSpell * s, CreatureID cre);
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||||
bool requiresCreatureTarget() const override;
|
bool requiresCreatureTarget() const override;
|
||||||
protected:
|
protected:
|
||||||
@ -222,8 +215,7 @@ private:
|
|||||||
class DLL_LINKAGE TeleportMechanics: public DefaultSpellMechanics
|
class DLL_LINKAGE TeleportMechanics: public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TeleportMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
TeleportMechanics(const CSpell * s);
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override;
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
|
@ -246,6 +246,11 @@ void SpellCastContext::afterCast()
|
|||||||
}
|
}
|
||||||
|
|
||||||
///DefaultSpellMechanics
|
///DefaultSpellMechanics
|
||||||
|
DefaultSpellMechanics::DefaultSpellMechanics(const CSpell * s):
|
||||||
|
ISpellMechanics(s)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
void DefaultSpellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
void DefaultSpellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
{
|
{
|
||||||
if (packet->castByHero)
|
if (packet->castByHero)
|
||||||
@ -884,6 +889,12 @@ bool DefaultSpellMechanics::requiresCreatureTarget() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///SpecialSpellMechanics
|
||||||
|
SpecialSpellMechanics::SpecialSpellMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem SpecialSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
ESpellCastProblem::ESpellCastProblem SpecialSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const
|
||||||
{
|
{
|
||||||
//no problems by default
|
//no problems by default
|
||||||
|
@ -45,7 +45,7 @@ private:
|
|||||||
class DLL_LINKAGE DefaultSpellMechanics : public ISpellMechanics
|
class DLL_LINKAGE DefaultSpellMechanics : public ISpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DefaultSpellMechanics(CSpell * s): ISpellMechanics(s){};
|
DefaultSpellMechanics(const CSpell * s);
|
||||||
|
|
||||||
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const override;
|
std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const override;
|
||||||
std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override final;
|
std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override final;
|
||||||
@ -94,7 +94,7 @@ private:
|
|||||||
class DLL_LINKAGE SpecialSpellMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE SpecialSpellMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpecialSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
SpecialSpellMechanics(const CSpell * s);
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
|
||||||
protected:
|
protected:
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
#include "../battle/BattleInfo.h"
|
#include "../battle/BattleInfo.h"
|
||||||
|
|
||||||
///AcidBreathDamageMechanics
|
///AcidBreathDamageMechanics
|
||||||
|
AcidBreathDamageMechanics::AcidBreathDamageMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void AcidBreathDamageMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void AcidBreathDamageMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
//todo: this should be effectValue
|
//todo: this should be effectValue
|
||||||
@ -56,6 +61,11 @@ ESpellCastProblem::ESpellCastProblem AcidBreathDamageMechanics::isImmuneByStack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
///DeathStareMechanics
|
///DeathStareMechanics
|
||||||
|
DeathStareMechanics::DeathStareMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
|
||||||
{
|
{
|
||||||
//calculating dmg to display
|
//calculating dmg to display
|
||||||
@ -80,6 +90,11 @@ void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
///DispellHelpfulMechanics
|
///DispellHelpfulMechanics
|
||||||
|
DispellHelpfulMechanics::DispellHelpfulMechanics(const CSpell * s):
|
||||||
|
DefaultSpellMechanics(s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
{
|
{
|
||||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||||
|
@ -16,10 +16,8 @@
|
|||||||
class DLL_LINKAGE AcidBreathDamageMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE AcidBreathDamageMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AcidBreathDamageMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
AcidBreathDamageMechanics(const CSpell * s);
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
};
|
};
|
||||||
@ -27,7 +25,7 @@ protected:
|
|||||||
class DLL_LINKAGE DeathStareMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE DeathStareMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DeathStareMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
DeathStareMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
};
|
};
|
||||||
@ -35,11 +33,9 @@ protected:
|
|||||||
class DLL_LINKAGE DispellHelpfulMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE DispellHelpfulMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DispellHelpfulMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
DispellHelpfulMechanics(const CSpell * s);
|
||||||
|
|
||||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
private:
|
private:
|
||||||
static bool positiveSpellEffects(const Bonus * b);
|
static bool positiveSpellEffects(const Bonus * b);
|
||||||
};
|
};
|
||||||
|
@ -113,13 +113,12 @@ int BattleSpellCastParameters::getEffectValue() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
///ISpellMechanics
|
///ISpellMechanics
|
||||||
ISpellMechanics::ISpellMechanics(CSpell * s):
|
ISpellMechanics::ISpellMechanics(const CSpell * s):
|
||||||
owner(s)
|
owner(s)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ISpellMechanics> ISpellMechanics::createMechanics(CSpell * s)
|
std::unique_ptr<ISpellMechanics> ISpellMechanics::createMechanics(const CSpell * s)
|
||||||
{
|
{
|
||||||
switch (s->id)
|
switch (s->id)
|
||||||
{
|
{
|
||||||
@ -174,13 +173,12 @@ std::unique_ptr<ISpellMechanics> ISpellMechanics::createMechanics(CSpell * s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//IAdventureSpellMechanics
|
//IAdventureSpellMechanics
|
||||||
IAdventureSpellMechanics::IAdventureSpellMechanics(CSpell * s):
|
IAdventureSpellMechanics::IAdventureSpellMechanics(const CSpell * s):
|
||||||
owner(s)
|
owner(s)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IAdventureSpellMechanics> IAdventureSpellMechanics::createMechanics(CSpell * s)
|
std::unique_ptr<IAdventureSpellMechanics> IAdventureSpellMechanics::createMechanics(const CSpell * s)
|
||||||
{
|
{
|
||||||
switch (s->id)
|
switch (s->id)
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "CSpellHandler.h"
|
#include "CSpellHandler.h"
|
||||||
#include "../battle/BattleHex.h"
|
#include "../battle/BattleHex.h"
|
||||||
|
|
||||||
|
|
||||||
///callback to be provided by server
|
///callback to be provided by server
|
||||||
class DLL_LINKAGE SpellCastEnvironment
|
class DLL_LINKAGE SpellCastEnvironment
|
||||||
{
|
{
|
||||||
@ -101,13 +100,12 @@ struct DLL_LINKAGE SpellTargetingContext
|
|||||||
SpellTargetingContext(const CSpell * s, ECastingMode::ECastingMode mode_, const ISpellCaster * caster_, int schoolLvl_, BattleHex destination_)
|
SpellTargetingContext(const CSpell * s, ECastingMode::ECastingMode mode_, const ISpellCaster * caster_, int schoolLvl_, BattleHex destination_)
|
||||||
: ti(s,schoolLvl_, mode_), mode(mode_), destination(destination_), caster(caster_), schoolLvl(schoolLvl_)
|
: ti(s,schoolLvl_, mode_), mode(mode_), destination(destination_), caster(caster_), schoolLvl(schoolLvl_)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE ISpellMechanics
|
class DLL_LINKAGE ISpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ISpellMechanics(CSpell * s);
|
ISpellMechanics(const CSpell * s);
|
||||||
virtual ~ISpellMechanics(){};
|
virtual ~ISpellMechanics(){};
|
||||||
|
|
||||||
virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0;
|
virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0;
|
||||||
@ -125,9 +123,9 @@ public:
|
|||||||
//if true use generic algorithm for target existence check, see CSpell::canBeCast
|
//if true use generic algorithm for target existence check, see CSpell::canBeCast
|
||||||
virtual bool requiresCreatureTarget() const = 0;
|
virtual bool requiresCreatureTarget() const = 0;
|
||||||
|
|
||||||
static std::unique_ptr<ISpellMechanics> createMechanics(CSpell * s);
|
static std::unique_ptr<ISpellMechanics> createMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
CSpell * owner;
|
const CSpell * owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DLL_LINKAGE AdventureSpellCastParameters
|
struct DLL_LINKAGE AdventureSpellCastParameters
|
||||||
@ -139,12 +137,12 @@ struct DLL_LINKAGE AdventureSpellCastParameters
|
|||||||
class DLL_LINKAGE IAdventureSpellMechanics
|
class DLL_LINKAGE IAdventureSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IAdventureSpellMechanics(CSpell * s);
|
IAdventureSpellMechanics(const CSpell * s);
|
||||||
virtual ~IAdventureSpellMechanics() = default;
|
virtual ~IAdventureSpellMechanics() = default;
|
||||||
|
|
||||||
virtual bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const = 0;
|
virtual bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const = 0;
|
||||||
|
|
||||||
static std::unique_ptr<IAdventureSpellMechanics> createMechanics(CSpell * s);
|
static std::unique_ptr<IAdventureSpellMechanics> createMechanics(const CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
CSpell * owner;
|
const CSpell * owner;
|
||||||
};
|
};
|
||||||
|
@ -310,7 +310,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
|
|||||||
}
|
}
|
||||||
else if (hlu.skills.size() > 1)
|
else if (hlu.skills.size() > 1)
|
||||||
{
|
{
|
||||||
auto levelUpQuery = std::make_shared<CHeroLevelUpDialogQuery>(hlu);
|
auto levelUpQuery = std::make_shared<CHeroLevelUpDialogQuery>(this, hlu);
|
||||||
hlu.queryID = levelUpQuery->queryID;
|
hlu.queryID = levelUpQuery->queryID;
|
||||||
queries.addQuery(levelUpQuery);
|
queries.addQuery(levelUpQuery);
|
||||||
sendAndApply(&hlu);
|
sendAndApply(&hlu);
|
||||||
@ -448,7 +448,7 @@ void CGameHandler::levelUpCommander(const CCommanderInstance * c)
|
|||||||
}
|
}
|
||||||
else if (skillAmount > 1) //apply and ask for secondary skill
|
else if (skillAmount > 1) //apply and ask for secondary skill
|
||||||
{
|
{
|
||||||
auto commanderLevelUp = std::make_shared<CCommanderLevelUpDialogQuery>(clu);
|
auto commanderLevelUp = std::make_shared<CCommanderLevelUpDialogQuery>(this, clu);
|
||||||
clu.queryID = commanderLevelUp->queryID;
|
clu.queryID = commanderLevelUp->queryID;
|
||||||
queries.addQuery(commanderLevelUp);
|
queries.addQuery(commanderLevelUp);
|
||||||
sendAndApply(&clu);
|
sendAndApply(&clu);
|
||||||
@ -1434,7 +1434,6 @@ CGameHandler::CGameHandler(void)
|
|||||||
applier = new CApplier<CBaseForGHApply>;
|
applier = new CApplier<CBaseForGHApply>;
|
||||||
registerTypesServerPacks(*applier);
|
registerTypesServerPacks(*applier);
|
||||||
visitObjectAfterVictory = false;
|
visitObjectAfterVictory = false;
|
||||||
queries.gh = this;
|
|
||||||
|
|
||||||
spellEnv = new ServerSpellCastEnvironment(this);
|
spellEnv = new ServerSpellCastEnvironment(this);
|
||||||
}
|
}
|
||||||
@ -2140,7 +2139,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
{
|
{
|
||||||
LOG_TRACE_PARAMS(logGlobal, "Hero %s starts movement from %s to %s", h->name % tmh.start % tmh.end);
|
LOG_TRACE_PARAMS(logGlobal, "Hero %s starts movement from %s to %s", h->name % tmh.start % tmh.end);
|
||||||
|
|
||||||
auto moveQuery = std::make_shared<CHeroMovementQuery>(tmh, h);
|
auto moveQuery = std::make_shared<CHeroMovementQuery>(this, tmh, h);
|
||||||
queries.addQuery(moveQuery);
|
queries.addQuery(moveQuery);
|
||||||
|
|
||||||
if (leavingTile == LEAVING_TILE)
|
if (leavingTile == LEAVING_TILE)
|
||||||
@ -2313,7 +2312,7 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner)
|
|||||||
|
|
||||||
void CGameHandler::showBlockingDialog(BlockingDialog *iw)
|
void CGameHandler::showBlockingDialog(BlockingDialog *iw)
|
||||||
{
|
{
|
||||||
auto dialogQuery = std::make_shared<CBlockingDialogQuery>(*iw);
|
auto dialogQuery = std::make_shared<CBlockingDialogQuery>(this, *iw);
|
||||||
queries.addQuery(dialogQuery);
|
queries.addQuery(dialogQuery);
|
||||||
iw->queryID = dialogQuery->queryID;
|
iw->queryID = dialogQuery->queryID;
|
||||||
sendToAllClients(iw);
|
sendToAllClients(iw);
|
||||||
@ -2321,7 +2320,7 @@ void CGameHandler::showBlockingDialog(BlockingDialog *iw)
|
|||||||
|
|
||||||
void CGameHandler::showTeleportDialog(TeleportDialog *iw)
|
void CGameHandler::showTeleportDialog(TeleportDialog *iw)
|
||||||
{
|
{
|
||||||
auto dialogQuery = std::make_shared<CTeleportDialogQuery>(*iw);
|
auto dialogQuery = std::make_shared<CTeleportDialogQuery>(this, *iw);
|
||||||
queries.addQuery(dialogQuery);
|
queries.addQuery(dialogQuery);
|
||||||
iw->queryID = dialogQuery->queryID;
|
iw->queryID = dialogQuery->queryID;
|
||||||
sendToAllClients(iw);
|
sendToAllClients(iw);
|
||||||
@ -2449,7 +2448,7 @@ void CGameHandler::startBattlePrimary(const CArmedInstance *army1, const CArmedI
|
|||||||
|
|
||||||
setupBattle(tile, armies, heroes, creatureBank, town); //initializes stacks, places creatures on battlefield, blocks and informs player interfaces
|
setupBattle(tile, armies, heroes, creatureBank, town); //initializes stacks, places creatures on battlefield, blocks and informs player interfaces
|
||||||
|
|
||||||
auto battleQuery = std::make_shared<CBattleQuery>(gs->curB);
|
auto battleQuery = std::make_shared<CBattleQuery>(this, gs->curB);
|
||||||
queries.addQuery(battleQuery);
|
queries.addQuery(battleQuery);
|
||||||
|
|
||||||
boost::thread(&CGameHandler::runBattle, this);
|
boost::thread(&CGameHandler::runBattle, this);
|
||||||
@ -2616,7 +2615,7 @@ void CGameHandler::heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)
|
|||||||
|
|
||||||
if (getPlayerRelations(h1->getOwner(), h2->getOwner()))
|
if (getPlayerRelations(h1->getOwner(), h2->getOwner()))
|
||||||
{
|
{
|
||||||
auto exchange = std::make_shared<CGarrisonDialogQuery>(h1, h2);
|
auto exchange = std::make_shared<CGarrisonDialogQuery>(this, h1, h2);
|
||||||
ExchangeDialog hex;
|
ExchangeDialog hex;
|
||||||
hex.queryID = exchange->queryID;
|
hex.queryID = exchange->queryID;
|
||||||
hex.heroes[0] = getHero(hero1);
|
hex.heroes[0] = getHero(hero1);
|
||||||
@ -3731,20 +3730,19 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor pl
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameHandler::queryReply(QueryID qid, ui32 answer, PlayerColor player)
|
bool CGameHandler::queryReply(QueryID qid, const JsonNode & answer, PlayerColor player)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> lock(gsm);
|
boost::unique_lock<boost::recursive_mutex> lock(gsm);
|
||||||
|
|
||||||
logGlobal->trace("Player %s attempts answering query %d with answer %d", player, qid, answer);
|
logGlobal->trace("Player %s attempts answering query %d with answer:", player, qid);
|
||||||
|
logGlobal->traceStream() << answer;
|
||||||
|
|
||||||
auto topQuery = queries.topQuery(player);
|
auto topQuery = queries.topQuery(player);
|
||||||
COMPLAIN_RET_FALSE_IF(!topQuery, "This player doesn't have any queries!");
|
COMPLAIN_RET_FALSE_IF(!topQuery, "This player doesn't have any queries!");
|
||||||
COMPLAIN_RET_FALSE_IF(topQuery->queryID != qid, "This player top query has different ID!");
|
COMPLAIN_RET_FALSE_IF(topQuery->queryID != qid, "This player top query has different ID!");
|
||||||
COMPLAIN_RET_FALSE_IF(!topQuery->endsByPlayerAnswer(), "This query cannot be ended by player's answer!");
|
COMPLAIN_RET_FALSE_IF(!topQuery->endsByPlayerAnswer(), "This query cannot be ended by player's answer!");
|
||||||
|
|
||||||
if (auto dialogQuery = std::dynamic_pointer_cast<CDialogQuery>(topQuery))
|
topQuery->setReply(answer);
|
||||||
dialogQuery->answer = answer;
|
|
||||||
|
|
||||||
queries.popQuery(topQuery);
|
queries.popQuery(topQuery);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4849,7 +4847,7 @@ void CGameHandler::showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID h
|
|||||||
assert(lowerArmy);
|
assert(lowerArmy);
|
||||||
assert(upperArmy);
|
assert(upperArmy);
|
||||||
|
|
||||||
auto garrisonQuery = std::make_shared<CGarrisonDialogQuery>(upperArmy, lowerArmy);
|
auto garrisonQuery = std::make_shared<CGarrisonDialogQuery>(this, upperArmy, lowerArmy);
|
||||||
queries.addQuery(garrisonQuery);
|
queries.addQuery(garrisonQuery);
|
||||||
|
|
||||||
GarrisonDialog gd;
|
GarrisonDialog gd;
|
||||||
@ -4920,7 +4918,7 @@ bool CGameHandler::isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2)
|
|||||||
void CGameHandler::objectVisited(const CGObjectInstance * obj, const CGHeroInstance * h)
|
void CGameHandler::objectVisited(const CGObjectInstance * obj, const CGHeroInstance * h)
|
||||||
{
|
{
|
||||||
logGlobal->debug("%s visits %s (%d:%d)", h->nodeName(), obj->getObjectName(), obj->ID, obj->subID);
|
logGlobal->debug("%s visits %s (%d:%d)", h->nodeName(), obj->getObjectName(), obj->ID, obj->subID);
|
||||||
auto visitQuery = std::make_shared<CObjectVisitQuery>(obj, h, obj->visitablePos());
|
auto visitQuery = std::make_shared<CObjectVisitQuery>(this, obj, h, obj->visitablePos());
|
||||||
queries.addQuery(visitQuery); //TODO real visit pos
|
queries.addQuery(visitQuery); //TODO real visit pos
|
||||||
|
|
||||||
HeroVisit hv;
|
HeroVisit hv;
|
||||||
@ -5405,17 +5403,6 @@ void CGameHandler::handleAfterAttackCasting(const BattleAttack & bat)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameHandler::castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos)
|
|
||||||
{
|
|
||||||
const CSpell *s = spellID.toSpell();
|
|
||||||
|
|
||||||
AdventureSpellCastParameters p;
|
|
||||||
p.caster = h;
|
|
||||||
p.pos = pos;
|
|
||||||
|
|
||||||
return s->adventureCast(spellEnv, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameHandler::visitObjectOnTile(const TerrainTile &t, const CGHeroInstance * h)
|
void CGameHandler::visitObjectOnTile(const TerrainTile &t, const CGHeroInstance * h)
|
||||||
{
|
{
|
||||||
if (!t.visitableObjects.empty())
|
if (!t.visitableObjects.empty())
|
||||||
|
@ -31,7 +31,7 @@ struct NewStructures;
|
|||||||
class CGHeroInstance;
|
class CGHeroInstance;
|
||||||
class IMarket;
|
class IMarket;
|
||||||
|
|
||||||
class ServerSpellCastEnvironment;
|
class SpellCastEnvironment;
|
||||||
|
|
||||||
struct PlayerStatus
|
struct PlayerStatus
|
||||||
{
|
{
|
||||||
@ -92,6 +92,8 @@ public:
|
|||||||
ui32 QID;
|
ui32 QID;
|
||||||
Queries queries;
|
Queries queries;
|
||||||
|
|
||||||
|
SpellCastEnvironment * spellEnv;
|
||||||
|
|
||||||
bool isValidObject(const CGObjectInstance *obj) const;
|
bool isValidObject(const CGObjectInstance *obj) const;
|
||||||
bool isBlockedByQueries(const CPack *pack, PlayerColor player);
|
bool isBlockedByQueries(const CPack *pack, PlayerColor player);
|
||||||
bool isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2);
|
bool isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2);
|
||||||
@ -199,7 +201,7 @@ public:
|
|||||||
void stackTurnTrigger(const CStack *stack);
|
void stackTurnTrigger(const CStack *stack);
|
||||||
void handleDamageFromObstacle(const CObstacleInstance &obstacle, const CStack * curStack); //checks if obstacle is land mine and handles possible consequences
|
void handleDamageFromObstacle(const CObstacleInstance &obstacle, const CStack * curStack); //checks if obstacle is land mine and handles possible consequences
|
||||||
void removeObstacle(const CObstacleInstance &obstacle);
|
void removeObstacle(const CObstacleInstance &obstacle);
|
||||||
bool queryReply( QueryID qid, ui32 answer, PlayerColor player );
|
bool queryReply( QueryID qid, const JsonNode & answer, PlayerColor player );
|
||||||
bool hireHero( const CGObjectInstance *obj, ui8 hid, PlayerColor player );
|
bool hireHero( const CGObjectInstance *obj, ui8 hid, PlayerColor player );
|
||||||
bool buildBoat( ObjectInstanceID objid );
|
bool buildBoat( ObjectInstanceID objid );
|
||||||
bool setFormation( ObjectInstanceID hid, ui8 formation );
|
bool setFormation( ObjectInstanceID hid, ui8 formation );
|
||||||
@ -231,7 +233,6 @@ public:
|
|||||||
void objectVisitEnded(const CObjectVisitQuery &query);
|
void objectVisitEnded(const CObjectVisitQuery &query);
|
||||||
void engageIntoBattle( PlayerColor player );
|
void engageIntoBattle( PlayerColor player );
|
||||||
bool dig(const CGHeroInstance *h);
|
bool dig(const CGHeroInstance *h);
|
||||||
bool castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos);
|
|
||||||
void moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging);
|
void moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging);
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
@ -257,7 +258,6 @@ public:
|
|||||||
FinishingBattleHelper();
|
FinishingBattleHelper();
|
||||||
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount);
|
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount);
|
||||||
|
|
||||||
//std::shared_ptr<const CBattleQuery> query;
|
|
||||||
const CGHeroInstance *winnerHero, *loserHero;
|
const CGHeroInstance *winnerHero, *loserHero;
|
||||||
PlayerColor victor, loser;
|
PlayerColor victor, loser;
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ public:
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & /*query & */winnerHero & loserHero & victor & loser;
|
h & winnerHero & loserHero & victor & loser;
|
||||||
if(version < 774 && !h.saving)
|
if(version < 774 && !h.saving)
|
||||||
{
|
{
|
||||||
bool duel;
|
bool duel;
|
||||||
@ -292,8 +292,6 @@ public:
|
|||||||
CRandomGenerator & getRandomGenerator();
|
CRandomGenerator & getRandomGenerator();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ServerSpellCastEnvironment * spellEnv;
|
|
||||||
|
|
||||||
std::list<PlayerColor> generatePlayerTurnOrder() const;
|
std::list<PlayerColor> generatePlayerTurnOrder() const;
|
||||||
void makeStackDoNothing(const CStack * next);
|
void makeStackDoNothing(const CStack * next);
|
||||||
void getVictoryLossMessage(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult, InfoWindow & out) const;
|
void getVictoryLossMessage(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult, InfoWindow & out) const;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "CGameHandler.h"
|
#include "CGameHandler.h"
|
||||||
#include "../lib/battle/BattleInfo.h"
|
#include "../lib/battle/BattleInfo.h"
|
||||||
#include "../lib/mapObjects/MiscObjects.h"
|
#include "../lib/mapObjects/MiscObjects.h"
|
||||||
|
#include "../lib/spells/ISpellMechanics.h"
|
||||||
|
|
||||||
boost::mutex Queries::mx;
|
boost::mutex Queries::mx;
|
||||||
|
|
||||||
@ -34,7 +35,8 @@ std::ostream & operator<<(std::ostream &out, QueryPtr query)
|
|||||||
return out << "[" << query.get() << "] " << query->toString();
|
return out << "[" << query.get() << "] " << query->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
CQuery::CQuery(void)
|
CQuery::CQuery(Queries * Owner):
|
||||||
|
owner(Owner)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::mutex> l(Queries::mx);
|
boost::unique_lock<boost::mutex> l(Queries::mx);
|
||||||
|
|
||||||
@ -69,7 +71,7 @@ bool CQuery::endsByPlayerAnswer() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CQuery::onRemoval(PlayerColor color)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,18 +84,45 @@ void CQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) cons
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CQuery::onExposure(CGameHandler *gh, QueryPtr topQuery)
|
void CQuery::onExposure(QueryPtr topQuery)
|
||||||
{
|
{
|
||||||
gh->queries.popQuery(*this);
|
owner->popQuery(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CQuery::onAdding(CGameHandler *gh, PlayerColor color)
|
void CQuery::onAdding(PlayerColor color)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjectVisitQuery::CObjectVisitQuery(const CGObjectInstance *Obj, const CGHeroInstance *Hero, int3 Tile)
|
void CQuery::onAdded(PlayerColor color)
|
||||||
: visitedObject(Obj), visitingHero(Hero), tile(Tile), removeObjectAfterVisit(false)
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CQuery::setReply(const JsonNode & reply)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CQuery::blockAllButReply(const CPack * pack) const
|
||||||
|
{
|
||||||
|
//We accept only query replies from correct player
|
||||||
|
if(auto reply = dynamic_ptr_cast<QueryReply>(pack))
|
||||||
|
{
|
||||||
|
return !vstd::contains(players, reply->player);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGhQuery::CGhQuery(CGameHandler * owner):
|
||||||
|
CQuery(&owner->queries), gh(owner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CObjectVisitQuery::CObjectVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero, int3 Tile):
|
||||||
|
CGhQuery(owner), visitedObject(Obj), visitingHero(Hero), tile(Tile), removeObjectAfterVisit(false)
|
||||||
{
|
{
|
||||||
addPlayer(Hero->tempOwner);
|
addPlayer(Hero->tempOwner);
|
||||||
}
|
}
|
||||||
@ -105,7 +134,7 @@ bool CObjectVisitQuery::blocksPack(const CPack *pack) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObjectVisitQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CObjectVisitQuery::onRemoval(PlayerColor color)
|
||||||
{
|
{
|
||||||
gh->objectVisitEnded(*this);
|
gh->objectVisitEnded(*this);
|
||||||
|
|
||||||
@ -115,13 +144,13 @@ void CObjectVisitQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
|||||||
gh->removeObject(visitedObject);
|
gh->removeObject(visitedObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObjectVisitQuery::onExposure(CGameHandler *gh, QueryPtr topQuery)
|
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))
|
||||||
topQuery->notifyObjectAboutRemoval(*this);
|
topQuery->notifyObjectAboutRemoval(*this);
|
||||||
|
|
||||||
gh->queries.popQuery(*this);
|
owner->popQuery(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Queries::popQuery(PlayerColor player, QueryPtr query)
|
void Queries::popQuery(PlayerColor player, QueryPtr query)
|
||||||
@ -136,12 +165,12 @@ void Queries::popQuery(PlayerColor player, QueryPtr query)
|
|||||||
queries[player] -= query;
|
queries[player] -= query;
|
||||||
auto nextQuery = topQuery(player);
|
auto nextQuery = topQuery(player);
|
||||||
|
|
||||||
query->onRemoval(gh, player);
|
query->onRemoval(player);
|
||||||
|
|
||||||
//Exposure on query below happens only if removal didn't trigger any new query
|
//Exposure on query below happens only if removal didn't trigger any new query
|
||||||
if(nextQuery && nextQuery == topQuery(player))
|
if(nextQuery && nextQuery == topQuery(player))
|
||||||
{
|
{
|
||||||
nextQuery->onExposure(gh, query);
|
nextQuery->onExposure(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,12 +199,15 @@ void Queries::addQuery(QueryPtr query)
|
|||||||
{
|
{
|
||||||
for(auto player : query->players)
|
for(auto player : query->players)
|
||||||
addQuery(player, query);
|
addQuery(player, query);
|
||||||
|
|
||||||
|
for(auto player : query->players)
|
||||||
|
query->onAdded(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Queries::addQuery(PlayerColor player, QueryPtr query)
|
void Queries::addQuery(PlayerColor player, QueryPtr query)
|
||||||
{
|
{
|
||||||
//LOG_TRACE_PARAMS(logGlobal, "player='%d', query='%s'", player.getNum() % query);
|
//LOG_TRACE_PARAMS(logGlobal, "player='%d', query='%s'", player.getNum() % query);
|
||||||
query->onAdding(gh, player);
|
query->onAdding(player);
|
||||||
queries[player].push_back(query);
|
queries[player].push_back(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +259,8 @@ void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit
|
|||||||
objectVisit.visitedObject->battleFinished(objectVisit.visitingHero, *result);
|
objectVisit.visitedObject->battleFinished(objectVisit.visitingHero, *result);
|
||||||
}
|
}
|
||||||
|
|
||||||
CBattleQuery::CBattleQuery(const BattleInfo *Bi)
|
CBattleQuery::CBattleQuery(CGameHandler * owner, const BattleInfo *Bi):
|
||||||
|
CGhQuery(owner)
|
||||||
{
|
{
|
||||||
belligerents[0] = Bi->sides[0].armyObject;
|
belligerents[0] = Bi->sides[0].armyObject;
|
||||||
belligerents[1] = Bi->sides[1].armyObject;
|
belligerents[1] = Bi->sides[1].armyObject;
|
||||||
@ -238,8 +271,8 @@ CBattleQuery::CBattleQuery(const BattleInfo *Bi)
|
|||||||
addPlayer(side.color);
|
addPlayer(side.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
CBattleQuery::CBattleQuery()
|
CBattleQuery::CBattleQuery(CGameHandler * owner):
|
||||||
:bi(nullptr)
|
CGhQuery(owner), bi(nullptr)
|
||||||
{
|
{
|
||||||
belligerents[0] = belligerents[1] = nullptr;
|
belligerents[0] = belligerents[1] = nullptr;
|
||||||
}
|
}
|
||||||
@ -250,7 +283,7 @@ bool CBattleQuery::blocksPack(const CPack *pack) const
|
|||||||
return strcmp(name, typeid(MakeAction).name()) && strcmp(name, typeid(MakeCustomAction).name());
|
return strcmp(name, typeid(MakeAction).name()) && strcmp(name, typeid(MakeCustomAction).name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CBattleQuery::onRemoval(PlayerColor color)
|
||||||
{
|
{
|
||||||
gh->battleAfterLevelUp(*result);
|
gh->battleAfterLevelUp(*result);
|
||||||
}
|
}
|
||||||
@ -260,7 +293,8 @@ void CGarrisonDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &obj
|
|||||||
objectVisit.visitedObject->garrisonDialogClosed(objectVisit.visitingHero);
|
objectVisit.visitedObject->garrisonDialogClosed(objectVisit.visitingHero);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGarrisonDialogQuery::CGarrisonDialogQuery(const CArmedInstance *up, const CArmedInstance *down)
|
CGarrisonDialogQuery::CGarrisonDialogQuery(CGameHandler * owner, const CArmedInstance * up, const CArmedInstance * down):
|
||||||
|
CDialogQuery(owner)
|
||||||
{
|
{
|
||||||
exchangingArmies[0] = up;
|
exchangingArmies[0] = up;
|
||||||
exchangingArmies[1] = down;
|
exchangingArmies[1] = down;
|
||||||
@ -314,13 +348,14 @@ void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &obj
|
|||||||
objectVisit.visitedObject->blockingDialogAnswered(objectVisit.visitingHero, *answer);
|
objectVisit.visitedObject->blockingDialogAnswered(objectVisit.visitingHero, *answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockingDialogQuery::CBlockingDialogQuery(const BlockingDialog &bd)
|
CBlockingDialogQuery::CBlockingDialogQuery(CGameHandler * owner, const BlockingDialog & bd):
|
||||||
|
CDialogQuery(owner)
|
||||||
{
|
{
|
||||||
this->bd = bd;
|
this->bd = bd;
|
||||||
addPlayer(bd.player);
|
addPlayer(bd.player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery & objectVisit) const
|
||||||
{
|
{
|
||||||
// do not change to dynamic_ptr_cast - SIGSEGV!
|
// do not change to dynamic_ptr_cast - SIGSEGV!
|
||||||
auto obj = dynamic_cast<const CGTeleport*>(objectVisit.visitedObject);
|
auto obj = dynamic_cast<const CGTeleport*>(objectVisit.visitedObject);
|
||||||
@ -330,19 +365,21 @@ void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &obj
|
|||||||
logGlobal->error("Invalid instance in teleport query");
|
logGlobal->error("Invalid instance in teleport query");
|
||||||
}
|
}
|
||||||
|
|
||||||
CTeleportDialogQuery::CTeleportDialogQuery(const TeleportDialog &td)
|
CTeleportDialogQuery::CTeleportDialogQuery(CGameHandler * owner, const TeleportDialog & td):
|
||||||
|
CDialogQuery(owner)
|
||||||
{
|
{
|
||||||
this->td = td;
|
this->td = td;
|
||||||
addPlayer(td.hero->tempOwner);
|
addPlayer(td.hero->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(const HeroLevelUp &Hlu)
|
CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(CGameHandler * owner, const HeroLevelUp & Hlu):
|
||||||
|
CDialogQuery(owner)
|
||||||
{
|
{
|
||||||
hlu = Hlu;
|
hlu = Hlu;
|
||||||
addPlayer(hlu.hero->tempOwner);
|
addPlayer(hlu.hero->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CHeroLevelUpDialogQuery::onRemoval(PlayerColor color)
|
||||||
{
|
{
|
||||||
assert(answer);
|
assert(answer);
|
||||||
logGlobal->trace("Completing hero level-up query. %s gains skill %d", hlu.hero->getObjectName(), answer.get());
|
logGlobal->trace("Completing hero level-up query. %s gains skill %d", hlu.hero->getObjectName(), answer.get());
|
||||||
@ -354,13 +391,14 @@ void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &
|
|||||||
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(const CommanderLevelUp &Clu)
|
CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(CGameHandler * owner, const CommanderLevelUp & Clu):
|
||||||
|
CDialogQuery(owner)
|
||||||
{
|
{
|
||||||
clu = Clu;
|
clu = Clu;
|
||||||
addPlayer(clu.hero->tempOwner);
|
addPlayer(clu.hero->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCommanderLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CCommanderLevelUpDialogQuery::onRemoval(PlayerColor color)
|
||||||
{
|
{
|
||||||
assert(answer);
|
assert(answer);
|
||||||
logGlobal->trace("Completing commander level-up query. Commander of hero %s gains skill %s", clu.hero->getObjectName(), answer.get());
|
logGlobal->trace("Completing commander level-up query. Commander of hero %s gains skill %s", clu.hero->getObjectName(), answer.get());
|
||||||
@ -372,29 +410,35 @@ void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQu
|
|||||||
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CDialogQuery::CDialogQuery(CGameHandler * owner):
|
||||||
|
CGhQuery(owner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool CDialogQuery::endsByPlayerAnswer() const
|
bool CDialogQuery::endsByPlayerAnswer() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDialogQuery::blocksPack(const CPack *pack) const
|
bool CDialogQuery::blocksPack(const CPack * pack) const
|
||||||
{
|
{
|
||||||
//We accept only query replies from correct player
|
return blockAllButReply(pack);
|
||||||
if(auto reply = dynamic_ptr_cast<QueryReply>(pack))
|
|
||||||
{
|
|
||||||
return !vstd::contains(players, reply->player);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeroMovementQuery::CHeroMovementQuery(const TryMoveHero &Tmh, const CGHeroInstance *Hero, bool VisitDestAfterVictory)
|
void CDialogQuery::setReply(const JsonNode & reply)
|
||||||
: tmh(Tmh), visitDestAfterVictory(VisitDestAfterVictory), hero(Hero)
|
{
|
||||||
|
if(reply.getType() == JsonNode::DATA_INTEGER)
|
||||||
|
answer = reply.Integer();
|
||||||
|
}
|
||||||
|
|
||||||
|
CHeroMovementQuery::CHeroMovementQuery(CGameHandler * owner, const TryMoveHero & Tmh, const CGHeroInstance * Hero, bool VisitDestAfterVictory):
|
||||||
|
CGhQuery(owner), tmh(Tmh), visitDestAfterVictory(VisitDestAfterVictory), hero(Hero)
|
||||||
{
|
{
|
||||||
players.push_back(hero->tempOwner);
|
players.push_back(hero->tempOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroMovementQuery::onExposure(CGameHandler *gh, QueryPtr topQuery)
|
void CHeroMovementQuery::onExposure(QueryPtr topQuery)
|
||||||
{
|
{
|
||||||
assert(players.size() == 1);
|
assert(players.size() == 1);
|
||||||
|
|
||||||
@ -407,10 +451,10 @@ void CHeroMovementQuery::onExposure(CGameHandler *gh, QueryPtr topQuery)
|
|||||||
gh->visitObjectOnTile(*gh->getTile(CGHeroInstance::convertPosition(tmh.end, false)), hero);
|
gh->visitObjectOnTile(*gh->getTile(CGHeroInstance::convertPosition(tmh.end, false)), hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
gh->queries.popIfTop(*this);
|
owner->popIfTop(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroMovementQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
void CHeroMovementQuery::onRemoval(PlayerColor color)
|
||||||
{
|
{
|
||||||
PlayerBlocked pb;
|
PlayerBlocked pb;
|
||||||
pb.player = color;
|
pb.player = color;
|
||||||
@ -419,7 +463,7 @@ void CHeroMovementQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
|||||||
gh->sendAndApply(&pb);
|
gh->sendAndApply(&pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroMovementQuery::onAdding(CGameHandler *gh, PlayerColor color)
|
void CHeroMovementQuery::onAdding(PlayerColor color)
|
||||||
{
|
{
|
||||||
PlayerBlocked pb;
|
PlayerBlocked pb;
|
||||||
pb.player = color;
|
pb.player = color;
|
||||||
@ -427,3 +471,67 @@ void CHeroMovementQuery::onAdding(CGameHandler *gh, PlayerColor color)
|
|||||||
pb.startOrEnd = PlayerBlocked::BLOCKADE_STARTED;
|
pb.startOrEnd = PlayerBlocked::BLOCKADE_STARTED;
|
||||||
gh->sendAndApply(&pb);
|
gh->sendAndApply(&pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMapObjectSelectQuery::CMapObjectSelectQuery(Queries * Owner):
|
||||||
|
CQuery(Owner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMapObjectSelectQuery::blocksPack(const CPack * pack) const
|
||||||
|
{
|
||||||
|
return blockAllButReply(pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMapObjectSelectQuery::endsByPlayerAnswer() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMapObjectSelectQuery::setReply(const JsonNode & reply)
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
CSpellQuery::CSpellQuery(Queries * Owner, const SpellCastEnvironment * SpellEnv):
|
||||||
|
CQuery(Owner), spellEnv(SpellEnv)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
120
server/CQuery.h
120
server/CQuery.h
@ -9,6 +9,9 @@ class CArmedInstance;
|
|||||||
class CGameHandler;
|
class CGameHandler;
|
||||||
class CObjectVisitQuery;
|
class CObjectVisitQuery;
|
||||||
class CQuery;
|
class CQuery;
|
||||||
|
class Queries;
|
||||||
|
class CSpell;
|
||||||
|
class SpellCastEnvironment;
|
||||||
|
|
||||||
typedef std::shared_ptr<CQuery> QueryPtr;
|
typedef std::shared_ptr<CQuery> QueryPtr;
|
||||||
|
|
||||||
@ -22,40 +25,47 @@ typedef std::shared_ptr<CQuery> QueryPtr;
|
|||||||
// Queries can cause another queries, forming a stack of queries for each player. Eg: hero movement -> object visit -> dialog.
|
// Queries can cause another queries, forming a stack of queries for each player. Eg: hero movement -> object visit -> dialog.
|
||||||
class CQuery
|
class CQuery
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
void addPlayer(PlayerColor color);
|
|
||||||
public:
|
public:
|
||||||
std::vector<PlayerColor> players; //players that are affected (often "blocked") by query
|
std::vector<PlayerColor> players; //players that are affected (often "blocked") by query
|
||||||
QueryID queryID;
|
QueryID queryID;
|
||||||
|
|
||||||
CQuery(void);
|
CQuery(Queries * Owner);
|
||||||
|
|
||||||
|
|
||||||
virtual bool blocksPack(const CPack *pack) const; //query can block attempting actions by player. Eg. he can't move hero during the battle.
|
virtual bool blocksPack(const CPack *pack) const; //query can block attempting actions by player. Eg. he can't move hero during the battle.
|
||||||
|
|
||||||
virtual bool endsByPlayerAnswer() const; //query is removed after player gives answer (like dialogs)
|
virtual bool endsByPlayerAnswer() const; //query is removed after player gives answer (like dialogs)
|
||||||
virtual void onAdding(CGameHandler *gh, PlayerColor color); //called just before query is pushed on stack
|
virtual void onAdding(PlayerColor color); //called just before query is pushed on stack
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color); //called after query is removed from stack
|
virtual void onAdded(PlayerColor color); //called right after query is pushed on stack
|
||||||
virtual void onExposure(CGameHandler *gh, QueryPtr topQuery);//called when query immediately above is removed and this is exposed (becomes top)
|
virtual void onRemoval(PlayerColor color); //called after query is removed from stack
|
||||||
|
virtual void onExposure(QueryPtr topQuery);//called when query immediately above is removed and this is exposed (becomes top)
|
||||||
virtual std::string toString() const;
|
virtual std::string toString() const;
|
||||||
|
|
||||||
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const;
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const;
|
||||||
|
|
||||||
|
virtual void setReply(const JsonNode & reply);
|
||||||
|
|
||||||
virtual ~CQuery(void);
|
virtual ~CQuery(void);
|
||||||
|
protected:
|
||||||
|
Queries * owner;
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
void addPlayer(PlayerColor color);
|
||||||
{
|
bool blockAllButReply(const CPack * pack) const;
|
||||||
h & players & queryID;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const CQuery &query);
|
std::ostream &operator<<(std::ostream &out, const CQuery &query);
|
||||||
std::ostream &operator<<(std::ostream &out, QueryPtr query);
|
std::ostream &operator<<(std::ostream &out, QueryPtr query);
|
||||||
|
|
||||||
|
class CGhQuery : public CQuery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CGhQuery(CGameHandler * owner);
|
||||||
|
protected:
|
||||||
|
CGameHandler * gh;
|
||||||
|
};
|
||||||
|
|
||||||
//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 CObjectVisitQuery : public CGhQuery
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const CGObjectInstance *visitedObject;
|
const CGObjectInstance *visitedObject;
|
||||||
@ -63,14 +73,14 @@ public:
|
|||||||
int3 tile; //may be different than hero pos -> eg. visit via teleport
|
int3 tile; //may be different than hero pos -> eg. visit via teleport
|
||||||
bool removeObjectAfterVisit;
|
bool removeObjectAfterVisit;
|
||||||
|
|
||||||
CObjectVisitQuery(const CGObjectInstance *Obj, const CGHeroInstance *Hero, int3 Tile);
|
CObjectVisitQuery(CGameHandler * owner, const CGObjectInstance *Obj, const CGHeroInstance *Hero, int3 Tile);
|
||||||
|
|
||||||
virtual bool blocksPack(const CPack *pack) const override;
|
virtual bool blocksPack(const CPack *pack) const override;
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color) override;
|
virtual void onRemoval(PlayerColor color) override;
|
||||||
virtual void onExposure(CGameHandler *gh, QueryPtr topQuery) override;
|
virtual void onExposure(QueryPtr topQuery) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBattleQuery : public CQuery
|
class CBattleQuery : public CGhQuery
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::array<const CArmedInstance *,2> belligerents;
|
std::array<const CArmedInstance *,2> belligerents;
|
||||||
@ -78,35 +88,38 @@ public:
|
|||||||
const BattleInfo *bi;
|
const BattleInfo *bi;
|
||||||
boost::optional<BattleResult> result;
|
boost::optional<BattleResult> result;
|
||||||
|
|
||||||
CBattleQuery();
|
CBattleQuery(CGameHandler * owner);
|
||||||
CBattleQuery(const BattleInfo *Bi); //TODO
|
CBattleQuery(CGameHandler * owner, const BattleInfo * Bi); //TODO
|
||||||
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
||||||
virtual bool blocksPack(const CPack *pack) const override;
|
virtual bool blocksPack(const CPack *pack) const override;
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color) override;
|
virtual void onRemoval(PlayerColor color) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Created when hero attempts move and something happens
|
//Created when hero attempts move and something happens
|
||||||
//(not necessarily position change, could be just an object interaction).
|
//(not necessarily position change, could be just an object interaction).
|
||||||
class CHeroMovementQuery : public CQuery
|
class CHeroMovementQuery : public CGhQuery
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TryMoveHero tmh;
|
TryMoveHero tmh;
|
||||||
bool visitDestAfterVictory; //if hero moved to guarded tile and it should be visited once guard is defeated
|
bool visitDestAfterVictory; //if hero moved to guarded tile and it should be visited once guard is defeated
|
||||||
const CGHeroInstance *hero;
|
const CGHeroInstance *hero;
|
||||||
|
|
||||||
virtual void onExposure(CGameHandler *gh, QueryPtr topQuery) override;
|
virtual void onExposure(QueryPtr topQuery) override;
|
||||||
|
|
||||||
CHeroMovementQuery(const TryMoveHero &Tmh, const CGHeroInstance *Hero, bool VisitDestAfterVictory = false);
|
CHeroMovementQuery(CGameHandler * owner, const TryMoveHero & Tmh, const CGHeroInstance * Hero, bool VisitDestAfterVictory = false);
|
||||||
virtual void onAdding(CGameHandler *gh, PlayerColor color) override;
|
virtual void onAdding(PlayerColor color) override;
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color) override;
|
virtual void onRemoval(PlayerColor color) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDialogQuery : public CQuery
|
class CDialogQuery : public CGhQuery
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
boost::optional<ui32> answer;
|
CDialogQuery(CGameHandler * owner);
|
||||||
virtual bool endsByPlayerAnswer() const override;
|
virtual bool endsByPlayerAnswer() const override;
|
||||||
virtual bool blocksPack(const CPack *pack) const override;
|
virtual bool blocksPack(const CPack *pack) const override;
|
||||||
|
void setReply(const JsonNode & reply) override;
|
||||||
|
protected:
|
||||||
|
boost::optional<ui32> answer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CGarrisonDialogQuery : public CDialogQuery //used also for hero exchange dialogs
|
class CGarrisonDialogQuery : public CDialogQuery //used also for hero exchange dialogs
|
||||||
@ -114,7 +127,7 @@ class CGarrisonDialogQuery : public CDialogQuery //used also for hero exchange d
|
|||||||
public:
|
public:
|
||||||
std::array<const CArmedInstance *,2> exchangingArmies;
|
std::array<const CArmedInstance *,2> exchangingArmies;
|
||||||
|
|
||||||
CGarrisonDialogQuery(const CArmedInstance *up, const CArmedInstance *down);
|
CGarrisonDialogQuery(CGameHandler * owner, const CArmedInstance *up, const CArmedInstance *down);
|
||||||
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
||||||
virtual bool blocksPack(const CPack *pack) const override;
|
virtual bool blocksPack(const CPack *pack) const override;
|
||||||
};
|
};
|
||||||
@ -125,7 +138,7 @@ class CBlockingDialogQuery : public CDialogQuery
|
|||||||
public:
|
public:
|
||||||
BlockingDialog bd; //copy of pack... debug purposes
|
BlockingDialog bd; //copy of pack... debug purposes
|
||||||
|
|
||||||
CBlockingDialogQuery(const BlockingDialog &bd);
|
CBlockingDialogQuery(CGameHandler * owner, const BlockingDialog &bd);
|
||||||
|
|
||||||
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
||||||
};
|
};
|
||||||
@ -135,7 +148,7 @@ class CTeleportDialogQuery : public CDialogQuery
|
|||||||
public:
|
public:
|
||||||
TeleportDialog td; //copy of pack... debug purposes
|
TeleportDialog td; //copy of pack... debug purposes
|
||||||
|
|
||||||
CTeleportDialogQuery(const TeleportDialog &td);
|
CTeleportDialogQuery(CGameHandler * owner, const TeleportDialog &td);
|
||||||
|
|
||||||
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
||||||
};
|
};
|
||||||
@ -143,27 +156,61 @@ public:
|
|||||||
class CHeroLevelUpDialogQuery : public CDialogQuery
|
class CHeroLevelUpDialogQuery : public CDialogQuery
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CHeroLevelUpDialogQuery(const HeroLevelUp &Hlu);
|
CHeroLevelUpDialogQuery(CGameHandler * owner, const HeroLevelUp &Hlu);
|
||||||
|
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color) override;
|
virtual void onRemoval(PlayerColor color) override;
|
||||||
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
||||||
|
|
||||||
HeroLevelUp hlu;
|
HeroLevelUp hlu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CCommanderLevelUpDialogQuery : public CDialogQuery
|
class CCommanderLevelUpDialogQuery : public CDialogQuery
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CCommanderLevelUpDialogQuery(const CommanderLevelUp &Clu);
|
CCommanderLevelUpDialogQuery(CGameHandler * owner, const CommanderLevelUp &Clu);
|
||||||
|
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color) override;
|
virtual void onRemoval(PlayerColor color) override;
|
||||||
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
|
||||||
|
|
||||||
CommanderLevelUp clu;
|
CommanderLevelUp clu;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Queries
|
class CMapObjectSelectQuery : public CQuery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMapObjectSelectQuery(Queries * Owner);
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Queries
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
void addQuery(PlayerColor player, QueryPtr query);
|
void addQuery(PlayerColor player, QueryPtr query);
|
||||||
@ -172,7 +219,6 @@ private:
|
|||||||
std::map<PlayerColor, std::vector<QueryPtr>> queries; //player => stack of queries
|
std::map<PlayerColor, std::vector<QueryPtr>> queries; //player => stack of queries
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGameHandler *gh;
|
|
||||||
static boost::mutex mx;
|
static boost::mutex mx;
|
||||||
|
|
||||||
void addQuery(QueryPtr query);
|
void addQuery(QueryPtr query);
|
||||||
|
@ -235,7 +235,7 @@ bool QueryReply::applyGh( CGameHandler *gh )
|
|||||||
COMPLAIN_AND_RETURN("Cannot answer the query with id -1!");
|
COMPLAIN_AND_RETURN("Cannot answer the query with id -1!");
|
||||||
|
|
||||||
assert(vstd::contains(gh->states.players, player));
|
assert(vstd::contains(gh->states.players, player));
|
||||||
return gh->queryReply(qid, answer, player);
|
return gh->queryReply(qid, reply, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MakeAction::applyGh( CGameHandler *gh )
|
bool MakeAction::applyGh( CGameHandler *gh )
|
||||||
@ -275,10 +275,22 @@ bool DigWithHero::applyGh( CGameHandler *gh )
|
|||||||
return gh->dig(gh->getHero(id));
|
return gh->dig(gh->getHero(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CastAdvSpell::applyGh( CGameHandler *gh )
|
bool CastAdvSpell::applyGh(CGameHandler * gh)
|
||||||
{
|
{
|
||||||
ERROR_IF_NOT_OWNS(hid);
|
ERROR_IF_NOT_OWNS(hid);
|
||||||
return gh->castSpell(gh->getHero(hid), sid, pos);
|
|
||||||
|
const CSpell * s = sid.toSpell();
|
||||||
|
if(!s)
|
||||||
|
ERROR_AND_RETURN;
|
||||||
|
const CGHeroInstance * h = gh->getHero(hid);
|
||||||
|
if(!h)
|
||||||
|
ERROR_AND_RETURN;
|
||||||
|
|
||||||
|
auto query = std::make_shared<AdventureSpellCastQuery>(&gh->queries, gh->spellEnv, s, h, pos);
|
||||||
|
|
||||||
|
gh->queries.addQuery(query);
|
||||||
|
gh->queries.popIfTop(query);//if we already can perform cast do it now
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerMessage::applyGh( CGameHandler *gh )
|
bool PlayerMessage::applyGh( CGameHandler *gh )
|
||||||
|
Loading…
Reference in New Issue
Block a user