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

* showing creature amount in the CCreInfoWindow

* fixes and improvements in dismiss/upgrade dialogs
* possibility of moving hero into the garrison
* viewing hero window in the town screen
This commit is contained in:
Michał W. Urbańczyk 2008-08-16 08:47:41 +00:00
parent 8a6cfa2590
commit 346af53961
17 changed files with 411 additions and 51 deletions

View File

@ -1237,7 +1237,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
pom->morale = h->getCurrentMorale();
pom->currentHealth = myst.firstHPleft;
}
(new CCreInfoWindow(myst.creature->idNumber,0,pom,boost::function<void()>(),boost::function<void()>(),NULL))
(new CCreInfoWindow(myst.creature->idNumber,0,myst.amount,pom,boost::function<void()>(),boost::function<void()>(),NULL))
->activate();
}
delete pom;

View File

@ -498,3 +498,9 @@ bool CCallback::battleCanShoot(int ID, int dest) //TODO: finish
return true;
return false;
}
void CCallback::swapGarrisonHero( const CGTownInstance *town )
{
if(town->tempOwner != player) return;
*cl->serv << ui16(508) << si32(town->id);
}

View File

@ -39,6 +39,7 @@ public:
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made
virtual void endTurn()=0;
virtual void swapGarrisonHero(const CGTownInstance *town)=0;
//get info
virtual bool verifyPath(CPath * path, bool blockSea)=0;
@ -111,6 +112,7 @@ public:
bool dismissCreature(const CArmedInstance *obj, int stackPos);
bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1);
void endTurn();
void swapGarrisonHero(const CGTownInstance *town);
//get info
bool verifyPath(CPath * path, bool blockSea);

View File

