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

Support for Tavern on adv map.

This commit is contained in:
Michał W. Urbańczyk 2010-07-08 23:03:27 +00:00
parent 24b47ce006
commit 1e30045541
18 changed files with 185 additions and 141 deletions

View File

@ -137,7 +137,7 @@ void CCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInsta
if(obj == NULL) if(obj == NULL)
return; return;
if(obj->ID == TOWNI_TYPE) //it is a town if(obj->ID == TOWNI_TYPE || obj->ID == 95) //it is a town or adv map tavern
{ {
gs->obtainPlayersStats(thi, gs->players[player].towns.size()); gs->obtainPlayersStats(thi, gs->players[player].towns.size());
} }
@ -793,21 +793,22 @@ void CCallback::setSelection(const CArmedInstance * obj)
} }
} }
void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *hero) void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)
{ {
ui8 i=0; ui8 i=0;
for(; i<gs->players[player].availableHeroes.size(); i++) for(; i<gs->players[player].availableHeroes.size(); i++)
{ {
if(gs->players[player].availableHeroes[i] == hero) if(gs->players[player].availableHeroes[i] == hero)
{ {
HireHero pack(i,town->id); HireHero pack(i,townOrTavern->id);
pack.player = player;
sendRequest(&pack); sendRequest(&pack);
return; return;
} }
} }
} }
std::vector<const CGHeroInstance *> CCallback::getAvailableHeroes(const CGTownInstance * town) const std::vector<const CGHeroInstance *> CCallback::getAvailableHeroes(const CGObjectInstance * townOrTavern) const
{ {
std::vector<const CGHeroInstance *> ret(gs->players[player].availableHeroes.size()); std::vector<const CGHeroInstance *> ret(gs->players[player].availableHeroes.size());
std::copy(gs->players[player].availableHeroes.begin(),gs->players[player].availableHeroes.end(),ret.begin()); std::copy(gs->players[player].availableHeroes.begin(),gs->players[player].availableHeroes.end(),ret.begin());
@ -980,6 +981,12 @@ int CCallback::getPlayerStatus(int player) const
return -1; return -1;
return ps->status; return ps->status;
} }
std::string CCallback::getTavernGossip(const CGObjectInstance * townOrTavern) const
{
return "GOSSIP TEST";
}
InfoAboutTown::InfoAboutTown() InfoAboutTown::InfoAboutTown()
{ {
tType = NULL; tType = NULL;

View File

@ -78,7 +78,7 @@ public:
virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses given hero; true - successfuly, false - not successfuly virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses given hero; true - successfuly, false - not successfuly
//town //town
virtual void recruitHero(const CGTownInstance *town, const CGHeroInstance *hero)=0; virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0;
virtual bool buildBuilding(const CGTownInstance *town, si32 buildingID)=0; virtual bool buildBuilding(const CGTownInstance *town, si32 buildingID)=0;
virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)=0; virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)=0;
virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made
@ -143,7 +143,8 @@ public:
virtual int howManyTowns()const =0; virtual int howManyTowns()const =0;
virtual const CGTownInstance * getTownInfo(int val, bool mode)const =0; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial) virtual const CGTownInstance * getTownInfo(int val, bool mode)const =0; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
virtual std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const=0; virtual std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const=0;
virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const =0; //heroes that can be recruited
virtual std::string getTavernGossip(const CGObjectInstance * townOrTavern) const =0;
virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
virtual std::set<int> getBuildingRequiments(const CGTownInstance *t, int ID) =0; virtual std::set<int> getBuildingRequiments(const CGTownInstance *t, int ID) =0;
virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const = 0; virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const = 0;
@ -229,7 +230,7 @@ public:
void trade(const CGObjectInstance *market, int mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL); void trade(const CGObjectInstance *market, int mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL);
void setFormation(const CGHeroInstance * hero, bool tight); void setFormation(const CGHeroInstance * hero, bool tight);
void setSelection(const CArmedInstance * obj); void setSelection(const CArmedInstance * obj);
void recruitHero(const CGTownInstance *town, const CGHeroInstance *hero); void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero);
void save(const std::string &fname); void save(const std::string &fname);
void sendMessage(const std::string &mess); void sendMessage(const std::string &mess);
void buildBoat(const IShipyard *obj); void buildBoat(const IShipyard *obj);
@ -267,7 +268,8 @@ public:
std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos) const; std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos) const;
std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const; std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const; //heroes that can be recruited std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
std::string getTavernGossip(const CGObjectInstance * townOrTavern) const;
const TerrainTile * getTileInfo(int3 tile) const; const TerrainTile * getTileInfo(int3 tile) const;
int canBuildStructure(const CGTownInstance *t, int ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements int canBuildStructure(const CGTownInstance *t, int ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
std::set<int> getBuildingRequiments(const CGTownInstance *t, int ID); std::set<int> getBuildingRequiments(const CGTownInstance *t, int ID);

View File

@ -84,6 +84,7 @@ public:
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) = 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, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
virtual void showPuzzleMap(){}; virtual void showPuzzleMap(){};
virtual void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor){}; virtual void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor){};
virtual void showTavernWindow(const CGObjectInstance *townOrTavern){};
virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID){}; //called when a hero casts a spell virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID){}; //called when a hero casts a spell
virtual void tileHidden(const std::set<int3> &pos){}; virtual void tileHidden(const std::set<int3> &pos){};
virtual void tileRevealed(const std::set<int3> &pos){}; virtual void tileRevealed(const std::set<int3> &pos){};

