1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Introduced strongly typed QueryID.

Exchange between heroes is now a proper first-class query. Fixes #1269. #66 should also be finally fully fixed.
VC projects: /Zm flag to fix compilation issues with recent Boost.
This commit is contained in:
Michał W. Urbańczyk 2013-05-27 10:53:28 +00:00
parent 09e2f0f021
commit 79026bdfde
28 changed files with 173 additions and 116 deletions

View File

@ -89,6 +89,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -100,6 +101,7 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -109,6 +111,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -118,6 +121,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>

View File

@ -89,6 +89,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -99,6 +100,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -108,6 +110,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -117,6 +120,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>

View File

@ -611,7 +611,7 @@ void VCAI::tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos)
addVisitableObj(obj); addVisitableObj(obj);
} }
void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2) void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query)
{ {
LOG_TRACE(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
@ -619,6 +619,8 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2)
auto firstHero = cb->getHero(hero1); auto firstHero = cb->getHero(hero1);
auto secondHero = cb->getHero(hero2); auto secondHero = cb->getHero(hero2);
status.addQuery(query, boost::str(boost::format("Exchange between heroes %s and %s") % firstHero->name % secondHero->name));
requestActionASAP([=]() requestActionASAP([=]()
{ {
if (firstHero->getHeroStrength() > secondHero->getHeroStrength() && canGetArmy (firstHero, secondHero)) if (firstHero->getHeroStrength() > secondHero->getHeroStrength() && canGetArmy (firstHero, secondHero))
@ -629,6 +631,8 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2)
completeGoal(CGoal(VISIT_HERO).sethero(firstHero)); //TODO: what if we were visited by other hero in the meantime? completeGoal(CGoal(VISIT_HERO).sethero(firstHero)); //TODO: what if we were visited by other hero in the meantime?
completeGoal(CGoal(VISIT_HERO).sethero(secondHero)); completeGoal(CGoal(VISIT_HERO).sethero(secondHero));
//TODO: exchange artifacts //TODO: exchange artifacts
answerQuery(query, 0);
}); });
} }
@ -843,7 +847,7 @@ void VCAI::yourTurn()
makingTurn = make_unique<boost::thread>(&VCAI::makeTurn, this); makingTurn = make_unique<boost::thread>(&VCAI::makeTurn, this);
} }
void VCAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID) void VCAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID)
{ {
LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID); LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
@ -851,7 +855,7 @@ void VCAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill p
requestActionASAP([=]{ answerQuery(queryID, 0); }); requestActionASAP([=]{ answerQuery(queryID, 0); });
} }
void VCAI::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID) void VCAI::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID)
{ {
LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID); LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
@ -859,7 +863,7 @@ void VCAI::commanderGotLevel (const CCommanderInstance * commander, std::vector<
requestActionASAP([=]{ answerQuery(queryID, 0); }); requestActionASAP([=]{ answerQuery(queryID, 0); });
} }
void VCAI::showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) void VCAI::showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel)
{ {
LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel); LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
@ -879,7 +883,7 @@ void VCAI::showBlockingDialog(const std::string &text, const std::vector<Compone
}); });
} }
void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID) void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID)
{ {
LOG_TRACE_PARAMS(logAi, "removableUnits '%i', queryID '%i'", removableUnits % queryID); LOG_TRACE_PARAMS(logAi, "removableUnits '%i', queryID '%i'", removableUnits % queryID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
@ -2524,10 +2528,10 @@ void VCAI::lostHero(HeroPtr h)
erase_if_present(reservedHeroesMap, h); erase_if_present(reservedHeroesMap, h);
} }
void VCAI::answerQuery(int queryID, int selection) void VCAI::answerQuery(QueryID queryID, int selection)
{ {
logAi->debugStream() << boost::format("I'll answer the query %d giving the choice %d") % queryID % selection; logAi->debugStream() << boost::format("I'll answer the query %d giving the choice %d") % queryID % selection;
if(queryID != -1) if(queryID != QueryID(-1))
{ {
cb->selectionMade(selection, queryID); cb->selectionMade(selection, queryID);
} }
@ -2597,24 +2601,24 @@ BattleState AIStatus::getBattle()
return battle; return battle;
} }
void AIStatus::addQuery(int ID, std::string description) void AIStatus::addQuery(QueryID ID, std::string description)
{ {
boost::unique_lock<boost::mutex> lock(mx); boost::unique_lock<boost::mutex> lock(mx);
if(ID == -1) if(ID == QueryID(-1))
{ {
logAi->debugStream() << boost::format("The \"query\" has an id %d, it'll be ignored as non-query. Description: %s") % ID % description; logAi->debugStream() << boost::format("The \"query\" has an id %d, it'll be ignored as non-query. Description: %s") % ID % description;
return; return;
} }
assert(!vstd::contains(remainingQueries, ID)); assert(!vstd::contains(remainingQueries, ID));
assert(ID >= 0); assert(ID.getNum() >= 0);
remainingQueries[ID] = description; remainingQueries[ID] = description;
cv.notify_all(); cv.notify_all();
logAi->debugStream() << boost::format("Adding query %d - %s. Total queries count: %d") % ID % description % remainingQueries.size(); logAi->debugStream() << boost::format("Adding query %d - %s. Total queries count: %d") % ID % description % remainingQueries.size();
} }
void AIStatus::removeQuery(int ID) void AIStatus::removeQuery(QueryID ID)
{ {
boost::unique_lock<boost::mutex> lock(mx); boost::unique_lock<boost::mutex> lock(mx);
assert(vstd::contains(remainingQueries, ID)); assert(vstd::contains(remainingQueries, ID));
@ -2658,7 +2662,7 @@ bool AIStatus::haveTurn()
return havingTurn; return havingTurn;
} }
void AIStatus::attemptedAnsweringQuery(int queryID, int answerRequestID) void AIStatus::attemptedAnsweringQuery(QueryID queryID, int answerRequestID)
{ {
boost::unique_lock<boost::mutex> lock(mx); boost::unique_lock<boost::mutex> lock(mx);
assert(vstd::contains(remainingQueries, queryID)); assert(vstd::contains(remainingQueries, queryID));
@ -2670,7 +2674,7 @@ void AIStatus::attemptedAnsweringQuery(int queryID, int answerRequestID)
void AIStatus::receivedAnswerConfirmation(int answerRequestID, int result) void AIStatus::receivedAnswerConfirmation(int answerRequestID, int result)
{ {
assert(vstd::contains(requestToQueryID, answerRequestID)); assert(vstd::contains(requestToQueryID, answerRequestID));
int query = requestToQueryID[answerRequestID]; QueryID query = requestToQueryID[answerRequestID];
assert(vstd::contains(remainingQueries, query)); assert(vstd::contains(remainingQueries, query));
requestToQueryID.erase(answerRequestID); requestToQueryID.erase(answerRequestID);

View File

@ -73,8 +73,8 @@ class AIStatus
boost::condition_variable cv; boost::condition_variable cv;
BattleState battle; BattleState battle;
std::map<int, std::string> remainingQueries; std::map<QueryID, std::string> remainingQueries;
std::map<int, int> requestToQueryID; //IDs of answer-requests sent to server => query ids (so we can match answer confirmation from server to the query) std::map<int, QueryID> requestToQueryID; //IDs of answer-requests sent to server => query ids (so we can match answer confirmation from server to the query)
bool havingTurn; bool havingTurn;
@ -83,14 +83,14 @@ public:
~AIStatus(); ~AIStatus();
void setBattle(BattleState BS); void setBattle(BattleState BS);
BattleState getBattle(); BattleState getBattle();
void addQuery(int ID, std::string description); void addQuery(QueryID ID, std::string description);
void removeQuery(int ID); void removeQuery(QueryID ID);
int getQueriesCount(); int getQueriesCount();
void startedTurn(); void startedTurn();
void madeTurn(); void madeTurn();
void waitTillFree(); void waitTillFree();
bool haveTurn(); bool haveTurn();
void attemptedAnsweringQuery(int queryID, int answerRequestID); void attemptedAnsweringQuery(QueryID queryID, int answerRequestID);
void receivedAnswerConfirmation(int answerRequestID, int result); void receivedAnswerConfirmation(int answerRequestID, int result);
@ -309,10 +309,10 @@ public:
virtual void init(CCallback * CB) OVERRIDE; virtual void init(CCallback * CB) OVERRIDE;
virtual void yourTurn() OVERRIDE; virtual void yourTurn() OVERRIDE;
virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID) OVERRIDE; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) OVERRIDE; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID) OVERRIDE; //TODO virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) OVERRIDE; //TODO
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 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, int 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 saveGame(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving virtual void saveGame(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
virtual void loadGame(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading virtual void loadGame(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
virtual void finish() OVERRIDE; virtual void finish() OVERRIDE;
@ -339,7 +339,7 @@ public:
virtual void availableArtifactsChanged(const CGBlackMarket *bm = NULL) OVERRIDE; virtual void availableArtifactsChanged(const CGBlackMarket *bm = NULL) OVERRIDE;
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) OVERRIDE; virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) OVERRIDE;
virtual void tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos) OVERRIDE; virtual void tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos) OVERRIDE;
virtual void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2) OVERRIDE; virtual void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) OVERRIDE;
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE; virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE;
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE; virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE;
virtual void heroMovePointsChanged(const CGHeroInstance * hero) OVERRIDE; virtual void heroMovePointsChanged(const CGHeroInstance * hero) OVERRIDE;
@ -425,7 +425,7 @@ public:
void checkHeroArmy (HeroPtr h); void checkHeroArmy (HeroPtr h);
void requestSent(const CPackForServer *pack, int requestID) OVERRIDE; void requestSent(const CPackForServer *pack, int requestID) OVERRIDE;
void answerQuery(int queryID, int selection); void answerQuery(QueryID queryID, int selection);
//special function that can be called ONLY from game events handling thread and will send request ASAP //special function that can be called ONLY from game events handling thread and will send request ASAP
void requestActionASAP(boost::function<void()> whatToDo); void requestActionASAP(boost::function<void()> whatToDo);