@ -14,6 +14,9 @@
#include "hch/CGeneralTextHandler.h"
#include "CCallback.h"
#include "client/Graphics.h"
#include "CHeroWindow.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
extern TTF_Font * GEOR16;
CBuildingRect::CBuildingRect(Structure *Str)
:str(Str), moi(false), offset(0)
@ -170,7 +173,116 @@ void CBuildingRect::mouseMoved (SDL_MouseMotionEvent & sEvent)
//if(border)
// blitAt(border,pos.x,pos.y);
}
void CHeroGSlot::hover (bool on)
{
if(!on) return;
CHeroGSlot *other = upg ? &owner->hslotup : &owner->hslotdown;
std::string temp;
if(hero)
{
if(highlight)//view NNN
{
temp = CGI->townh->tcommands[4];
boost::algorithm::replace_first(temp,"%s",hero->name);
}
else if(other->hero && other->highlight)//exchange
{
temp = CGI->townh->tcommands[7];
boost::algorithm::replace_first(temp,"%s",hero->name);
boost::algorithm::replace_first(temp,"%s",other->hero->name);
}
else// select NNN (in ZZZ)
{
if(upg)//down - visiting
{
temp = CGI->townh->tcommands[32];
boost::algorithm::replace_first(temp,"%s",hero->name);
}
else //up - garrison
{
temp = CGI->townh->tcommands[12];
boost::algorithm::replace_first(temp,"%s",hero->name);
}
}
}
else //we are empty slot
{
if(other->highlight && other->hero) //move NNNN
{
temp = CGI->townh->tcommands[6];
boost::algorithm::replace_first(temp,"%s",other->hero->name);
}
else //empty
{
temp = CGI->generaltexth->allTexts[507];
}
}
if(temp.size())
LOCPLINT->statusbar->print(temp);
}
void CHeroGSlot::clickRight (boost::logic::tribool down)
{
}
void CHeroGSlot::clickLeft(boost::logic::tribool down)
{
if(!down)
{
CHeroGSlot *other = upg ? &owner->hslotup : &owner->hslotdown;
if(hero && highlight)
{
highlight = false;
LOCPLINT->openHeroWindow(hero);
LOCPLINT->adventureInt->heroWindow->quitButton->callback += boost::bind(&CCastleInterface::showAll,owner,screen,true);
}
else if(hero)
{
highlight = true;
owner->showAll();
}
else if(other->hero, other->highlight)
{
other->highlight = highlight = false;
LOCPLINT->cb->swapGarrisonHero(owner->town);
}
hover(false);hover(true); //refresh statusbar
}
}
void CHeroGSlot::activate()
{
ClickableL::activate();
ClickableR::activate();
Hoverable::activate();
}
void CHeroGSlot::deactivate()
{
ClickableL::deactivate();
ClickableR::deactivate();
Hoverable::deactivate();
}
void CHeroGSlot::show()
{
if(hero) //there is hero
blitAt(graphics->portraitLarge[hero->portrait],pos);
else if(!upg) //up garrison
blitAt((static_cast<CCastleInterface*>(LOCPLINT->curint))->flag->ourImages[(static_cast<CCastleInterface*>(LOCPLINT->curint))->town->getOwner()].bitmap,pos);
if(highlight)
blitAt(graphics->bigImgs[-1],pos);
}
CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, CCastleInterface * Owner)
{
owner = Owner;
pos.x = x;
pos.y = y;
pos.w = 58;
pos.h = 64;
hero = h;
upg = updown;
highlight = false;
}
CHeroGSlot::~CHeroGSlot()
{
}
std::string getBgName(int type) //TODO - co z tym zrobiæ?
{
switch (type)
@ -213,6 +325,7 @@ public:
} srthlp ;
CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
:hslotup(241,387,0,Town->garrisonHero,this),hslotdown(241,483,1,Town->visitingHero,this)
{
hall = NULL;
townInt = BitmapHandler::loadBitmap("TOWNSCRN.bmp");
@ -375,7 +488,7 @@ void CCastleInterface::enterHall()
hallInt->activate();
hallInt->show();
}
void CCastleInterface::showAll(SDL_Surface * to)
void CCastleInterface::showAll( SDL_Surface * to/*=NULL*/, bool forceTotalRedraw /*= false*/)
{
if (!to)
to=screen;
@ -445,11 +558,15 @@ void CCastleInterface::showAll(SDL_Surface * to)
pom++;
blitAt(graphics->bigTownPic->ourImages[pom].bitmap,15,387,to);
//flag
if(town->getOwner()<PLAYER_LIMIT)
blitAt(flag->ourImages[town->getOwner()].bitmap,241,387,to);
hslotup.show();
hslotdown.show();
pom=false;
if(forceTotalRedraw && !showing)
pom = showing = true;
show();
if(pom)
showing = false;
}
void CCastleInterface::townChange()
{
@ -466,7 +583,7 @@ void CCastleInterface::show(SDL_Surface * to)
if (!to)
to=screen;
count++;
if(count==4)
if(count==8)
{
count=0;
animval++;
@ -503,6 +620,8 @@ void CCastleInterface::activate()
split->activate();
for(int i=0;i<buildings.size();i++)
buildings[i]->activate();
hslotdown.activate();
hslotup.activate();
}
void CCastleInterface::deactivate()
{
@ -513,6 +632,8 @@ void CCastleInterface::deactivate()
split->deactivate();
for(int i=0;i<buildings.size();i++)
buildings[i]->deactivate();
hslotdown.deactivate();
hslotup.deactivate();
}
void CCastleInterface::addBuilding(int bid)

View File

@ -28,6 +28,24 @@ public:
void mouseMoved (SDL_MouseMotionEvent & sEvent);
};
class CHeroGSlot : public ClickableL, public ClickableR, public Hoverable
{
public:
CCastleInterface *owner;
const CGHeroInstance *hero;
int upg; //0 - up garrison, 1 - down garrison
bool highlight;
void hover (bool on);
void clickRight (boost::logic::tribool down);
void clickLeft(boost::logic::tribool down);
void activate();
void deactivate();
void show();
CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner);
~CHeroGSlot();
};
class CCastleInterface : public IShowable, public IActivable
{
public:
@ -44,6 +62,7 @@ public:
CDefEssential* bicons; //150x70 buildings imgs
CTownList * townlist;
CHeroGSlot hslotup, hslotdown;
CGarrisonInt * garr;
AdventureMapButton *exit;
AdventureMapButton *split;
@ -54,7 +73,7 @@ public:
~CCastleInterface();
void townChange();
void show(SDL_Surface * to=NULL);
void showAll(SDL_Surface * to=NULL);
void showAll(SDL_Surface * to=NULL, bool forceTotalRedraw = false);
void buildingClicked(int building);
void enterHall();
void close();

View File

@ -59,6 +59,7 @@ public:
virtual void garrisonChanged(const CGObjectInstance * obj){};
virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
virtual void heroInGarrisonChange(const CGTownInstance *town){};
//battle call-ins
virtual void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right
virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning

View File

@ -431,6 +431,27 @@ void CGameState::applyNL(IPack * pack)
static_cast<CGTownInstance*>(map->objects[sac->tid])->strInfo.creatures = sac->creatures;
break;
}
case 508:
{
SetHeroesInTown *sac = static_cast<SetHeroesInTown*>(pack);
CGTownInstance *t = getTown(sac->tid);
CGHeroInstance *v = getHero(sac->visiting), *g = getHero(sac->garrison);
t->visitingHero = v;
t->garrisonHero = g;
if(v)
{
v->visitedTown = t;
v->inTownGarrison = false;
map->addBlockVisTiles(v);
}
if(g)
{
g->visitedTown = t;
g->inTownGarrison = true;
map->removeBlockVisTiles(g);
}
break;
}
case 1001://set object property
{
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);