View File

@ -1389,9 +1389,7 @@ void CCastleInterface::enterMageGuild()
void CCastleInterface::enterTavern() void CCastleInterface::enterTavern()
{ {
std::vector<const CGHeroInstance*> h = LOCPLINT->cb->getAvailableHeroes(town); LOCPLINT->showTavernWindow(town);
CTavernWindow *tv = new CTavernWindow(h[0],h[1],"GOSSIP TEST");
GH.pushInt(tv);
} }
void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key ) void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )

View File

@ -1995,4 +1995,10 @@ void CPlayerInterface::availableArtifactsChanged(const CGBlackMarket *bm /*= NUL
{ {
if(CMarketplaceWindow *cmw = dynamic_cast<CMarketplaceWindow*>(GH.topInt())) if(CMarketplaceWindow *cmw = dynamic_cast<CMarketplaceWindow*>(GH.topInt()))
cmw->artifactsChanged(false); cmw->artifactsChanged(false);
}
void CPlayerInterface::showTavernWindow(const CGObjectInstance *townOrTavern)
{
CTavernWindow *tv = new CTavernWindow(townOrTavern);
GH.pushInt(tv);
} }

View File

@ -163,6 +163,7 @@ public:
void showArtifactAssemblyDialog(ui32 artifactID, ui32 assembleTo, bool assemble, CFunctionList<void()> onYes, CFunctionList<void()> onNo); void showArtifactAssemblyDialog(ui32 artifactID, ui32 assembleTo, bool assemble, CFunctionList<void()> onYes, CFunctionList<void()> onNo);
void showPuzzleMap(); void showPuzzleMap();
void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor); void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor);
void showTavernWindow(const CGObjectInstance *townOrTavern);
void advmapSpellCast(const CGHeroInstance * caster, int spellID); //called when a hero casts a spell void advmapSpellCast(const CGHeroInstance * caster, int spellID); //called when a hero casts a spell
void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war
void tileRevealed(const std::set<int3> &pos); //called when fog of war disappears from given tiles void tileRevealed(const std::set<int3> &pos); //called when fog of war disappears from given tiles

View File

@ -3403,38 +3403,36 @@ void CSystemOptionsWindow::show(SDL_Surface *to)
effectsVolume->show(to); effectsVolume->show(to);
} }
CTavernWindow::CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2, const std::string &gossip) CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj)
:h1(selected,0,72,299,H1),h2(selected,1,162,299,H2) : tavernObj(TavernObj)
{ {
if(H1) OBJ_CONSTRUCTION_CAPTURING_ALL;
std::vector<const CGHeroInstance*> h = LOCPLINT->cb->getAvailableHeroes(TavernObj);
assert(h.size() == 2);
h1 = new HeroPortrait(selected,0,72,299,h[0]);
h2 = new HeroPortrait(selected,1,162,299,h[1]);
if(h[0])
selected = 0; selected = 0;
else else
selected = -1; selected = -1;
oldSelected = -1; oldSelected = -1;
SDL_Surface *hhlp = BitmapHandler::loadBitmap("TPTAVERN.bmp"); bg = new CPicture("TPTAVERN.bmp");
graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID); bg->colorizeAndConvert(LOCPLINT->playerID);
bg = SDL_ConvertSurface(hhlp,screen->format,0); pos = center(bg->pos);
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
SDL_FreeSurface(hhlp);
printAtMiddle(CGI->generaltexth->jktexts[37],200,35,FONT_BIG,tytulowy,bg);
printAtMiddle("2500",320,328,FONT_SMALL,zwykly,bg); printAtMiddle(CGI->generaltexth->jktexts[37],200,35,FONT_BIG,tytulowy,*bg);
printAtMiddle("2500",320,328,FONT_SMALL,zwykly,*bg);
// printAtMiddle(CGI->generaltexth->jktexts[38],146,283,FONT_BIG,tytulowy,bg); //what is this??? // printAtMiddle(CGI->generaltexth->jktexts[38],146,283,FONT_BIG,tytulowy,bg); //what is this???
printAtMiddleWB(gossip,200,220,FONT_SMALL,50,zwykly,bg); printAtMiddleWB(LOCPLINT->cb->getTavernGossip(tavernObj), 200, 220, FONT_SMALL, 50, zwykly, *bg);
pos.w = bg->w;
pos.h = bg->h;
pos.x = (screen->w-bg->w)/2;
pos.y = (screen->h-bg->h)/2;
bar = new CStatusBar(pos.x+8, pos.y+478, "APHLFTRT.bmp", 380);
h1.pos.x += pos.x;
h2.pos.x += pos.x;
h1.pos.y += pos.y;
h2.pos.y += pos.y;
cancel = new AdventureMapButton(CGI->generaltexth->tavernInfo[7],"", boost::bind(&CTavernWindow::close, this), pos.x+310,pos.y+428, "ICANCEL.DEF", SDLK_ESCAPE);
recruit = new AdventureMapButton("", "", boost::bind(&CTavernWindow::recruitb, this), pos.x+272, pos.y+355, "TPTAV01.DEF", SDLK_RETURN); bar = new CGStatusBar(8, 478, "APHLFTRT.bmp", 380);
thiefGuild = new AdventureMapButton(CGI->generaltexth->tavernInfo[5],"", boost::bind(&CTavernWindow::thievesguildb, this), pos.x+22, pos.y+428, "TPTAV02.DEF", SDLK_t); cancel = new AdventureMapButton(CGI->generaltexth->tavernInfo[7],"", boost::bind(&CTavernWindow::close, this), 310, 428, "ICANCEL.DEF", SDLK_ESCAPE);
recruit = new AdventureMapButton("", "", boost::bind(&CTavernWindow::recruitb, this), 272, 355, "TPTAV01.DEF", SDLK_RETURN);
thiefGuild = new AdventureMapButton(CGI->generaltexth->tavernInfo[5],"", boost::bind(&CTavernWindow::thievesguildb, this), 22, 428, "TPTAV02.DEF", SDLK_t);
if(LOCPLINT->cb->getResourceAmount(6) < 2500) //not enough gold if(LOCPLINT->cb->getResourceAmount(6) < 2500) //not enough gold
{ {
@ -3454,7 +3452,7 @@ CTavernWindow::CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2,
} }
else else
{ {
if(!H1) if(!h[0])
recruit->block(1); recruit->block(1);
} }
@ -3467,47 +3465,20 @@ CTavernWindow::CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2,
void CTavernWindow::recruitb() void CTavernWindow::recruitb()
{ {
const CGHeroInstance *toBuy = (selected ? h2 : h1).h; const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
const CGObjectInstance *obj = tavernObj;
close(); close();
LOCPLINT->cb->recruitHero(LOCPLINT->castleInt->town,toBuy); LOCPLINT->cb->recruitHero(obj, toBuy);
} }
void CTavernWindow::thievesguildb() void CTavernWindow::thievesguildb()
{ {
GH.pushInt( new CThievesGuildWindow(LOCPLINT->castleInt->town) ); GH.pushInt( new CThievesGuildWindow(tavernObj) );
} }
CTavernWindow::~CTavernWindow() CTavernWindow::~CTavernWindow()
{ {
CGI->videoh->close(); CGI->videoh->close();
SDL_FreeSurface(bg);
delete cancel;
delete thiefGuild;
delete recruit;
delete bar;
}
void CTavernWindow::activate()
{
thiefGuild->activate();
cancel->activate();
if(h1.h)
h1.activate();
if(h2.h)
h2.activate();
recruit->activate();
GH.statusbar = bar;
}
void CTavernWindow::deactivate()
{
thiefGuild->deactivate();
cancel->deactivate();
if(h1.h)
h1.deactivate();
if(h2.h)
h2.deactivate();
recruit->deactivate();
} }
void CTavernWindow::close() void CTavernWindow::close()
@ -3517,20 +3488,12 @@ void CTavernWindow::close()
void CTavernWindow::show(SDL_Surface * to) void CTavernWindow::show(SDL_Surface * to)
{ {
blitAt(bg,pos.x,pos.y,to); CIntObject::show(to);
CGI->videoh->update(pos.x+70, pos.y+56, to, true, false);
if(h1.h)
h1.show(to);
if(h2.h)
h2.show(to);
thiefGuild->show(to);
cancel->show(to);
recruit->show(to);
bar->show(to);
CGI->videoh->update(pos.x+70, pos.y+56, to, true, false);
if(selected >= 0) if(selected >= 0)
{ {
HeroPortrait *sel = selected ? &h2 : &h1; HeroPortrait *sel = selected ? h2 : h1;
if (selected != oldSelected && !recruit->blocked) if (selected != oldSelected && !recruit->blocked)
{ {
@ -3549,28 +3512,14 @@ void CTavernWindow::show(SDL_Surface * to)
void CTavernWindow::HeroPortrait::clickLeft(tribool down, bool previousState) void CTavernWindow::HeroPortrait::clickLeft(tribool down, bool previousState)
{ {
if(previousState && !down) if(previousState && !down && h)
as(); as();
//ClickableL::clickLeft(down); //ClickableL::clickLeft(down);
} }
void CTavernWindow::HeroPortrait::activate()
{
activateLClick();
activateRClick();
activateHover();
}
void CTavernWindow::HeroPortrait::deactivate()
{
deactivateLClick();
deactivateRClick();
deactivateHover();
}
void CTavernWindow::HeroPortrait::clickRight(tribool down, bool previousState) void CTavernWindow::HeroPortrait::clickRight(tribool down, bool previousState)
{ {
if(down) if(down && h)
{ {
adventureInt->heroWindow->setHero(h); adventureInt->heroWindow->setHero(h);
GH.pushInt(new CRClickPopupInt(adventureInt->heroWindow,false)); GH.pushInt(new CRClickPopupInt(adventureInt->heroWindow,false));
@ -3578,13 +3527,15 @@ void CTavernWindow::HeroPortrait::clickRight(tribool down, bool previousState)
} }
CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H) CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H)
:as(sel,id) :as(sel,id), h(H)
{ {
used = LCLICK | RCLICK | HOVER;
h = H; h = H;
pos.x = x; pos.x = x;
pos.y = y; pos.y = y;
pos.w = 58; pos.w = 58;
pos.h = 64; pos.h = 64;
if(H) if(H)
{ {
hoverName = CGI->generaltexth->tavernInfo[4]; hoverName = CGI->generaltexth->tavernInfo[4];
@ -5370,7 +5321,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
SDL_FreeSurface(bg); SDL_FreeSurface(bg);
exitb = new AdventureMapButton (std::string(), std::string(), boost::bind(&CThievesGuildWindow::bexitf,this), 748, 556, "HSBTNS.def", SDLK_RETURN); exitb = new AdventureMapButton (std::string(), std::string(), boost::bind(&CThievesGuildWindow::bexitf,this), 748, 556, "HSBTNS.def", SDLK_RETURN);
statusBar = new CStatusBar(3, 555, "TStatBar.bmp", 742); statusBar = new CGStatusBar(3, 555, "TStatBar.bmp", 742);
resdatabar = new CMinorResDataBar(); resdatabar = new CMinorResDataBar();
resdatabar->pos.x += pos.x - 3; resdatabar->pos.x += pos.x - 3;
@ -5709,16 +5660,22 @@ CGStatusBar::CGStatusBar(CPicture *BG, EFonts Font /*= FONT_SMALL*/, EAlignment
bg = BG; bg = BG;
moveChild(bg, bg->parent, this); moveChild(bg, bg->parent, this);
pos = bg->pos; pos = bg->pos;
calcOffset();
}
switch(Align) CGStatusBar::CGStatusBar(int x, int y, std::string name/*="ADROLLVR.bmp"*/, int maxw/*=-1*/)
: CLabel(x, y, FONT_SMALL, CENTER)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
init();
bg = new CPicture(name);
pos = bg->pos;
if(maxw < pos.w)
{ {
case CENTER: amin(pos.w, maxw);
textOffset = Point(pos.w/2, pos.h/2); bg->srcRect = new Rect(0, 0, maxw, pos.h);
break;
case BOTTOMRIGHT:
textOffset = Point(pos.w, pos.h);
break;
} }
calcOffset();
} }
CGStatusBar::~CGStatusBar() CGStatusBar::~CGStatusBar()
@ -5737,6 +5694,19 @@ void CGStatusBar::init()
GH.statusbar = this; GH.statusbar = this;
} }
void CGStatusBar::calcOffset()
{
switch(alignment)
{
case CENTER:
textOffset = Point(pos.w/2, pos.h/2);
break;
case BOTTOMRIGHT:
textOffset = Point(pos.w, pos.h);
break;
}
}
CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB ) CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB )
:cb(CB) :cb(CB)
{ {

View File

@ -329,8 +329,10 @@ public:
CGStatusBar(int x, int y, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = zwykly, const std::string &Text = ""); CGStatusBar(int x, int y, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = zwykly, const std::string &Text = "");
CGStatusBar(CPicture *BG, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = zwykly); //given CPicture will be captured by created sbar and it's pos will be used as pos for sbar CGStatusBar(CPicture *BG, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = zwykly); //given CPicture will be captured by created sbar and it's pos will be used as pos for sbar
CGStatusBar(int x, int y, std::string name, int maxw=-1);
~CGStatusBar(); ~CGStatusBar();
void calcOffset();
}; };
class CFocusable class CFocusable
@ -657,31 +659,30 @@ public:
std::string hoverName; std::string hoverName;
vstd::assigner<int,int> as; vstd::assigner<int,int> as;
const CGHeroInstance *h; const CGHeroInstance *h;
void activate(); char descr[100]; // "XXX is a level Y ZZZ with N artifacts"
void deactivate();
void clickLeft(tribool down, bool previousState); void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState); void clickRight(tribool down, bool previousState);
void hover (bool on); void hover (bool on);
HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H); HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H);
void show(SDL_Surface * to); void show(SDL_Surface * to);
char descr[100]; // "XXX is a level Y ZZZ with N artifacts"
} h1, h2; //recruitable heroes
SDL_Surface *bg; //background } *h1, *h2; //recruitable heroes
CStatusBar *bar; //tavern's internal status bar
CPicture *bg; //background
CGStatusBar *bar; //tavern's internal status bar
int selected;//0 (left) or 1 (right) int selected;//0 (left) or 1 (right)
int oldSelected;//0 (left) or 1 (right) int oldSelected;//0 (left) or 1 (right)
AdventureMapButton *thiefGuild, *cancel, *recruit; AdventureMapButton *thiefGuild, *cancel, *recruit;
const CGObjectInstance *tavernObj;
CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2, const std::string &gossip); //c-tor CTavernWindow(const CGObjectInstance *TavernObj); //c-tor
~CTavernWindow(); //d-tor ~CTavernWindow(); //d-tor
void recruitb(); void recruitb();
void close(); void close();
void thievesguildb(); void thievesguildb();
void activate();
void deactivate();
void show(SDL_Surface * to); void show(SDL_Surface * to);
}; };
@ -1049,7 +1050,7 @@ class CThievesGuildWindow : public CIntObject
{ {
const CGObjectInstance * owner; const CGObjectInstance * owner;
CStatusBar * statusBar; CGStatusBar * statusBar;
AdventureMapButton * exitb; AdventureMapButton * exitb;
SDL_Surface * background; SDL_Surface * background;
CMinorResDataBar * resdatabar; CMinorResDataBar * resdatabar;

View File

@ -343,10 +343,12 @@ void HeroRecruited::applyCl( CClient *cl )
CGI->mh->initHeroDef(h); CGI->mh->initHeroDef(h);
CGI->mh->printObject(h); CGI->mh->printObject(h);
if(vstd::contains(cl->playerint,h->tempOwner)) if(vstd::contains(cl->playerint,h->tempOwner))
{ {
cl->playerint[h->tempOwner]->heroCreated(h); cl->playerint[h->tempOwner]->heroCreated(h);
cl->playerint[h->tempOwner]->heroInGarrisonChange(GS(cl)->getTown(tid)); if(const CGTownInstance *t = GS(cl)->getTown(tid))
cl->playerint[h->tempOwner]->heroInGarrisonChange(t);
} }
} }
@ -733,6 +735,10 @@ void OpenWindow::applyCl(CClient *cl)
{ {
INTERFACE_CALL_IF_PRESENT(id1, showPuzzleMap); INTERFACE_CALL_IF_PRESENT(id1, showPuzzleMap);
} }
case TAVERN_WINDOW:
const CGObjectInstance *obj1 = cl->getObj(id1),
*obj2 = cl->getObj(id2);
INTERFACE_CALL_IF_PRESENT(obj1->tempOwner, showTavernWindow, obj2);
break; break;
} }