View File

@ -56,10 +56,10 @@ bool CCallback::moveHero(const CGHeroInstance *h, int3 dst)
return true; return true;
} }
int CCallback::selectionMade(int selection, int queryID) int CCallback::selectionMade(int selection, QueryID queryID)
{ {
ASSERT_IF_CALLED_WITH_PLAYER ASSERT_IF_CALLED_WITH_PLAYER
if(queryID == -1) if(queryID == QueryID(-1))
{ {
logGlobal->errorStream() << "Cannot answer the query -1!"; logGlobal->errorStream() << "Cannot answer the query -1!";
return false; return false;

View File

@ -56,7 +56,7 @@ public:
virtual void trade(const CGObjectInstance *market, EMarketMode::EMarketMode mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL)=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 = NULL)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
virtual int selectionMade(int selection, int queryID) =0; virtual int selectionMade(int selection, 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
@ -117,7 +117,7 @@ public:
//commands //commands
bool moveHero(const CGHeroInstance *h, int3 dst); //dst must be free, neighbouring tile (this function can move hero only by one tile) bool moveHero(const CGHeroInstance *h, int3 dst); //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, int queryID); int selectionMade(int selection, QueryID queryID);
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2);
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, SlotID p1, SlotID p2); //first goes to the second

View File

@ -843,6 +843,10 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
if(h && key.state == SDL_PRESSED) if(h && key.state == SDL_PRESSED)
{ {
auto unlockPim = vstd::makeUnlockGuard(*LOCPLINT->pim); auto unlockPim = vstd::makeUnlockGuard(*LOCPLINT->pim);
//TODO!!!!!!! possible freeze, when GS mutex is locked and network thread can't apply package
//this thread leaves scope and tries to lock pim while holding gs,
//network thread tries to lock gs (appluy cl) while holding pim
//this thread should first lock pim, however gs locking/unlocking is done inside cb
LOCPLINT->cb->moveHero(h,h->pos); LOCPLINT->cb->moveHero(h,h->pos);
} }
} }