View File

@ -518,7 +518,7 @@ void CHeroWindow::quit()
}
deactivate();
LOCPLINT->adventureInt->activate();
LOCPLINT->curint->activate();
SDL_FreeSurface(curBack);
curBack = NULL;
@ -544,7 +544,7 @@ void CHeroWindow::quit()
void CHeroWindow::activate()
{
LOCPLINT->curint = this;
//LOCPLINT->curint = this;
quitButton->activate();
dismissButton->activate();
questlogButton->activate();

View File

@ -91,9 +91,6 @@ class CHeroWindow: public IActivable, public IShowable, public virtual CIntObjec
CDefHandler *flags;
//buttons
AdventureMapButton * quitButton, * dismissButton, * questlogButton, //general
* gar1button, * gar2button, * gar3button, //garrison / formation handling
* leftArtRoll, * rightArtRoll;
AdventureMapButton * gar4button; //splitting
//std::vector< AdventureMapButton<CHeroWindow> * > heroList; //list of heroes
std::vector<LClickableAreaHero *> heroListMi; //new better list of heroes
@ -114,6 +111,9 @@ class CHeroWindow: public IActivable, public IShowable, public virtual CIntObjec
LRClickableAreaWText * spellPointsArea;
std::vector<LRClickableAreaWTextComp *> secSkillAreas;
public:
AdventureMapButton * quitButton, * dismissButton, * questlogButton, //general
* gar1button, * gar2button, * gar3button, //garrison / formation handling
* leftArtRoll, * rightArtRoll;
int player;
CHeroWindow(int playerColor); //c-tor
~CHeroWindow(); //d-tor

View File

@ -291,12 +291,12 @@ void CVisitableOPH::onNAHeroVisit(int objid, int heroID, bool alreadyVisited)
}
case 100: //give 1000 exp
{
cb->changePrimSkill(heroID,w,vvv);
InfoWindow iw;
iw.components.push_back(Component(0,4,vvv,0));
iw.player = cb->getHeroOwner(heroID);
iw.text << std::pair<ui8,ui32>(11,ot);
cb->showInfoDialog(&iw);
cb->changePrimSkill(heroID,w,vvv);
break;
}
}

View File