View File

@ -383,6 +383,12 @@ bool CGObjectInstance::operator<(const CGObjectInstance & cmp) const //screen p
void CGObjectInstance::initObj() void CGObjectInstance::initObj()
{ {
switch(ID)
{
case 95:
blockVisit = true;
break;
}
} }
void CGObjectInstance::setProperty( ui8 what, ui32 val ) void CGObjectInstance::setProperty( ui8 what, ui32 val )
@ -474,6 +480,15 @@ void CGObjectInstance::giveDummyBonus(int heroID, ui8 duration) const
void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
{ {
switch(ID)
{
case 95:
OpenWindow ow;
ow.window = OpenWindow::TAVERN_WINDOW;
ow.id1 = h->id;
ow.id2 = id;
cb->sendAndApply(&ow);
}
} }
ui8 CGObjectInstance::getPassableness() const ui8 CGObjectInstance::getPassableness() const

View File

@ -893,7 +893,12 @@ CGTownInstance *CGameState::getTown(int objid)
{ {
if(objid<0 || objid>=map->objects.size()) if(objid<0 || objid>=map->objects.size())
return NULL; return NULL;
return static_cast<CGTownInstance *>(map->objects[objid]); CGObjectInstance *obj = map->objects[objid];
if(obj->ID != TOWNI_TYPE)
return NULL;
return static_cast<CGTownInstance *>(obj);
} }
const CGTownInstance * CGameState::getTown( int objid ) const const CGTownInstance * CGameState::getTown( int objid ) const