View File

@ -1203,7 +1203,7 @@ void HeroSlots::splitClicked()
{ {
if(!!town->visitingHero && town->garrisonHero && (visitingHero->selection || garrisonedHero->selection)) if(!!town->visitingHero && town->garrisonHero && (visitingHero->selection || garrisonedHero->selection))
{ {
LOCPLINT->heroExchangeStarted(town->visitingHero->id, town->garrisonHero->id); LOCPLINT->heroExchangeStarted(town->visitingHero->id, town->garrisonHero->id, QueryID(-1));
} }
} }

View File

@ -471,7 +471,7 @@ void CPlayerInterface::receivedResource(int type, int val)
GH.totalRedraw(); GH.totalRedraw();
} }
void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill>& skills, int queryID) void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill>& skills, QueryID queryID)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
waitWhileDialog(); waitWhileDialog();
@ -481,7 +481,7 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::Pr
[=](ui32 selection){ cb->selectionMade(selection, queryID); }); [=](ui32 selection){ cb->selectionMade(selection, queryID); });
GH.pushInt(lw); GH.pushInt(lw);
} }
void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID) void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
waitWhileDialog(); waitWhileDialog();
@ -1016,7 +1016,7 @@ void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<vo
CInfoWindow::showYesNoDialog(text, &components, onYes, onNo, DelComps, playerID); CInfoWindow::showYesNoDialog(text, &components, onYes, onNo, DelComps, playerID);
} }
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel ) void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, QueryID askID, int soundID, bool selection, bool cancel )
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
waitWhileDialog(); waitWhileDialog();
@ -1324,7 +1324,7 @@ bool CPlayerInterface::altPressed() const
return SDL_GetKeyState(NULL)[SDLK_LALT] || SDL_GetKeyState(NULL)[SDLK_RALT]; return SDL_GetKeyState(NULL)[SDLK_LALT] || SDL_GetKeyState(NULL)[SDLK_RALT];
} }
void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID) void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
auto onEnd = [=]{ cb->selectionMade(0, queryID); }; auto onEnd = [=]{ cb->selectionMade(0, queryID); };
@ -1384,10 +1384,10 @@ void CPlayerInterface::requestRealized( PackageApplied *pa )
stillMoveHero.setn(CONTINUE_MOVE); stillMoveHero.setn(CONTINUE_MOVE);
} }
void CPlayerInterface::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2) void CPlayerInterface::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
GH.pushInt(new CExchangeWindow(hero1, hero2)); GH.pushInt(new CExchangeWindow(hero1, hero2, query));
} }
void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop) void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)

View File