@ -137,8 +137,9 @@ void CGarrisonSlot::clickRight (tribool down)
pom->luck = h->getCurrentLuck();
pom->morale = h->getCurrentMorale();
}
(new CCreInfoWindow(creature->idNumber,0,pom,boost::function<void()>(),boost::function<void()>(),NULL))
(new CCreInfoWindow(creature->idNumber,0,count,pom,boost::function<void()>(),boost::function<void()>(),NULL))
->activate();
//LOCPLINT->curint->deactivate();
}
delete pom;
}
@ -160,16 +161,18 @@ void CGarrisonSlot::clickLeft(tribool down)
if(pom.oldID>=0)
{
(new CCreInfoWindow
(creature->idNumber,1,NULL,
(creature->idNumber,1,count,NULL,
boost::bind(&CCallback::upgradeCreature,LOCPLINT->cb,getObj(),ID,pom.newID[0]), //if upgrade is possible we'll bind proper function in callback
boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID),&pom))
->activate();
LOCPLINT->curint->deactivate();
}
else
{
(new CCreInfoWindow
(creature->idNumber,1,NULL,0, boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID),NULL) )
(creature->idNumber,1,count,NULL,0, boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID),NULL) )
->activate();
LOCPLINT->curint->deactivate();
}
owner->highlighted = NULL;
show();
@ -387,6 +390,8 @@ void CGarrisonInt::deleteSlots()
delete (*sup)[i];
}
}
delete sup;
sup = NULL;
}
if(sdown)
{
@ -397,6 +402,8 @@ void CGarrisonInt::deleteSlots()
delete (*sdown)[i];
}
}
delete sdown;
sdown = NULL;
}
}
void CGarrisonInt::recreateSlots()
@ -484,6 +491,7 @@ void CInfoWindow::close()
{
deactivate();
delete this;
LOCPLINT->showingDialog->setn(false);
}
void CInfoWindow::show(SDL_Surface * to)
{
@ -494,8 +502,11 @@ void CInfoWindow::show(SDL_Surface * to)
CInfoWindow::~CInfoWindow()
{
for (int i=0;i<components.size();i++)
delete components[i];
if(delComps)
{
for (int i=0;i<components.size();i++)
delete components[i];
}
for(int i=0;i<buttons.size();i++)
delete buttons[i];
}
@ -966,10 +977,12 @@ CPlayerInterface::CPlayerInterface(int Player, int serial)
serialID=serial;
human=true;
pim = new boost::mutex;
showingDialog = new CondSh<bool>(false);
}
CPlayerInterface::~CPlayerInterface()
{
delete pim;
delete showingDialog;
}
void CPlayerInterface::init(ICallback * CB)
{
@ -1929,11 +1942,53 @@ void CPlayerInterface::showSelDialog(std::string &text, std::vector<Component*>
}
void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16>& skills, boost::function<void(ui32)> &callback)
{
{
boost::unique_lock<boost::mutex> un(showingDialog->mx);
while(showingDialog->data)
showingDialog->cond.wait(un);
}
boost::unique_lock<boost::mutex> un(*pim);
CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback);
curint->deactivate();
lw->activate();
}
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
{
boost::unique_lock<boost::mutex> un(*pim);
//redraw infowindow
SDL_FreeSurface(graphics->townWins[town->subID]);
graphics->townWins[town->subID] = infoWin(town);
if(town->garrisonHero)
{
CGI->mh->hideObject(town->garrisonHero);
for(int i=0; i<adventureInt->heroList.items.size();i++)
{
if(adventureInt->heroList.items[i].first == town->garrisonHero)
{
adventureInt->heroList.items.erase(adventureInt->heroList.items.begin()+i);
if(adventureInt->heroList.selected >= adventureInt->heroList.items.size())
adventureInt->heroList.selected--;
break;
}
}
}
if(town->visitingHero)
{
CGI->mh->printObject(town->visitingHero);
adventureInt->heroList.items.push_back(std::pair<const CGHeroInstance*, CPath *>(town->visitingHero,NULL));
}
CCastleInterface *c = dynamic_cast<CCastleInterface*>(curint);
if(c)
{
c->garr->highlighted = NULL;
c->hslotup.hero = town->garrisonHero;
c->garr->odown = c->hslotdown.hero = town->visitingHero;
c->garr->set2 = town->visitingHero ? &town->visitingHero->army : NULL;
c->garr->recreateSlots();
c->showAll();
}
}
void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town)
{
boost::unique_lock<boost::mutex> un(*pim);
@ -2098,6 +2153,7 @@ void CPlayerInterface::showInfoDialog(std::string &text, std::vector<Component*>
}
void CPlayerInterface::showInfoDialog(std::string &text, std::vector<SComponent*> & components)
{
showingDialog->set(true);
curint->deactivate(); //dezaktywacja starego interfejsu
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
@ -2108,18 +2164,24 @@ void CPlayerInterface::showInfoDialog(std::string &text, std::vector<SComponent*
temp->activate();
LOCPLINT->objsToBlit.push_back(temp);
}
void CPlayerInterface::showYesNoDialog(std::string &text, std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool deactivateCur)
void CPlayerInterface::showYesNoDialog(std::string &text, std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool deactivateCur, bool DelComps)
{
if(deactivateCur)
curint->deactivate(); //dezaktywacja starego interfejsu
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",onYes));
pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",onNo));
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",0));
CInfoWindow * temp = new CInfoWindow(text,playerID,32,components,pom);
if(onYes)
temp->buttons[0]->callback += boost::bind(&CInfoWindow::close,temp);
if(onNo)
temp->buttons[1]->callback += boost::bind(&CInfoWindow::close,temp);
temp->delComps = DelComps;
for(int i=0;i<onYes.funcs.size();i++)
temp->buttons[0]->callback += onYes.funcs[i];
for(int i=0;i<onNo.funcs.size();i++)
temp->buttons[1]->callback += onNo.funcs[i];
//if(onYes)
// temp->buttons[0]->callback += boost::bind(&CInfoWindow::close,temp);
//if(onNo)
// temp->buttons[1]->callback += boost::bind(&CInfoWindow::close,temp);
temp->activate();
LOCPLINT->objsToBlit.push_back(temp);
}
@ -2141,7 +2203,7 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
{
adventureInt->heroWindow->setHero(hero);
this->objsToBlit.push_back(adventureInt->heroWindow);
adventureInt->hide();
curint->deactivate();
adventureInt->heroWindow->activate();
}
CStatusBar::CStatusBar(int x, int y, std::string name, int maxw)
@ -2797,7 +2859,7 @@ void CRecrutationWindow::show(SDL_Surface * to)
curx = pos.x + 192 + 102 - (102*creatures.size()/2) - (18*(creatures.size()-1)/2);
for(int i=0;i<creatures.size();i++)
{
creatures[i].pic->blitPic(screen,curx-50,pos.y+130-65,!(c%2));
creatures[i].pic->blitPic(screen,curx-50,pos.y+130-65,!(c%4));
curx += 120;
}
c++;
@ -2966,8 +3028,11 @@ void CCreInfoWindow::show(SDL_Surface * to)
{
char pom[15];
blitAt(bitmap,pos.x,pos.y,screen);
anim->blitPic(screen,pos.x+21,pos.y+48,(type) && anf%4);
anf++;
anim->blitPic(screen,pos.x+21,pos.y+48,(type) && !(anf%4));
if(++anf==4)
anf=0;
if(count.size())
printTo(count.c_str(),pos.x+114,pos.y+174,GEOR16,zwykly);
if(upgrade)
upgrade->show();
if(dismiss)
@ -2976,9 +3041,11 @@ void CCreInfoWindow::show(SDL_Surface * to)
ok->show();
}
CCreInfoWindow::CCreInfoWindow(int Cid, int Type, StackState *State, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui)
CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState *State, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui)
:ok(0),dismiss(0),upgrade(0),type(Type),dsm(Dsm),dependant(0)
{
active = false;
anf = 0;
c = &CGI->creh->creatures[Cid];
bitmap = BitmapHandler::loadBitmap("CRSTKPU.bmp");
pos.x = screen->w/2 - bitmap->w/2;
@ -2991,6 +3058,13 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, StackState *State, boost::func
if(!type) anim->anim->setType(1);
char pom[25];int hlp=0;
if(creatureCount)
{
SDL_itoa(creatureCount,pom,10);
count = pom;
}
printAtMiddle(c->namePl,149,30,GEOR13,zwykly,bitmap); //creature name
//atttack
@ -3063,24 +3137,41 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, StackState *State, boost::func
{
if(Upg && ui)
{
for(std::set<std::pair<int,int> >::iterator i=ui->cost[0].begin(); i!=ui->cost[0].end(); i++) //calculate upgrade cost
{
upgResCost.push_back(new SComponent(SComponent::resource,i->first,i->second*creatureCount));
}
CFunctionList<void()> fs[2];
fs[0] += Upg;
fs[0] += boost::bind(&CCreInfoWindow::close,this);
std::vector<SComponent*> upgResCost;
for(std::set<std::pair<int,int> >::iterator i=ui->cost[0].begin(); i!=ui->cost[0].end(); i++)
CCastleInterface *pom;
if(pom=dynamic_cast<CCastleInterface*>(LOCPLINT->curint)) //if town screen is opened it needs to be redrawn
{
upgResCost.push_back(new SComponent(SComponent::resource,i->first,i->second)); //will be deleted by CInfoWindow::close
fs[1] += boost::bind(&CCastleInterface::showAll,pom,screen,true);
}
boost::function<void()> fff = boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[207],upgResCost,fs[0],fs[1],false);
upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,fff,pos.x+76,pos.y+237,"IVIEWCR.DEF");
fs[1] += boost::bind(&CCreInfoWindow::activate,this);
CFunctionList<void()> cfl = boost::bind(&CCreInfoWindow::deactivate,this);
cfl += boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[207],boost::ref(upgResCost),fs[0],fs[1],false,false);
upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,cfl,pos.x+76,pos.y+237,"IVIEWCR.DEF");
}
if(Dsm)
{
CFunctionList<void()> fs[2];
fs[0] += Dsm;
fs[0] += boost::bind(&CCreInfoWindow::close,this);
boost::function<void()> fff = boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[12],std::vector<SComponent*>(),fs[0],fs[1],false);
dismiss = new AdventureMapButton("",CGI->preth->zelp[445].second,fff,pos.x+21,pos.y+237,"IVIEWCR2.DEF");
//on dismiss confirmed
fs[0] += Dsm; //dismiss
fs[0] += boost::bind(&CCreInfoWindow::close,this);//close this window
CCastleInterface *pom;
if(pom=dynamic_cast<CCastleInterface*>(LOCPLINT->curint)) //if town screen is opened it needs to be redrawn
{
fs[1] += boost::bind(&CCastleInterface::showAll,pom,screen,true);
}
fs[1] += boost::bind(&CCreInfoWindow::activate,this);
CFunctionList<void()> cfl = boost::bind(&CCreInfoWindow::deactivate,this);
cfl += boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[12],std::vector<SComponent*>(),fs[0],fs[1],false,false);
dismiss = new AdventureMapButton("",CGI->preth->zelp[445].second,cfl,pos.x+21,pos.y+237,"IVIEWCR2.DEF");
}
ok = new AdventureMapButton("",CGI->preth->zelp[445].second,boost::bind(&CCreInfoWindow::close,this),pos.x+216,pos.y+237,"IOKAY.DEF");
}
@ -3096,9 +3187,13 @@ CCreInfoWindow::~CCreInfoWindow()
delete upgrade;
delete ok;
delete dismiss;
for(int i=0; i<upgResCost.size();i++)
delete upgResCost[i];
}
void CCreInfoWindow::activate()
{
if(active) return;
active = true;
if(!type)
ClickableR::activate();
LOCPLINT->objsToBlit.push_back(this);
@ -3108,8 +3203,6 @@ void CCreInfoWindow::activate()
dismiss->activate();
if(upgrade)
upgrade->activate();
if(type)
LOCPLINT->curint->deactivate();
}
void CCreInfoWindow::close()
{
@ -3119,7 +3212,6 @@ void CCreInfoWindow::close()
if(type)
LOCPLINT->curint->activate();
delete this;
}
void CCreInfoWindow::clickRight(boost::logic::tribool down)
{
@ -3137,6 +3229,8 @@ void CCreInfoWindow::keyPressed (SDL_KeyboardEvent & key)
}
void CCreInfoWindow::deactivate()
{
if(!active) return;
active = false;
if(!type)
ClickableR::deactivate();
LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));

