mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* Started making support for garrison window. Leaving guardians in flagged mines.
This commit is contained in:
parent
d72d988a9c
commit
f9aebcc4bd
@ -64,6 +64,11 @@ void CGeniusAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector
|
||||
callback(rand() % skills.size());
|
||||
}
|
||||
|
||||
void GeniusAI::CGeniusAI::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd )
|
||||
{
|
||||
onEnd();
|
||||
}
|
||||
|
||||
void CGeniusAI::showBlockingDialog( const std::string &text, const std::vector<Component> &components, ui32 askID, bool selection, bool cancel )
|
||||
{
|
||||
m_cb->selectionMade(cancel ? 0 : 1, askID);
|
||||
|
@ -194,6 +194,7 @@ public:
|
||||
virtual void tileRevealed(int3 pos){};
|
||||
virtual void tileHidden(int3 pos){};
|
||||
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
|
||||
// battle
|
||||
virtual void actionFinished(const BattleAction *action);//occurs AFTER every action taken by any stack or by the hero
|
||||
virtual void actionStarted(const BattleAction *action);//occurs BEFORE every action taken by any stack or by the hero
|
||||
|
@ -1364,15 +1364,17 @@ void CAdvMapInt::fendTurn()
|
||||
|
||||
void CAdvMapInt::activate()
|
||||
{
|
||||
if(active++)
|
||||
{
|
||||
tlog1 << "Error: advmapint already active...\n";
|
||||
}
|
||||
if(subInt == heroWindow)
|
||||
{
|
||||
heroWindow->activate();
|
||||
return;
|
||||
}
|
||||
if(active++)
|
||||
{
|
||||
tlog1 << "Error: advmapint already active...\n";
|
||||
active--;
|
||||
return;
|
||||
}
|
||||
LOCPLINT->curint = this;
|
||||
LOCPLINT->statusbar = &statusbar;
|
||||
kingOverview.activate();
|
||||
@ -1397,10 +1399,6 @@ void CAdvMapInt::activate()
|
||||
}
|
||||
void CAdvMapInt::deactivate()
|
||||
{
|
||||
if(--active)
|
||||
{
|
||||
tlog1 << "Error: advmapint still active...\n";
|
||||
}
|
||||
if(subInt == heroWindow)
|
||||
{
|
||||
heroWindow->deactivate();
|
||||
@ -1410,6 +1408,12 @@ void CAdvMapInt::deactivate()
|
||||
hide();
|
||||
|
||||
LOCPLINT->cingconsole->deactivate();
|
||||
|
||||
if(--active)
|
||||
{
|
||||
tlog1 << "Error: advmapint still active...\n";
|
||||
deactivate();
|
||||
}
|
||||
}
|
||||
void CAdvMapInt::show(SDL_Surface *to)
|
||||
{
|
||||
|
@ -324,16 +324,14 @@ int CCallback::getHeroSerial(const CGHeroInstance * hero) const
|
||||
const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj) const
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
if(!obj)
|
||||
const CArmedInstance *armi = dynamic_cast<const CArmedInstance*>(obj);
|
||||
if(!armi)
|
||||
return NULL;
|
||||
if(obj->ID == HEROI_TYPE)
|
||||
return &(dynamic_cast<const CGHeroInstance*>(obj))->army;
|
||||
else if(obj->ID == TOWNI_TYPE)
|
||||
return &(dynamic_cast<const CGTownInstance*>(obj)->army);
|
||||
else return NULL;
|
||||
else
|
||||
return &armi->army;
|
||||
}
|
||||
|
||||
int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)
|
||||
int CCallback::swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
|
||||
{
|
||||
if(s1->tempOwner != player || s2->tempOwner != player)
|
||||
return -1;
|
||||
@ -343,7 +341,7 @@ int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CCallback::mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)
|
||||
int CCallback::mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
|
||||
{
|
||||
if ((s1->tempOwner!= player || s2->tempOwner!=player))
|
||||
{
|
||||
@ -353,7 +351,7 @@ int CCallback::mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s
|
||||
*cl->serv << &pack;
|
||||
return 0;
|
||||
}
|
||||
int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)
|
||||
int CCallback::splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)
|
||||
{
|
||||
if (s1->tempOwner!= player || s2->tempOwner!=player || (!val))
|
||||
{
|
||||
|
12
CCallback.h
12
CCallback.h
@ -33,9 +33,9 @@ class ICallback
|
||||
public:
|
||||
virtual bool moveHero(const CGHeroInstance *h, int3 dst) const =0; //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
virtual void selectionMade(int selection, int asker) =0;
|
||||
virtual int swapCreatures(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)=0;//swaps creatures between two posiibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||
virtual int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)=0;//joins first stack tothe second (creatures must be same type)
|
||||
virtual int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
|
||||
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two posiibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack tothe second (creatures must be same type)
|
||||
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
|
||||
virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses diven hero; true - successfuly, false - not successfuly
|
||||
virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
|
||||
virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)=0;
|
||||
@ -123,9 +123,9 @@ public:
|
||||
//commands
|
||||
bool moveHero(const CGHeroInstance *h, int3 dst) const; //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
void selectionMade(int selection, int asker);
|
||||
int swapCreatures(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2);
|
||||
int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2); //first goes to the second
|
||||
int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val);
|
||||
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2);
|
||||
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
|
||||
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
||||
bool dismissHero(const CGHeroInstance * hero);
|
||||
bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
|
||||
bool buildBuilding(const CGTownInstance *town, si32 buildingID);
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
//virtual void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||
//virtual void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, bool selection, bool cancel) = 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 showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||
virtual void tileHidden(const std::set<int3> &pos){};
|
||||
virtual void tileRevealed(const std::set<int3> &pos){};
|
||||
virtual void yourTurn(){};
|
||||
|
@ -232,7 +232,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
portraitArea->text = hero->getBiography();
|
||||
|
||||
delete garInt;
|
||||
/*gar4button->owner = */garInt = new CGarrisonInt(pos.x+80, pos.y+493, 8, 0, curBack, 13, 482, curHero);
|
||||
/*gar4button->owner = */garInt = new CGarrisonInt(pos.x+80, pos.y+493, 8, 0, curBack, 15, 485, curHero);
|
||||
garInt->update = false;
|
||||
gar4button->callback = boost::bind(&CGarrisonInt::splitClick,garInt);//actualization of callback function
|
||||
|
||||
|
@ -2117,11 +2117,6 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
|
||||
hw->garInt->recreateSlots();
|
||||
hw->garInt->show();
|
||||
}
|
||||
if(castleInt) //opened town window - redraw town garrison slots (change is within hero garr)
|
||||
{
|
||||
castleInt->garr->highlighted = NULL;
|
||||
castleInt->garr->recreateSlots();
|
||||
}
|
||||
|
||||
}
|
||||
else if (obj->ID == TOWNI_TYPE) //town
|
||||
@ -2137,12 +2132,24 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
|
||||
SDL_FreeSurface(graphics->heroWins[tt->visitingHero->subID]);
|
||||
graphics->heroWins[tt->visitingHero->subID] = infoWin(tt->visitingHero);
|
||||
}
|
||||
if(LOCPLINT->castleInt)
|
||||
|
||||
}
|
||||
|
||||
if(castleInt) //opened town window - redraw town garrison slots (change is within hero garr)
|
||||
{
|
||||
LOCPLINT->castleInt->garr->highlighted = NULL;
|
||||
LOCPLINT->castleInt->garr->recreateSlots();
|
||||
castleInt->garr->highlighted = NULL;
|
||||
castleInt->garr->recreateSlots();
|
||||
}
|
||||
else if(curint && curint->subInt)
|
||||
{
|
||||
CGarrisonWindow *gw = dynamic_cast<CGarrisonWindow*>(curint->subInt);
|
||||
if(gw)
|
||||
{
|
||||
gw->garr->recreateSlots();
|
||||
gw->garr->show();
|
||||
}
|
||||
}
|
||||
|
||||
if(curint == adventureInt)
|
||||
adventureInt->infoBar.draw();
|
||||
}
|
||||
@ -2613,6 +2620,16 @@ bool CPlayerInterface::shiftPressed() const
|
||||
return SDL_GetKeyState(NULL)[SDLK_LSHIFT] || SDL_GetKeyState(NULL)[SDLK_RSHIFT];
|
||||
}
|
||||
|
||||
void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd )
|
||||
{
|
||||
CGarrisonWindow *cgw = new CGarrisonWindow(up,down);
|
||||
cgw->quit->callback += onEnd;
|
||||
curint->deactivate();
|
||||
cgw->activate();
|
||||
objsToBlit += cgw;
|
||||
LOCPLINT->curint->subInt = cgw;
|
||||
}
|
||||
|
||||
CStatusBar::CStatusBar(int x, int y, std::string name, int maxw)
|
||||
{
|
||||
bg=BitmapHandler::loadBitmap(name);
|
||||
@ -3791,7 +3808,7 @@ void CCreInfoWindow::activate()
|
||||
void CCreInfoWindow::close()
|
||||
{
|
||||
deactivate();
|
||||
if(dynamic_cast<CHeroWindow*>(LOCPLINT->curint->subInt))
|
||||
if(LOCPLINT->curint->subInt)
|
||||
{
|
||||
if(type)
|
||||
LOCPLINT->curint->subInt->activate();
|
||||
@ -4791,3 +4808,57 @@ CInGameConsole::CInGameConsole() : defaultTimeout(10000), maxDisplayedTexts(10),
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CGarrisonWindow::close()
|
||||
{
|
||||
LOCPLINT->curint->subInt = NULL;
|
||||
deactivate();
|
||||
LOCPLINT->curint->activate();
|
||||
LOCPLINT->objsToBlit -= this;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void CGarrisonWindow::activate()
|
||||
{
|
||||
split->activate();
|
||||
quit->activate();
|
||||
garr->activate();
|
||||
}
|
||||
|
||||
void CGarrisonWindow::deactivate()
|
||||
{
|
||||
split->deactivate();
|
||||
quit->deactivate();
|
||||
garr->deactivate();
|
||||
}
|
||||
|
||||
void CGarrisonWindow::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(bg,pos);
|
||||
split->show();
|
||||
quit->show();
|
||||
garr->show();
|
||||
}
|
||||
|
||||
CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down )
|
||||
{
|
||||
bg = BitmapHandler::loadBitmap("GARRISON.bmp");
|
||||
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
|
||||
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
|
||||
pos.x = screen->w/2 - bg->w/2;
|
||||
pos.y = screen->h/2 - bg->h/2;
|
||||
pos.w = screen->w;
|
||||
pos.h = screen->h;
|
||||
|
||||
garr = new CGarrisonInt(pos.x+92, pos.y+129, 4, 30, bg, 92, 126, up, down);
|
||||
split = new AdventureMapButton(CGI->generaltexth->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+88,pos.y+314,"IDV6432.DEF");
|
||||
quit = new AdventureMapButton(CGI->generaltexth->tcommands[8],"",boost::bind(&CGarrisonWindow::close,this),pos.x+399,pos.y+314,"IOK6432.DEF",SDLK_RETURN);
|
||||
}
|
||||
|
||||
CGarrisonWindow::~CGarrisonWindow()
|
||||
{
|
||||
SDL_FreeSurface(bg);
|
||||
delete split;
|
||||
delete quit;
|
||||
delete garr;
|
||||
}
|
@ -548,6 +548,7 @@ public:
|
||||
//void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
||||
//void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, bool selection, bool cancel); //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, boost::function<void()> &onEnd);
|
||||
void tileHidden(const std::set<int3> &pos);
|
||||
void tileRevealed(const std::set<int3> &pos);
|
||||
void yourTurn();
|
||||
@ -927,6 +928,21 @@ public:
|
||||
CInGameConsole(); //c-tor
|
||||
};
|
||||
|
||||
class CGarrisonWindow : public IShowActivable, public CIntObject
|
||||
{
|
||||
public:
|
||||
CGarrisonInt *garr;
|
||||
SDL_Surface *bg;
|
||||
AdventureMapButton *split, *quit;
|
||||
|
||||
void close();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void show(SDL_Surface * to = NULL);
|
||||
CGarrisonWindow(const CArmedInstance *up, const CGHeroInstance *down);
|
||||
~CGarrisonWindow();
|
||||
};
|
||||
|
||||
extern CPlayerInterface * LOCPLINT;
|
||||
|
||||
|
||||
|
@ -79,6 +79,7 @@ public:
|
||||
void showInfoDialog(InfoWindow *iw){};
|
||||
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback){};
|
||||
ui32 showBlockingDialog(BlockingDialog *iw){return 0;}; //synchronous version of above
|
||||
void showGarrisonDialog(int upobj, int hid, const boost::function<void()> &cb){};
|
||||
void giveResource(int player, int which, int val){};
|
||||
void showCompInfo(ShowInInfobox * comp){};
|
||||
void heroVisitCastle(int obj, int heroID){};
|
||||
|
@ -291,6 +291,18 @@ void BlockingDialog::applyCl( CClient *cl )
|
||||
tlog2 << "We received YesNoDialog for not our player...\n";
|
||||
}
|
||||
|
||||
void GarrisonDialog::applyCl(CClient *cl)
|
||||
{
|
||||
const CGHeroInstance *h = cl->getHero(hid);
|
||||
const CArmedInstance *obj = static_cast<const CArmedInstance*>(cl->getObj(objid));
|
||||
|
||||
if(!vstd::contains(cl->playerint,h->getOwner()))
|
||||
return;
|
||||
|
||||
boost::function<void()> callback = boost::bind(&CCallback::selectionMade,LOCPLINT->cb,0,id);
|
||||
cl->playerint[h->getOwner()]->showGarrisonDialog(obj,h,callback);
|
||||
}
|
||||
|
||||
void BattleStart::applyCl( CClient *cl )
|
||||
{
|
||||
if(vstd::contains(cl->playerint,info->side1))
|
||||
|
@ -119,7 +119,7 @@ void CHeroHandler::loadObstacles()
|
||||
inp.open("config" PATHSEPARATOR "obstacles.txt", std::ios_base::in|std::ios_base::binary);
|
||||
if(!inp.is_open())
|
||||
{
|
||||
tlog1<<"missing file: config/heroes_sec_skills.txt"<<std::endl;
|
||||
tlog1<<"missing file: config/obstacles.txt"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1292,7 +1292,10 @@ void CGMine::onHeroVisit( const CGHeroInstance * h ) const
|
||||
return;
|
||||
|
||||
if(h->tempOwner == tempOwner) //we're visiting our mine
|
||||
return; //TODO: leaving garrison
|
||||
{
|
||||
cb->showGarrisonDialog(id,h->id,0);
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: check if mine is guarded
|
||||
cb->setOwner(id,h->tempOwner); //not ours? flag it!
|
||||
|
@ -599,6 +599,7 @@ public:
|
||||
class DLL_EXPORT CGMine : public CArmedInstance
|
||||
{
|
||||
public:
|
||||
void offerLeavingGuards(const CGHeroInstance *h) const;
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void newTurn() const;
|
||||
void initObj();
|
||||
|
16
int3.h
16
int3.h
@ -11,9 +11,9 @@ class CCreatureSet //seven combined creatures
|
||||
public:
|
||||
std::map<si32,std::pair<ui32,si32> > slots; //slots[slot_id]=> pair(creature_id,creature_quantity)
|
||||
bool formation; //false - wide, true - tight
|
||||
si32 getSlotFor(ui32 creature, ui32 slotsAmount=7) //returns -1 if no slot available
|
||||
si32 getSlotFor(ui32 creature, ui32 slotsAmount=7) const //returns -1 if no slot available
|
||||
{
|
||||
for(std::map<si32,std::pair<ui32,si32> >::iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
for(std::map<si32,std::pair<ui32,si32> >::const_iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
{
|
||||
if(i->second.first == creature)
|
||||
{
|
||||
@ -37,6 +37,18 @@ public:
|
||||
{
|
||||
return slots.size()>0;
|
||||
}
|
||||
void sweep()
|
||||
{
|
||||
for(std::map<si32,std::pair<ui32,si32> >::iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
{
|
||||
if(!i->second.second)
|
||||
{
|
||||
slots.erase(i);
|
||||
sweep();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class int3
|
||||
|
@ -52,7 +52,8 @@ public:
|
||||
virtual void changeSecSkill(int ID, int which, int val, bool abs=false)=0;
|
||||
virtual void showInfoDialog(InfoWindow *iw)=0;
|
||||
virtual void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
|
||||
virtual ui32 showBlockingDialog(BlockingDialog *iw) =0; //synchronous version of above
|
||||
virtual ui32 showBlockingDialog(BlockingDialog *iw) =0; //synchronous version of above //TODO:
|
||||
virtual void showGarrisonDialog(int upobj, int hid, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
|
||||
virtual void giveResource(int player, int which, int val)=0;
|
||||
virtual void showCompInfo(ShowInInfobox * comp)=0;
|
||||
virtual void heroVisitCastle(int obj, int heroID)=0;
|
||||
|
@ -595,6 +595,18 @@ struct BlockingDialog : public Query//2003
|
||||
}
|
||||
};
|
||||
|
||||
struct GarrisonDialog : public Query//2004
|
||||
{
|
||||
GarrisonDialog(){type = 2004;}
|
||||
void applyCl(CClient *cl);
|
||||
si32 objid, hid;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & objid & hid;
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleInfo;
|
||||
struct BattleStart : public CPackForClient//3000
|
||||
{
|
||||
|
@ -68,6 +68,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<SetHoverName>();
|
||||
s.template registerType<HeroLevelUp>();
|
||||
s.template registerType<BlockingDialog>();
|
||||
s.template registerType<GarrisonDialog>();
|
||||
s.template registerType<BattleStart>();
|
||||
s.template registerType<BattleNextRound>();
|
||||
s.template registerType<BattleSetActiveStack>();
|
||||
|
@ -38,13 +38,9 @@ extern bool end2;
|
||||
bnr.round = gs->curB->round + 1;\
|
||||
sendAndApply(&bnr);
|
||||
|
||||
boost::mutex gsm;
|
||||
ui32 CGameHandler::QID = 1;
|
||||
|
||||
CondSh<bool> battleMadeAction;
|
||||
CondSh<BattleResult *> battleResult(NULL);
|
||||
|
||||
std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback function - for selection dialogs
|
||||
|
||||
class CBaseForGHApply
|
||||
{
|
||||
@ -581,6 +577,7 @@ void CGameHandler::moveStack(int stack, int dest)
|
||||
}
|
||||
CGameHandler::CGameHandler(void)
|
||||
{
|
||||
QID = 1;
|
||||
gs = NULL;
|
||||
IObjectInterface::cb = this;
|
||||
applier = new CGHApplier;
|
||||
@ -1466,6 +1463,12 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
|
||||
CCreatureSet temp1 = s1->army, temp2 = s2->army,
|
||||
&S1 = temp1, &S2 = (s1!=s2)?(temp2):(temp1);
|
||||
|
||||
if(!isAllowedExchange(id1,id2))
|
||||
{
|
||||
complain("Cannot exchange stacks between these two objects!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(what==1) //swap
|
||||
{
|
||||
std::swap(S1.slots[p1],S2.slots[p2]); //swap slots
|
||||
@ -1925,10 +1928,25 @@ void CGameHandler::hireHero( ui32 tid, ui8 hid )
|
||||
void CGameHandler::queryReply( ui32 qid, ui32 answer )
|
||||
{
|
||||
gsm.lock();
|
||||
if(vstd::contains(callbacks,qid))
|
||||
{
|
||||
CFunctionList<void(ui32)> callb = callbacks[qid];
|
||||
callbacks.erase(qid);
|
||||
gsm.unlock();
|
||||
if(callb)
|
||||
callb(answer);
|
||||
}
|
||||
else if(vstd::contains(garrisonCallbacks,qid))
|
||||
{
|
||||
if(garrisonCallbacks[qid])
|
||||
garrisonCallbacks[qid]();
|
||||
garrisonCallbacks.erase(qid);
|
||||
allowedExchanges.erase(qid);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlog1 << "Unknown query reply...\n";
|
||||
}
|
||||
gsm.unlock();
|
||||
}
|
||||
|
||||
void CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
@ -2399,3 +2417,49 @@ ui32 CGameHandler::getQueryResult( ui8 player, int queryID )
|
||||
//TODO: write
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CGameHandler::showGarrisonDialog( int upobj, int hid, const boost::function<void()> &cb )
|
||||
{
|
||||
ui8 player = getOwner(hid);
|
||||
GarrisonDialog gd;
|
||||
gd.hid = hid;
|
||||
gd.objid = upobj;
|
||||
gsm.lock();
|
||||
gd.id = QID;
|
||||
garrisonCallbacks[QID] = cb;
|
||||
allowedExchanges[QID] = std::pair<si32,si32>(upobj,hid);
|
||||
states.addQuery(player,QID);
|
||||
QID++;
|
||||
sendAndApply(&gd);
|
||||
gsm.unlock();
|
||||
}
|
||||
|
||||
bool CGameHandler::isAllowedExchange( int id1, int id2 )
|
||||
{
|
||||
if(id1 == id2)
|
||||
return true;
|
||||
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(gsm);
|
||||
for(std::map<ui32, std::pair<si32,si32> >::const_iterator i = allowedExchanges.begin(); i!=allowedExchanges.end(); i++)
|
||||
if(id1 == i->second.first && id2 == i->second.second || id2 == i->second.first && id1 == i->second.second)
|
||||
return true;
|
||||
}
|
||||
|
||||
const CGObjectInstance *o1 = getObj(id1), *o2 = getObj(id2);
|
||||
|
||||
if(o1->ID == TOWNI_TYPE)
|
||||
{
|
||||
const CGTownInstance *t = static_cast<const CGTownInstance*>(o1);
|
||||
if(t->visitingHero == o2 || t->garrisonHero == o2)
|
||||
return true;
|
||||
}
|
||||
if(o2->ID == TOWNI_TYPE)
|
||||
{
|
||||
const CGTownInstance *t = static_cast<const CGTownInstance*>(o2);
|
||||
if(t->visitingHero == o1 || t->garrisonHero == o1)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -58,12 +58,19 @@ public:
|
||||
class CGameHandler : public IGameCallback
|
||||
{
|
||||
public:
|
||||
static ui32 QID;
|
||||
CVCMIServer *s;
|
||||
std::map<int,CConnection*> connections; //player color -> connection to clinet with interface of that player
|
||||
std::map<int,CConnection*> connections; //player color -> connection to client with interface of that player
|
||||
PlayerStatuses states; //player color -> player state
|
||||
std::set<CConnection*> conns;
|
||||
|
||||
//queries stuff
|
||||
boost::mutex gsm;
|
||||
ui32 QID;
|
||||
std::map<ui32, CFunctionList<void(ui32)> > callbacks; //query id => callback function - for selection and yes/no dialogs
|
||||
std::map<ui32, boost::function<void()> > garrisonCallbacks; //query id => callback - for garrison dialogs
|
||||
std::map<ui32, std::pair<si32,si32> > allowedExchanges;
|
||||
|
||||
bool isAllowedExchange(int id1, int id2);
|
||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||
void moveStack(int stack, int dest);
|
||||
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
|
||||
@ -95,6 +102,7 @@ public:
|
||||
void showInfoDialog(InfoWindow *iw);
|
||||
void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback);
|
||||
ui32 showBlockingDialog(BlockingDialog *iw); //synchronous version of above
|
||||
void showGarrisonDialog(int upobj, int hid, const boost::function<void()> &cb);
|
||||
void giveResource(int player, int which, int val);
|
||||
void showCompInfo(ShowInInfobox * comp);
|
||||
void heroVisitCastle(int obj, int heroID);
|
||||
|
Loading…
Reference in New Issue
Block a user