@ -143,8 +143,8 @@ public:
void artifactDisassembled(const ArtifactLocation &al); void artifactDisassembled(const ArtifactLocation &al);
void heroCreated(const CGHeroInstance* hero) OVERRIDE; void heroCreated(const CGHeroInstance* hero) OVERRIDE;
void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID) OVERRIDE; void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) OVERRIDE;
void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID) OVERRIDE; void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) OVERRIDE;
void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE; void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE;
void heroMoved(const TryMoveHero & details) OVERRIDE; void heroMoved(const TryMoveHero & details) OVERRIDE;
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE; void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE;
@ -156,8 +156,8 @@ public:
void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) OVERRIDE; void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) OVERRIDE;
void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE; void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE;
void showShipyardDialog(const IShipyard *obj) OVERRIDE; //obj may be town or shipyard; void showShipyardDialog(const IShipyard *obj) OVERRIDE; //obj may be town or shipyard;
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, 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, 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 showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID) OVERRIDE; void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) OVERRIDE;
void showPuzzleMap() OVERRIDE; void showPuzzleMap() OVERRIDE;
void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE; void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE;
void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE; void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE;
@ -175,7 +175,7 @@ public:
void heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain) OVERRIDE;//if gain hero received bonus, else he lost it void heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain) OVERRIDE;//if gain hero received bonus, else he lost it
void playerBonusChanged(const Bonus &bonus, bool gain) OVERRIDE; void playerBonusChanged(const Bonus &bonus, bool gain) OVERRIDE;
void requestRealized(PackageApplied *pa) OVERRIDE; void requestRealized(PackageApplied *pa) OVERRIDE;
void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2) OVERRIDE; void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) OVERRIDE;
void centerView (int3 pos, int focusTime) OVERRIDE; void centerView (int3 pos, int focusTime) OVERRIDE;
void objectPropertyChanged(const SetObjectProperty * sop) OVERRIDE; void objectPropertyChanged(const SetObjectProperty * sop) OVERRIDE;
void objectRemoved(const CGObjectInstance *obj) OVERRIDE; void objectRemoved(const CGObjectInstance *obj) OVERRIDE;

View File

@ -653,7 +653,7 @@ CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
type |= BLOCK_ADV_HOTKEYS; type |= BLOCK_ADV_HOTKEYS;
ID = -1; ID = QueryID(-1);
for(int i=0;i<Buttons.size();i++) for(int i=0;i<Buttons.size();i++)
{ {
CAdventureMapButton *button = new CAdventureMapButton("","",boost::bind(&CInfoWindow::close,this),0,0,Buttons[i].first); CAdventureMapButton *button = new CAdventureMapButton("","",boost::bind(&CInfoWindow::close,this),0,0,Buttons[i].first);
@ -689,7 +689,7 @@ CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo
CInfoWindow::CInfoWindow() CInfoWindow::CInfoWindow()
{ {
ID = -1; ID = QueryID(-1);
setDelComps(false); setDelComps(false);
text = NULL; text = NULL;
} }
@ -1262,14 +1262,14 @@ void CSelWindow::selectionChange(unsigned to)
redraw(); redraw();
} }
CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperline, const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID) CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperline, const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, QueryID askID)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
ID = askID; ID = askID;
for(int i=0;i<Buttons.size();i++) for(int i=0;i<Buttons.size();i++)
{ {
buttons.push_back(new CAdventureMapButton("","",Buttons[i].second,0,0,Buttons[i].first)); buttons.push_back(new CAdventureMapButton("","",Buttons[i].second,0,0,Buttons[i].first));
if(!i && askID >= 0) if(!i && askID.getNum() >= 0)
buttons.back()->callback += boost::bind(&CSelWindow::madeChoice,this); buttons.back()->callback += boost::bind(&CSelWindow::madeChoice,this);
buttons[i]->callback += boost::bind(&CInfoWindow::close,this); //each button will close the window apart from call-defined actions buttons[i]->callback += boost::bind(&CInfoWindow::close,this); //each button will close the window apart from call-defined actions
} }
@ -1279,7 +1279,7 @@ CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperl
buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter
buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape
if(buttons.size() > 1 && askID >= 0) //cancel button functionality if(buttons.size() > 1 && askID.getNum() >= 0) //cancel button functionality
buttons.back()->callback += boost::bind(&CCallback::selectionMade,LOCPLINT->cb,0,askID); buttons.back()->callback += boost::bind(&CCallback::selectionMade,LOCPLINT->cb,0,askID);
for(int i=0;i<comps.size();i++) for(int i=0;i<comps.size();i++)
@ -1296,7 +1296,7 @@ CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperl
void CSelWindow::madeChoice() void CSelWindow::madeChoice()
{ {
if(ID < 0) if(ID.getNum() < 0)
return; return;
int ret = -1; int ret = -1;
for (int i=0;i<components.size();i++) for (int i=0;i<components.size();i++)
@ -5078,7 +5078,7 @@ void CExchangeWindow::prepareBackground()
new CAnimImage("PortraitsLarge", heroInst[1]->portrait, 0, 485, 13); new CAnimImage("PortraitsLarge", heroInst[1]->portrait, 0, 485, 13);
} }
CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2): CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID queryID):
CWindowObject(PLAYER_COLORED | BORDERED, "TRADE2") CWindowObject(PLAYER_COLORED | BORDERED, "TRADE2")
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
@ -5165,6 +5165,9 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2)
//buttons //buttons
quit = new CAdventureMapButton(CGI->generaltexth->zelp[600], boost::bind(&CExchangeWindow::close, this), 732, 567, "IOKAY.DEF", SDLK_RETURN); quit = new CAdventureMapButton(CGI->generaltexth->zelp[600], boost::bind(&CExchangeWindow::close, this), 732, 567, "IOKAY.DEF", SDLK_RETURN);
if(queryID.getNum() > 0)
quit->callback += [=]{ LOCPLINT->cb->selectionMade(0, queryID); };
questlogButton[0] = new CAdventureMapButton(CGI->generaltexth->heroscrn[0], "", boost::bind(&CExchangeWindow::questlog,this, 0), 10, 44, "hsbtns4.def"); questlogButton[0] = new CAdventureMapButton(CGI->generaltexth->heroscrn[0], "", boost::bind(&CExchangeWindow::questlog,this, 0), 10, 44, "hsbtns4.def");
questlogButton[1] = new CAdventureMapButton(CGI->generaltexth->heroscrn[0], "", boost::bind(&CExchangeWindow::questlog,this, 1), 740, 44, "hsbtns4.def"); questlogButton[1] = new CAdventureMapButton(CGI->generaltexth->heroscrn[0], "", boost::bind(&CExchangeWindow::questlog,this, 1), 740, 44, "hsbtns4.def");