View File

@ -24,6 +24,8 @@ class CCreatureSet;
class CGObjectInstance;
class CSlider;
struct UpgradeInfo;
template <typename T> struct CondSh;
namespace boost
{
class mutex;
@ -158,8 +160,9 @@ public:
};
class CInfoWindow : public CSimpleWindow //text + comp. + ok button
{ //window deletes its components when closed
{ //window able to delete its components when closed
public:
bool delComps; //whether comps will be deleted
std::vector<AdventureMapButton *> buttons;
std::vector<SComponent*> components;
virtual void close();
@ -303,6 +306,7 @@ class CPlayerInterface : public CGameInterface
{
public:
//minor interfaces
CondSh<bool> *showingDialog;
boost::mutex *pim;
bool makingTurn;
SDL_Event * current;
@ -311,7 +315,6 @@ public:
CCastleInterface * castleInt;
FPSmanager * mainFPSmng;
IStatusBar *statusbar;
//to commucate with engine
CCallback * cb;
@ -339,6 +342,7 @@ public:
void garrisonChanged(const CGObjectInstance * obj);
void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
void heroInGarrisonChange(const CGTownInstance *town);
//for battles
void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right
void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning
@ -367,7 +371,7 @@ public:
int3 repairScreenPos(int3 pos);
void removeObjToBlit(IShowable* obj);
void showInfoDialog(std::string &text, std::vector<SComponent*> & components);
void showYesNoDialog(std::string &text, std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool deactivateCur);
void showYesNoDialog(std::string &text, std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool deactivateCur, bool DelComps); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close
CPlayerInterface(int Player, int serial);//c-tor
~CPlayerInterface();//d-tor
@ -521,17 +525,20 @@ public:
class CCreInfoWindow : public IShowable, public KeyInterested, public ClickableR
{
public:
bool active;
int type;//0 - rclick popup; 1 - normal window
SDL_Surface *bitmap;
char anf;
std::string count; //creature count in text format
boost::function<void()> dsm;
CCreaturePic *anim;
CCreature *c;
CInfoWindow *dependant; //it may be dialog asking whther upgrade/dismiss stack (if opened)
std::vector<SComponent*> upgResCost; //cost of upgrade (if not possible then empty)
AdventureMapButton *dismiss, *upgrade, *ok;
CCreInfoWindow(int Cid, int Type, StackState *State, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui);
CCreInfoWindow(int Cid, int Type, int creatureCount, StackState *State, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui);
~CCreInfoWindow();
void activate();
void close();

View File

@ -337,6 +337,17 @@ void CClient::process(int what)
//TODO: do we need to inform interface?
break;
}
case 508:
{
SetHeroesInTown inTown;
*serv >> inTown;
std::cout << "Setting heroes in town " << inTown.tid << std::endl;
gs->apply(&inTown);
CGTownInstance *t = gs->getTown(inTown.tid);
if(vstd::contains(playerint,t->tempOwner))
playerint[t->tempOwner]->heroInGarrisonChange(t);
break;
}
case 1001:
{
SetObjectProperty sop;

View File

@ -154,6 +154,16 @@ struct SetAvailableCreatures : public CPack<SetAvailableCreatures> //506
h & tid & creatures;
}
};
struct SetHeroesInTown : public CPack<SetHeroesInTown> //508
{
SetHeroesInTown(){type = 508;};
si32 tid, visiting, garrison; //id of town, visiting hero, hero in garrison
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tid & visiting & garrison;
}
};
struct NewTurn : public CPack<NewTurn> //101
{
struct Hero

View File

@ -1107,7 +1107,7 @@ std::string CMapHandler::getDefName(int id, int subid)
#endif
}
bool CMapHandler::printObject(CGObjectInstance *obj)
bool CMapHandler::printObject(const CGObjectInstance *obj)
{
CDefHandler * curd = obj->defInfo->handler;
for(int fx=0; fx<curd->ourImages[0].bitmap->w/32; ++fx)
@ -1119,7 +1119,7 @@ bool CMapHandler::printObject(CGObjectInstance *obj)
cr.h = 32;
cr.x = fx*32;
cr.y = fy*32;
std::pair<CGObjectInstance*,SDL_Rect> toAdd = std::make_pair(obj, cr);
std::pair<const CGObjectInstance*,SDL_Rect> toAdd = std::make_pair(obj, cr);
if((obj->pos.x + fx - curd->ourImages[0].bitmap->w/32+1)>=0 && (obj->pos.x + fx - curd->ourImages[0].bitmap->w/32+1)<ttiles.size()-Woff && (obj->pos.y + fy - curd->ourImages[0].bitmap->h/32+1)>=0 && (obj->pos.y + fy - curd->ourImages[0].bitmap->h/32+1)<ttiles[0].size()-Hoff)
{
TerrainTile2 & curt =
@ -1137,7 +1137,7 @@ bool CMapHandler::printObject(CGObjectInstance *obj)
return true;
}
bool CMapHandler::hideObject(CGObjectInstance *obj)
bool CMapHandler::hideObject(const CGObjectInstance *obj)
{
CDefHandler * curd = obj->defInfo->handler;
for(int fx=0; fx<curd->ourImages[0].bitmap->w/32; ++fx)

View File

@ -86,8 +86,8 @@ public:
//std::vector< CGObjectInstance * > getVisitableObjs(int3 pos); //returns vector of visitable objects at certain position
CGObjectInstance * createObject(int id, int subid, int3 pos, int owner=254); //creates a new object with a certain id and subid
std::string getDefName(int id, int subid); //returns name of def for object with given id and subid
bool printObject(CGObjectInstance * obj); //puts appropriate things to ttiles, so obj will be visible on map
bool hideObject(CGObjectInstance * obj); //removes appropriate things from ttiles, so obj will be no longer visible on map (but still will exist)
bool printObject(const CGObjectInstance * obj); //puts appropriate things to ttiles, so obj will be visible on map
bool hideObject(const CGObjectInstance * obj); //removes appropriate things from ttiles, so obj will be no longer visible on map (but still will exist)
bool removeObject(CGObjectInstance * obj); //removes object from each place in VCMI (I hope)
void init();
void calculateBlockedPos();

View File

@ -666,6 +666,72 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
upgend:
break;
}
case 508: //garrison swap
{
si32 tid;
c >> tid;
CGTownInstance *town = gs->getTown(tid);
if(!town->garrisonHero && town->visitingHero) //visiting => garrison, merge armies
{
CCreatureSet csn = town->visitingHero->army, cso = town->army;
while(!cso.slots.empty())//while there are unmoved creatures
{
int pos = csn.getSlotFor(cso.slots.begin()->first);
if(pos<0)
goto handleConEnd;
if(csn.slots.find(pos)!=csn.slots.end()) //add creatures to the existing stack
{
csn.slots[pos].second += cso.slots.begin()->second.second;
}
else //move stack on the free pos
{
csn.slots[pos].first = cso.slots.begin()->second.first;
csn.slots[pos].second = cso.slots.begin()->second.second;
}
cso.slots.erase(cso.slots.begin());
}
SetGarrisons sg;
sg.garrs[town->visitingHero->id] = csn;
sg.garrs[town->id] = csn;
sendAndApply(&sg);
SetHeroesInTown intown;
intown.tid = tid;
intown.visiting = -1;
intown.garrison = town->visitingHero->id;
sendAndApply(&intown);
}
else if (town->garrisonHero && !town->visitingHero) //move hero out of the garrison
{
//town will be empty
SetGarrisons sg;
sg.garrs[tid] = CCreatureSet();
sendAndApply(&sg);
SetHeroesInTown intown;
intown.tid = tid;
intown.garrison = -1;
intown.visiting = town->garrisonHero->id;
sendAndApply(&intown);
}
else if (town->garrisonHero && town->visitingHero) //swap visiting and garrison hero
{
SetGarrisons sg;
sg.garrs[town->id] = town->visitingHero->army;
sendAndApply(&sg);
SetHeroesInTown intown;
intown.tid = tid;
intown.garrison = town->visitingHero->id;
intown.visiting = town->garrisonHero->id;
sendAndApply(&intown);
}
else
{
std::cout << "Warning, wrong garrison swap command for " << tid << std::endl;
}
break;
}
case 2001:
{
ui32 qid, answer;
@ -759,6 +825,8 @@ upgend:
{
end2 = true;
}
handleConEnd:
;
}
void CGameHandler::moveStack(int stack, int dest)
{