1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -100,6 +101,7 @@
<Optimization>Disabled</Optimization>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -109,6 +111,7 @@
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -118,6 +121,7 @@
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm159 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>

View File

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

View File

@ -611,7 +611,7 @@ void VCAI::tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos)
addVisitableObj(obj);
}
void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2)
void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query)
{
LOG_TRACE(logAi);
NET_EVENT_HANDLER;
@ -619,6 +619,8 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2)
auto firstHero = cb->getHero(hero1);
auto secondHero = cb->getHero(hero2);
status.addQuery(query, boost::str(boost::format("Exchange between heroes %s and %s") % firstHero->name % secondHero->name));
requestActionASAP([=]()
{
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(secondHero));
//TODO: exchange artifacts
answerQuery(query, 0);
});
}
@ -843,7 +847,7 @@ void VCAI::yourTurn()
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);
NET_EVENT_HANDLER;
@ -851,7 +855,7 @@ void VCAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill p
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);
NET_EVENT_HANDLER;
@ -859,7 +863,7 @@ void VCAI::commanderGotLevel (const CCommanderInstance * commander, std::vector<
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);
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);
NET_EVENT_HANDLER;
@ -2524,10 +2528,10 @@ void VCAI::lostHero(HeroPtr 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;
if(queryID != -1)
if(queryID != QueryID(-1))
{
cb->selectionMade(selection, queryID);
}
@ -2597,24 +2601,24 @@ BattleState AIStatus::getBattle()
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);
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;
return;
}
assert(!vstd::contains(remainingQueries, ID));
assert(ID >= 0);
assert(ID.getNum() >= 0);
remainingQueries[ID] = description;
cv.notify_all();
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);
assert(vstd::contains(remainingQueries, ID));
@ -2658,7 +2662,7 @@ bool AIStatus::haveTurn()
return havingTurn;
}
void AIStatus::attemptedAnsweringQuery(int queryID, int answerRequestID)
void AIStatus::attemptedAnsweringQuery(QueryID queryID, int answerRequestID)
{
boost::unique_lock<boost::mutex> lock(mx);
assert(vstd::contains(remainingQueries, queryID));
@ -2670,7 +2674,7 @@ void AIStatus::attemptedAnsweringQuery(int queryID, int answerRequestID)
void AIStatus::receivedAnswerConfirmation(int answerRequestID, int result)
{
assert(vstd::contains(requestToQueryID, answerRequestID));
int query = requestToQueryID[answerRequestID];
QueryID query = requestToQueryID[answerRequestID];
assert(vstd::contains(remainingQueries, query));
requestToQueryID.erase(answerRequestID);

View File

@ -73,8 +73,8 @@ class AIStatus
boost::condition_variable cv;
BattleState battle;
std::map<int, 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<QueryID, std::string> remainingQueries;
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;
@ -83,14 +83,14 @@ public:
~AIStatus();
void setBattle(BattleState BS);
BattleState getBattle();
void addQuery(int ID, std::string description);
void removeQuery(int ID);
void addQuery(QueryID ID, std::string description);
void removeQuery(QueryID ID);
int getQueriesCount();
void startedTurn();
void madeTurn();
void waitTillFree();
bool haveTurn();
void attemptedAnsweringQuery(int queryID, int answerRequestID);
void attemptedAnsweringQuery(QueryID queryID, int answerRequestID);
void receivedAnswerConfirmation(int answerRequestID, int result);
@ -309,10 +309,10 @@ public:
virtual void init(CCallback * CB) 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 commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int 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 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 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, QueryID queryID) OVERRIDE; //TODO
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 saveGame(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
virtual void loadGame(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
virtual void finish() OVERRIDE;
@ -339,7 +339,7 @@ public:
virtual void availableArtifactsChanged(const CGBlackMarket *bm = NULL) OVERRIDE;
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) 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 showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE;
virtual void heroMovePointsChanged(const CGHeroInstance * hero) OVERRIDE;
@ -425,7 +425,7 @@ public:
void checkHeroArmy (HeroPtr h);
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
void requestActionASAP(boost::function<void()> whatToDo);

View File

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

View File

@ -843,6 +843,10 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
if(h && key.state == SDL_PRESSED)
{
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);
}
}

View File

@ -1203,7 +1203,7 @@ void HeroSlots::splitClicked()
{
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();
}
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;
waitWhileDialog();
@ -481,7 +481,7 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::Pr
[=](ui32 selection){ cb->selectionMade(selection, queryID); });
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;
waitWhileDialog();
@ -1016,7 +1016,7 @@ void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<vo
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;
waitWhileDialog();
@ -1324,7 +1324,7 @@ bool CPlayerInterface::altPressed() const
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;
auto onEnd = [=]{ cb->selectionMade(0, queryID); };
@ -1384,10 +1384,10 @@ void CPlayerInterface::requestRealized( PackageApplied *pa )
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;
GH.pushInt(new CExchangeWindow(hero1, hero2));
GH.pushInt(new CExchangeWindow(hero1, hero2, query));
}
void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)

View File