View File

@ -87,7 +87,7 @@ class CInfoWindow : public CSimpleWindow
public: public:
typedef std::vector<std::pair<std::string,CFunctionList<void()> > > TButtonsInfo; typedef std::vector<std::pair<std::string,CFunctionList<void()> > > TButtonsInfo;
typedef std::vector<CComponent*> TCompsInfo; typedef std::vector<CComponent*> TCompsInfo;
int ID; //for identification QueryID ID; //for identification
CTextBox *text; CTextBox *text;
std::vector<CAdventureMapButton *> buttons; std::vector<CAdventureMapButton *> buttons;
std::vector<CComponent*> components; std::vector<CComponent*> components;
@ -117,7 +117,7 @@ class CSelWindow : public CInfoWindow
public: public:
void selectionChange(unsigned to); void selectionChange(unsigned to);
void madeChoice(); //looks for selected component and calls callback void madeChoice(); //looks for selected component and calls callback
CSelWindow(const std::string& text, PlayerColor player, int charperline ,const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID); //c-tor CSelWindow(const std::string& text, PlayerColor player, int charperline ,const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, QueryID askID); //c-tor
CSelWindow(){}; //c-tor CSelWindow(){}; //c-tor
//notification - this class inherits important destructor from CInfoWindow //notification - this class inherits important destructor from CInfoWindow
}; };
@ -1034,7 +1034,7 @@ public:
void prepareBackground(); //prepares or redraws bg void prepareBackground(); //prepares or redraws bg
CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2); //c-tor CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID queryID); //c-tor
~CExchangeWindow(); //d-tor ~CExchangeWindow(); //d-tor
}; };

View File