View File

@ -8,6 +8,7 @@
#include "../hch/CSpellHandler.h" #include "../hch/CSpellHandler.h"
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include <boost/random/linear_congruential.hpp> #include <boost/random/linear_congruential.hpp>
#include "../hch/CTownHandler.h"
/* /*
* IGameCallback.cpp, part of VCMI engine * IGameCallback.cpp, part of VCMI engine
@ -233,3 +234,8 @@ const PlayerState * IGameCallback::getPlayerState( int color )
{ {
return gs->getPlayer(color, false); return gs->getPlayer(color, false);
} }
const CTown * IGameCallback::getNativeTown(int color)
{
return &VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(color).castle];
}

View File

@ -36,6 +36,7 @@ class CArtifact;
class CArmedInstance; class CArmedInstance;
struct TerrainTile; struct TerrainTile;
struct PlayerState; struct PlayerState;
class CTown;
class DLL_EXPORT IGameCallback class DLL_EXPORT IGameCallback
{ {
@ -67,6 +68,7 @@ public:
virtual int3 getMapSize(); //returns size of the map virtual int3 getMapSize(); //returns size of the map
virtual TerrainTile * getTile(int3 pos); virtual TerrainTile * getTile(int3 pos);
virtual const PlayerState * getPlayerState(int color); virtual const PlayerState * getPlayerState(int color);
virtual const CTown *getNativeTown(int color);
//do sth //do sth
virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0; virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0;

View File

@ -627,7 +627,8 @@ struct OpenWindow : public CPackForClient //517
OpenWindow(){type = 517;}; OpenWindow(){type = 517;};
void applyCl(CClient *cl); void applyCl(CClient *cl);
enum EWindow {EXCHANGE_WINDOW, RECRUITMENT_FIRST, RECRUITMENT_ALL, SHIPYARD_WINDOW, THIEVES_GUILD, PUZZLE_MAP, MARKET_WINDOW}; enum EWindow {EXCHANGE_WINDOW, RECRUITMENT_FIRST, RECRUITMENT_ALL, SHIPYARD_WINDOW, THIEVES_GUILD, PUZZLE_MAP,
MARKET_WINDOW, TAVERN_WINDOW};
ui8 window; ui8 window;
ui32 id1, id2; ui32 id1, id2;
@ -1434,12 +1435,13 @@ struct HireHero : public CPackForServer
{ {
HireHero(){}; HireHero(){};
HireHero(si32 HID, si32 TID):hid(HID),tid(TID){}; HireHero(si32 HID, si32 TID):hid(HID),tid(TID){};
si32 hid, tid; //available hero serial and town id si32 hid, tid; //available hero serial and town (tavern) id
ui8 player;
bool applyGh(CGameHandler *gh); bool applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & hid & tid; h & hid & tid & player;
} }
}; };

View File

@ -551,8 +551,12 @@ DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
gs->getPlayer(h->getOwner())->heroes.push_back(h); gs->getPlayer(h->getOwner())->heroes.push_back(h);
h->initObj(); h->initObj();
gs->map->addBlockVisTiles(h); gs->map->addBlockVisTiles(h);
t->visitingHero = h;
h->visitedTown = t; if(t)
{
t->visitingHero = h;
h->visitedTown = t;
}
h->inTownGarrison = false; h->inTownGarrison = false;
} }

View File

@ -952,8 +952,6 @@ void CGameHandler::newTurn()
if(gs->getDate(1)==7) //first day of week - new heroes in tavern if(gs->getDate(1)==7) //first day of week - new heroes in tavern
{ {
const CTown *nativeTownType = &VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle];
SetAvailableHeroes sah; SetAvailableHeroes sah;
sah.player = i->first; sah.player = i->first;
@ -961,7 +959,7 @@ void CGameHandler::newTurn()
CHeroClass *banned = NULL; CHeroClass *banned = NULL;
for (int j = 0; j < AVAILABLE_HEROES_PER_PLAYER; j++) for (int j = 0; j < AVAILABLE_HEROES_PER_PLAYER; j++)
{ {
if(CGHeroInstance *h = gs->hpool.pickHeroFor(j == 0, i->first, nativeTownType, pool, banned)) //first hero - native if possible, second hero -> any other class if(CGHeroInstance *h = gs->hpool.pickHeroFor(j == 0, i->first, getNativeTown(i->first), pool, banned)) //first hero - native if possible, second hero -> any other class
{ {
sah.hid[j] = h->subID; sah.hid[j] = h->subID;
h->initArmy(sah.army[j] = new CCreatureSet()); h->initArmy(sah.army[j] = new CCreatureSet());
@ -3279,35 +3277,47 @@ bool CGameHandler::setFormation( si32 hid, ui8 formation )
return true; return true;
} }
bool CGameHandler::hireHero( ui32 tid, ui8 hid ) bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, ui8 player)
{ {
const CGTownInstance *t = gs->getTown(tid); const PlayerState *p = gs->getPlayer(player);
const PlayerState *p = gs->getPlayer(t->tempOwner); const CGTownInstance *t = gs->getTown(obj->id);
if(!vstd::contains(t->builtBuildings,5) && complain("No tavern!") //common prconditions
|| p->resources[6]<2500 && complain("Not enough gold for buying hero!") if( p->resources[6]<2500 && complain("Not enough gold for buying hero!")
|| t->visitingHero && complain("There is visiting hero - no place!") || getHeroCount(player, false) >= 8 && complain("Cannot hire hero, only 8 wandering heroes are allowed!"))
|| getHeroCount(t->tempOwner,false) >= 8 && complain("Cannot hire hero, only 8 wandering heroes are allowed!")
)
return false; return false;
if(t) //tavern in town
{
if(!vstd::contains(t->builtBuildings,5) && complain("No tavern!")
|| t->visitingHero && complain("There is visiting hero - no place!"))
return false;
}
else if(obj->ID == 95) //Tavern on adv map
{
if(getTile(obj->visitablePos())->visitableObjects.back() != obj && complain("Tavern entry must be unoccupied!"))
return false;
}
CGHeroInstance *nh = p->availableHeroes[hid]; CGHeroInstance *nh = p->availableHeroes[hid];
assert(nh); assert(nh);
HeroRecruited hr; HeroRecruited hr;
hr.tid = tid; hr.tid = obj->id;
hr.hid = nh->subID; hr.hid = nh->subID;
hr.player = t->tempOwner; hr.player = player;
hr.tile = t->pos - int3(1,0,0); hr.tile = obj->visitablePos() + nh->getVisitableOffset();
sendAndApply(&hr); sendAndApply(&hr);
std::map<ui32,CGHeroInstance *> pool = gs->unusedHeroesFromPool(); std::map<ui32,CGHeroInstance *> pool = gs->unusedHeroesFromPool();
const CGHeroInstance *theOtherHero = p->availableHeroes[!hid]; const CGHeroInstance *theOtherHero = p->availableHeroes[!hid];
const CGHeroInstance *newHero = gs->hpool.pickHeroFor(false, t->tempOwner,t->town, pool, theOtherHero->type->heroClass); const CGHeroInstance *newHero = gs->hpool.pickHeroFor(false, player, getNativeTown(player), pool, theOtherHero->type->heroClass);
SetAvailableHeroes sah; SetAvailableHeroes sah;
sah.player = t->tempOwner; sah.player = player;
if(newHero) if(newHero)
{ {
@ -3322,13 +3332,16 @@ bool CGameHandler::hireHero( ui32 tid, ui8 hid )
sendAndApply(&sah); sendAndApply(&sah);
SetResource sr; SetResource sr;
sr.player = t->tempOwner; sr.player = player;
sr.resid = 6; sr.resid = 6;
sr.val = p->resources[6] - 2500; sr.val = p->resources[6] - 2500;
sendAndApply(&sr); sendAndApply(&sr);
vistiCastleObjects (t, nh); if(t)
giveSpells (t,nh); {
vistiCastleObjects (t, nh);
giveSpells (t,nh);
}
return true; return true;
} }

View File

@ -166,7 +166,7 @@ public:
void handleSpellCasting(int spellID, int spellLvl, int destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero, int usedSpellPower); void handleSpellCasting(int spellID, int spellLvl, int destination, ui8 casterSide, ui8 casterColor, const CGHeroInstance * caster, const CGHeroInstance * secHero, int usedSpellPower);
bool makeCustomAction(BattleAction &ba); bool makeCustomAction(BattleAction &ba);
bool queryReply( ui32 qid, ui32 answer ); bool queryReply( ui32 qid, ui32 answer );
bool hireHero( ui32 tid, ui8 hid ); bool hireHero( const CGObjectInstance *obj, ui8 hid, ui8 player );
bool buildBoat( ui32 objid ); bool buildBoat( ui32 objid );
bool setFormation( si32 hid, ui8 formation ); bool setFormation( si32 hid, ui8 formation );
bool tradeResources(const IMarket *market, ui32 val, ui8 player, ui32 id1, ui32 id2); bool tradeResources(const IMarket *market, ui32 val, ui8 player, ui32 id1, ui32 id2);

View File

@ -171,8 +171,13 @@ bool SetFormation::applyGh( CGameHandler *gh )
bool HireHero::applyGh( CGameHandler *gh ) bool HireHero::applyGh( CGameHandler *gh )
{ {
ERROR_IF_NOT_OWNS(tid); const CGObjectInstance *obj = gh->getObj(tid);
return gh->hireHero(tid,hid);
if(obj->ID == TOWNI_TYPE)
ERROR_IF_NOT_OWNS(tid);
//TODO check for visiting hero
return gh->hireHero(obj, hid,player);
} }
bool BuildBoat::applyGh( CGameHandler *gh ) bool BuildBoat::applyGh( CGameHandler *gh )