@ -143,8 +143,8 @@ public:
void artifactDisassembled(const ArtifactLocation &al);
void heroCreated(const CGHeroInstance* hero) OVERRIDE;
void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID) OVERRIDE;
void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> 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, QueryID queryID) OVERRIDE;
void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE;
void heroMoved(const TryMoveHero & details) 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 showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE;
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 showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID) OVERRIDE;
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, QueryID queryID) OVERRIDE;
void showPuzzleMap() OVERRIDE;
void showMarketWindow(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 playerBonusChanged(const Bonus &bonus, bool gain) 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 objectPropertyChanged(const SetObjectProperty * sop) 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;
type |= BLOCK_ADV_HOTKEYS;
ID = -1;
ID = QueryID(-1);
for(int i=0;i<Buttons.size();i++)
{
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()
{
ID = -1;
ID = QueryID(-1);
setDelComps(false);
text = NULL;
}
@ -1262,14 +1262,14 @@ void CSelWindow::selectionChange(unsigned to)
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;
ID = askID;
for(int i=0;i<Buttons.size();i++)
{
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[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.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);
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()
{
if(ID < 0)
if(ID.getNum() < 0)
return;
int ret = -1;
for (int i=0;i<components.size();i++)
@ -5078,7 +5078,7 @@ void CExchangeWindow::prepareBackground()
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")
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
@ -5165,6 +5165,9 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2)
//buttons
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[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:
typedef std::vector<std::pair<std::string,CFunctionList<void()> > > TButtonsInfo;
typedef std::vector<CComponent*> TCompsInfo;
int ID; //for identification
QueryID ID; //for identification
CTextBox *text;
std::vector<CAdventureMapButton *> buttons;
std::vector<CComponent*> components;
@ -117,7 +117,7 @@ class CSelWindow : public CInfoWindow
public:
void selectionChange(unsigned to);
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
//notification - this class inherits important destructor from CInfoWindow
};
@ -1034,7 +1034,7 @@ public:
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
};

View File

@ -588,6 +588,12 @@ void GarrisonDialog::applyCl(CClient *cl)
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 )
{
cl->battleStarted(info);
@ -829,14 +835,6 @@ void OpenWindow::applyCl(CClient *cl)
{
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_ALL:
{

View File

@ -94,13 +94,13 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalOptions>/MP4 %(AdditionalOptions)</AdditionalOptions>
<Optimization>
</Optimization>
<DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<AssemblerOutput>NoListing</AssemblerOutput>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
</ClCompile>
<Link>
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalOptions>/MP4 %(AdditionalOptions)</AdditionalOptions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
<DisableSpecificWarnings>4251;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<AssemblerOutput>NoListing</AssemblerOutput>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>SDL.lib;zlib.lib;SDL_image.lib;SDL_ttf.lib;SDL_mixer.lib;VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -136,6 +136,7 @@
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
</ClCompile>
<Link>
<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 Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
<ClCompile>
<AdditionalOptions>/Oy- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/MP4 /Zm150</AdditionalOptions>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
</ClCompile>
@ -260,4 +261,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -2,10 +2,6 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<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="CAnimation.cpp" />
<ClCompile Include="..\CCallback.cpp" />
@ -29,22 +25,22 @@
<ClCompile Include="mapHandler.cpp" />
<ClCompile Include="NetPacksClient.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="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>
<ClInclude Include="..\Global.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="CAnimation.h" />
<ClInclude Include="CBitmapHandler.h" />
@ -69,19 +65,23 @@
<ClInclude Include="GUIClasses.h" />
<ClInclude Include="resource.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" />
<ClCompile Include="CQuestLog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<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>
<ResourceCompile Include="VCMI_client.rc" />

View File

@ -80,16 +80,16 @@ public:
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
virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID)=0;
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> 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, QueryID queryID)=0;
// 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, 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
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
};

View File

@ -723,6 +723,12 @@ public:
for(ui32 i=0;i<length;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>
void saveSerializable(const std::set<T> &data)
{
@ -1077,6 +1083,12 @@ public:
for(ui32 i=0;i<length;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>
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>
{
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 requestSent(const CPackForServer *pack, int requestID){};
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 objectRemoved(const CGObjectInstance *obj){}; //eg. collected resource, picked artifact, beaten hero
virtual void playerBlocked(int reason){}; //reason: 0 - upcoming battle
virtual void gameOver(PlayerColor player, bool victory){}; //player lost or won the game
virtual void playerStartsTurn(PlayerColor player){};
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
{
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()
{
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 BattleStart : public CPackForClient//3000
{
@ -2053,8 +2065,9 @@ struct BuildBoat : public CPackForServer
struct QueryReply : public CPackForServer
{
QueryReply(){type = 6000;};
QueryReply(ui32 QID, ui32 Answer):qid(QID),answer(Answer){type = 6000;};
ui32 qid, answer; //hero and artifact id
QueryReply(QueryID QID, ui32 Answer):qid(QID),answer(Answer){type = 6000;};
QueryID qid;
ui32 answer; //hero and artifact id
PlayerColor player;
bool applyGh(CGameHandler *gh);

View File

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

View File

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

View File

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

View File

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

View File

@ -207,7 +207,7 @@ public:
void stackTurnTrigger(const CStack * stack);
void handleDamageFromObstacle(const CObstacleInstance &obstacle, const CStack * curStack); //checks if obstacle is land mine and handles possible consequences
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 buildBoat( ObjectInstanceID objid );
bool setFormation( ObjectInstanceID hid, ui8 formation );

View File

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

View File

@ -12,7 +12,6 @@ class CObjectVisitQuery;
struct TryMoveHero;
class CQuery;
typedef si32 TQueryID;
typedef shared_ptr<CQuery> QueryPtr;
// 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);
public:
std::vector<PlayerColor> players; //players that are affected (often "blocked") by query
TQueryID queryID;
QueryID queryID;
CQuery(void);
@ -109,7 +108,7 @@ public:
virtual bool blocksPack(const CPack *pack) const OVERRIDE;
};
class CGarrisonDialogQuery : public CDialogQuery
class CGarrisonDialogQuery : public CDialogQuery //used also for hero exchange dialogs
{
public:
std::array<const CArmedInstance *,2> exchangingArmies;

View File

@ -232,7 +232,7 @@ bool QueryReply::applyGh( CGameHandler *gh )
COMPLAIN_AND_RETURN("No such player!");
if(playerToConnection->second != c)
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!");
assert(vstd::contains(gh->states.players, player));