@ -588,6 +588,12 @@ void GarrisonDialog::applyCl(CClient *cl)
cl->playerint[h->getOwner()]->showGarrisonDialog(obj,h,removableUnits,queryID); cl->playerint[h->getOwner()]->showGarrisonDialog(obj,h,removableUnits,queryID);
} }
void ExchangeDialog::applyCl(CClient *cl)
{
assert(heroes[0] && heroes[1]);
INTERFACE_CALL_IF_PRESENT(heroes[0]->tempOwner, heroExchangeStarted, heroes[0]->id, heroes[1]->id, queryID);
}
void BattleStart::applyCl( CClient *cl ) void BattleStart::applyCl( CClient *cl )
{ {
cl->battleStarted(info); cl->battleStarted(info);
@ -829,14 +835,6 @@ void OpenWindow::applyCl(CClient *cl)
{ {
switch(window) switch(window)
{ {
case EXCHANGE_WINDOW:
{
const CGHeroInstance *h = cl->getHero(ObjectInstanceID(id1));
const CGObjectInstance *h2 = cl->getHero(ObjectInstanceID(id2));
assert(h && h2);
INTERFACE_CALL_IF_PRESENT(h->tempOwner,heroExchangeStarted, ObjectInstanceID(id1), ObjectInstanceID(id2));
}
break;
case RECRUITMENT_FIRST: case RECRUITMENT_FIRST:
case RECRUITMENT_ALL: case RECRUITMENT_ALL:
{ {

View File

@ -94,13 +94,13 @@
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<AdditionalOptions>/MP4 %(AdditionalOptions)</AdditionalOptions>
<Optimization> <Optimization>
</Optimization> </Optimization>
<DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings> <DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<AssemblerOutput>NoListing</AssemblerOutput> <AssemblerOutput>NoListing</AssemblerOutput>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -114,13 +114,13 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<AdditionalOptions>/MP4 %(AdditionalOptions)</AdditionalOptions>
<PreprocessToFile>false</PreprocessToFile> <PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers> <PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
<DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings> <DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<AssemblerOutput>NoListing</AssemblerOutput> <AssemblerOutput>NoListing</AssemblerOutput>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -136,6 +136,7 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -147,7 +148,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
<ClCompile> <ClCompile>
<AdditionalOptions>/Oy- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
</ClCompile> </ClCompile>

View File

@ -2,10 +2,6 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<ClCompile Include="AdventureMapClasses.cpp" /> <ClCompile Include="AdventureMapClasses.cpp" />
<ClCompile Include="BattleInterface\CBattleAnimations.cpp" />
<ClCompile Include="BattleInterface\CBattleInterface.cpp" />
<ClCompile Include="BattleInterface\CBattleInterfaceClasses.cpp" />
<ClCompile Include="BattleInterface\CCreatureAnimation.cpp" />
<ClCompile Include="CAdvmapInterface.cpp" /> <ClCompile Include="CAdvmapInterface.cpp" />
<ClCompile Include="CAnimation.cpp" /> <ClCompile Include="CAnimation.cpp" />
<ClCompile Include="..\CCallback.cpp" /> <ClCompile Include="..\CCallback.cpp" />
@ -29,22 +25,22 @@
<ClCompile Include="mapHandler.cpp" /> <ClCompile Include="mapHandler.cpp" />
<ClCompile Include="NetPacksClient.cpp" /> <ClCompile Include="NetPacksClient.cpp" />
<ClCompile Include="StdInc.cpp" /> <ClCompile Include="StdInc.cpp" />
<ClCompile Include="UIFramework\CCursorHandler.cpp" />
<ClCompile Include="UIFramework\CGuiHandler.cpp" />
<ClCompile Include="UIFramework\CIntObject.cpp" />
<ClCompile Include="UIFramework\CIntObjectClasses.cpp" />
<ClCompile Include="UIFramework\Geometries.cpp" />
<ClCompile Include="UIFramework\SDL_Extensions.cpp" />
<ClCompile Include="CQuestLog.cpp" /> <ClCompile Include="CQuestLog.cpp" />
<ClCompile Include="UIFramework\Fonts.cpp" /> <ClCompile Include="battle\CBattleAnimations.cpp" />
<ClCompile Include="battle\CBattleInterface.cpp" />
<ClCompile Include="battle\CBattleInterfaceClasses.cpp" />
<ClCompile Include="battle\CCreatureAnimation.cpp" />
<ClCompile Include="gui\CCursorHandler.cpp" />
<ClCompile Include="gui\CGuiHandler.cpp" />
<ClCompile Include="gui\CIntObject.cpp" />
<ClCompile Include="gui\CIntObjectClasses.cpp" />
<ClCompile Include="gui\Fonts.cpp" />
<ClCompile Include="gui\Geometries.cpp" />
<ClCompile Include="gui\SDL_Extensions.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\Global.h" /> <ClInclude Include="..\Global.h" />
<ClInclude Include="AdventureMapClasses.h" /> <ClInclude Include="AdventureMapClasses.h" />
<ClInclude Include="BattleInterface\CBattleAnimations.h" />
<ClInclude Include="BattleInterface\CBattleInterface.h" />
<ClInclude Include="BattleInterface\CBattleInterfaceClasses.h" />
<ClInclude Include="BattleInterface\CCreatureAnimation.h" />
<ClInclude Include="CAdvmapInterface.h" /> <ClInclude Include="CAdvmapInterface.h" />
<ClInclude Include="CAnimation.h" /> <ClInclude Include="CAnimation.h" />
<ClInclude Include="CBitmapHandler.h" /> <ClInclude Include="CBitmapHandler.h" />
@ -69,19 +65,23 @@
<ClInclude Include="GUIClasses.h" /> <ClInclude Include="GUIClasses.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="StdInc.h" /> <ClInclude Include="StdInc.h" />
<ClInclude Include="UIFramework\CCursorHandler.h" />
<ClInclude Include="UIFramework\CGuiHandler.h" />
<ClInclude Include="UIFramework\CIntObject.h" />
<ClInclude Include="UIFramework\CIntObjectClasses.h" />
<ClInclude Include="UIFramework\Geometries.h" />
<ClInclude Include="UIFramework\SDL_Extensions.h" />
<ClInclude Include="UIFramework\SDL_Pixels.h" />
<ClInclude Include="CQuestLog.h" /> <ClInclude Include="CQuestLog.h" />
<ClCompile Include="CQuestLog.cpp"> <ClCompile Include="CQuestLog.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClInclude Include="mapHandler.h" /> <ClInclude Include="mapHandler.h" />
<ClInclude Include="UIFramework\Fonts.h" /> <ClInclude Include="battle\CBattleAnimations.h" />
<ClInclude Include="battle\CBattleInterface.h" />
<ClInclude Include="battle\CBattleInterfaceClasses.h" />
<ClInclude Include="battle\CCreatureAnimation.h" />
<ClInclude Include="gui\CCursorHandler.h" />
<ClInclude Include="gui\CGuiHandler.h" />
<ClInclude Include="gui\CIntObject.h" />
<ClInclude Include="gui\CIntObjectClasses.h" />
<ClInclude Include="gui\Fonts.h" />
<ClInclude Include="gui\Geometries.h" />
<ClInclude Include="gui\SDL_Extensions.h" />
<ClInclude Include="gui\SDL_Pixels.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="VCMI_client.rc" /> <ResourceCompile Include="VCMI_client.rc" />

View File

@ -80,16 +80,16 @@ public:
virtual void yourTurn(){}; //called AFTER playerStartsTurn(player) virtual void yourTurn(){}; //called AFTER playerStartsTurn(player)
//pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID)=0; virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID)=0;
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID)=0; virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID)=0;
// Show a dialog, player must take decision. If selection then he has to choose between one of given components, // 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 // 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. // 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, ui32 askID, const int soundID, bool selection, bool cancel) = 0; virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) = 0;
// 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, int queryID) = 0; virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) = 0;
virtual void finish(){}; //if for some reason we want to end virtual void finish(){}; //if for some reason we want to end
}; };

View File

@ -723,6 +723,12 @@ public:
for(ui32 i=0;i<length;i++) for(ui32 i=0;i<length;i++)
*this << data[i]; *this << data[i];
} }
template <typename T, size_t N>
void saveSerializable(const std::array<T, N> &data)
{
for(ui32 i=0; i < N; i++)
*this << data[i];
}
template <typename T> template <typename T>
void saveSerializable(const std::set<T> &data) void saveSerializable(const std::set<T> &data)
{ {
@ -1077,6 +1083,12 @@ public:
for(ui32 i=0;i<length;i++) for(ui32 i=0;i<length;i++)
*this >> data[i]; *this >> data[i];
} }
template <typename T, size_t N>
void loadSerializable(std::array<T, N> &data)
{
for(ui32 i = 0; i < N; i++)
*this >> data[i];
}
template <typename T> template <typename T>
void loadSerializable(std::set<T> &data) void loadSerializable(std::set<T> &data)
{ {

View File

@ -183,6 +183,17 @@ class ArtifactInstanceID : public BaseForID<ArtifactInstanceID, si32>
}; };
class QueryID : public BaseForID<QueryID, si32>
{
INSTID_LIKE_CLASS_COMMON(QueryID, si32)
QueryID & operator++()
{
++num;
return *this;
}
};
class ObjectInstanceID : public BaseForID<ObjectInstanceID, si32> class ObjectInstanceID : public BaseForID<ObjectInstanceID, si32>
{ {
INSTID_LIKE_CLASS_COMMON(ObjectInstanceID, si32) INSTID_LIKE_CLASS_COMMON(ObjectInstanceID, si32)

View File

@ -124,11 +124,13 @@ public:
virtual void playerBonusChanged(const Bonus &bonus, bool gain){};//if gain hero received bonus, else he lost it virtual void playerBonusChanged(const Bonus &bonus, bool gain){};//if gain hero received bonus, else he lost it
virtual void requestSent(const CPackForServer *pack, int requestID){}; virtual void requestSent(const CPackForServer *pack, int requestID){};
virtual void requestRealized(PackageApplied *pa){}; virtual void requestRealized(PackageApplied *pa){};
virtual void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2){};
virtual void objectPropertyChanged(const SetObjectProperty * sop){}; //eg. mine has been flagged virtual void objectPropertyChanged(const SetObjectProperty * sop){}; //eg. mine has been flagged
virtual void objectRemoved(const CGObjectInstance *obj){}; //eg. collected resource, picked artifact, beaten hero virtual void objectRemoved(const CGObjectInstance *obj){}; //eg. collected resource, picked artifact, beaten hero
virtual void playerBlocked(int reason){}; //reason: 0 - upcoming battle virtual void playerBlocked(int reason){}; //reason: 0 - upcoming battle
virtual void gameOver(PlayerColor player, bool victory){}; //player lost or won the game virtual void gameOver(PlayerColor player, bool victory){}; //player lost or won the game
virtual void playerStartsTurn(PlayerColor player){}; virtual void playerStartsTurn(PlayerColor player){};
virtual void showComp(const Component &comp, std::string message) {}; //display component in the advmapint infobox virtual void showComp(const Component &comp, std::string message) {}; //display component in the advmapint infobox
//TODO shouldnt be moved down the tree?
virtual void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID queryID){};
}; };

View File

@ -81,11 +81,10 @@ struct CPackForServer : public CPack
struct Query : public CPackForClient struct Query : public CPackForClient
{ {
ui32 queryID; // equals to -1 if it is not an actual query (and should not be answered) QueryID queryID; // equals to -1 if it is not an actual query (and should not be answered)
Query() Query()
{ {
queryID = -1;
} }
}; };
@ -1326,6 +1325,19 @@ struct GarrisonDialog : public Query//2004
} }
}; };
struct ExchangeDialog : public Query//2005
{
ExchangeDialog(){type = 2005;}
void applyCl(CClient *cl);
std::array<const CGHeroInstance*, 2> heroes;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & queryID & heroes;
}
};
struct BattleInfo; struct BattleInfo;
struct BattleStart : public CPackForClient//3000 struct BattleStart : public CPackForClient//3000
{ {
@ -2053,8 +2065,9 @@ struct BuildBoat : public CPackForServer
struct QueryReply : public CPackForServer struct QueryReply : public CPackForServer
{ {
QueryReply(){type = 6000;}; QueryReply(){type = 6000;};
QueryReply(ui32 QID, ui32 Answer):qid(QID),answer(Answer){type = 6000;}; QueryReply(QueryID QID, ui32 Answer):qid(QID),answer(Answer){type = 6000;};
ui32 qid, answer; //hero and artifact id QueryID qid;
ui32 answer; //hero and artifact id
PlayerColor player; PlayerColor player;
bool applyGh(CGameHandler *gh); bool applyGh(CGameHandler *gh);

View File

@ -160,6 +160,7 @@ void registerTypes2(Serializer &s)
s.template registerType<SetCommanderProperty>(); s.template registerType<SetCommanderProperty>();
s.template registerType<BlockingDialog>(); s.template registerType<BlockingDialog>();
s.template registerType<GarrisonDialog>(); s.template registerType<GarrisonDialog>();
s.template registerType<ExchangeDialog>();
s.template registerType<BattleStart>(); s.template registerType<BattleStart>();
s.template registerType<BattleNextRound>(); s.template registerType<BattleNextRound>();
s.template registerType<BattleSetActiveStack>(); s.template registerType<BattleSetActiveStack>();

View File

@ -95,7 +95,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<AdditionalOptions>/MP4 %(AdditionalOptions) /bigobj <AdditionalOptions>/MP4 %(AdditionalOptions) /bigobj
</AdditionalOptions> /Zm150</AdditionalOptions>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
@ -119,7 +119,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<AdditionalOptions>/MP4 %(AdditionalOptions) /bigobj <AdditionalOptions>/MP4 %(AdditionalOptions) /bigobj
</AdditionalOptions> /Zm150</AdditionalOptions>
<DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings> <DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ExpandAttributedSource>false</ExpandAttributedSource> <ExpandAttributedSource>false</ExpandAttributedSource>
<AssemblerOutput>NoListing</AssemblerOutput> <AssemblerOutput>NoListing</AssemblerOutput>
@ -133,7 +133,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">
<ClCompile> <ClCompile>
<AdditionalOptions>/Oy- %(AdditionalOptions) /bigobj <AdditionalOptions>/Oy- %(AdditionalOptions) /bigobj
</AdditionalOptions> /Zm150</AdditionalOptions>
<PreprocessorDefinitions>VCMI_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>VCMI_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@ -149,7 +149,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
<ClCompile> <ClCompile>
<AdditionalOptions>/Oy- %(AdditionalOptions) /bigobj <AdditionalOptions>/Oy- %(AdditionalOptions) /bigobj
</AdditionalOptions> /Zm150</AdditionalOptions>
<PreprocessorDefinitions>VCMI_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>VCMI_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>

View File

@ -27,27 +27,27 @@
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v100</PlatformToolset> <PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset> <PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v100</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">

View File

@ -2119,17 +2119,18 @@ void CGameHandler::useScholarSkill(ObjectInstanceID fromHero, ObjectInstanceID t
void CGameHandler::heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) void CGameHandler::heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)
{ {
PlayerColor player1 = getHero(hero1)->tempOwner; auto h1 = getHero(hero1), h2 = getHero(hero2);
PlayerColor player2 = getHero(hero2)->tempOwner;
if( gameState()->getPlayerRelations( player1, player2)) if( gameState()->getPlayerRelations(h1->getOwner(), h2->getOwner()))
{ {
OpenWindow hex; auto exchange = make_shared<CGarrisonDialogQuery>(h1, h2);
hex.window = OpenWindow::EXCHANGE_WINDOW; ExchangeDialog hex;
hex.id1 = hero1.getNum(); hex.queryID = exchange->queryID;
hex.id2 = hero2.getNum(); hex.heroes[0] = getHero(hero1);
hex.heroes[1] = getHero(hero2);
sendAndApply(&hex); sendAndApply(&hex);
useScholarSkill(hero1,hero2); useScholarSkill(hero1,hero2);
queries.addQuery(exchange);
} }
} }
@ -3204,7 +3205,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor pl
return true; return true;
} }
bool CGameHandler::queryReply(ui32 qid, ui32 answer, PlayerColor player) bool CGameHandler::queryReply(QueryID qid, ui32 answer, PlayerColor player)
{ {
boost::unique_lock<boost::recursive_mutex> lock(gsm); boost::unique_lock<boost::recursive_mutex> lock(gsm);

View File

@ -207,7 +207,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( ui32 qid, ui32 answer, PlayerColor player ); bool queryReply( QueryID qid, ui32 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 );

View File

@ -37,7 +37,7 @@ CQuery::CQuery(void)
{ {
boost::unique_lock<boost::mutex> l(Queries::mx); boost::unique_lock<boost::mutex> l(Queries::mx);
static TQueryID QID = 1; static QueryID QID = QueryID(1);
queryID = QID++; queryID = QID++;
logGlobal->traceStream() << "Created a new query with id " << queryID; logGlobal->traceStream() << "Created a new query with id " << queryID;

View File

@ -12,7 +12,6 @@ class CObjectVisitQuery;
struct TryMoveHero; struct TryMoveHero;
class CQuery; class CQuery;
typedef si32 TQueryID;
typedef shared_ptr<CQuery> QueryPtr; typedef shared_ptr<CQuery> QueryPtr;
// This class represents any kind of prolonged interaction that may need to do something special after it is over. // This class represents any kind of prolonged interaction that may need to do something special after it is over.
@ -29,7 +28,7 @@ protected:
void addPlayer(PlayerColor color); 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
TQueryID queryID; QueryID queryID;
CQuery(void); CQuery(void);
@ -109,7 +108,7 @@ public:
virtual bool blocksPack(const CPack *pack) const OVERRIDE; virtual bool blocksPack(const CPack *pack) const OVERRIDE;
}; };
class CGarrisonDialogQuery : public CDialogQuery class CGarrisonDialogQuery : public CDialogQuery //used also for hero exchange dialogs
{ {
public: public:
std::array<const CArmedInstance *,2> exchangingArmies; std::array<const CArmedInstance *,2> exchangingArmies;

View File

@ -232,7 +232,7 @@ bool QueryReply::applyGh( CGameHandler *gh )
COMPLAIN_AND_RETURN("No such player!"); COMPLAIN_AND_RETURN("No such player!");
if(playerToConnection->second != c) if(playerToConnection->second != c)
COMPLAIN_AND_RETURN("Message came from wrong connection!"); COMPLAIN_AND_RETURN("Message came from wrong connection!");
if(qid == -1) if(qid == QueryID(-1))
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));