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)
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());
}
@ -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;
for(; i<gs->players[player].availableHeroes.size(); i++)
{
if(gs->players[player].availableHeroes[i] == hero)
{
HireHero pack(i,town->id);
HireHero pack(i,townOrTavern->id);
pack.player = player;
sendRequest(&pack);
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::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 ps->status;
}
std::string CCallback::getTavernGossip(const CGObjectInstance * townOrTavern) const
{
return "GOSSIP TEST";
}
InfoAboutTown::InfoAboutTown()
{
tType = NULL;

View File

@ -78,7 +78,7 @@ public:
virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses given hero; true - successfuly, false - not successfuly
//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 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
@ -143,7 +143,8 @@ public:
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 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 std::set<int> getBuildingRequiments(const CGTownInstance *t, int ID) =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 setFormation(const CGHeroInstance * hero, bool tight);
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 sendMessage(const std::string &mess);
void buildBoat(const IShipyard *obj);
@ -267,7 +268,8 @@ public:
std::vector < const CGObjectInstance * > getVisitableObjs(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
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;
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);

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 showPuzzleMap(){};
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 tileHidden(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()
{
std::vector<const CGHeroInstance*> h = LOCPLINT->cb->getAvailableHeroes(town);
CTavernWindow *tv = new CTavernWindow(h[0],h[1],"GOSSIP TEST");
GH.pushInt(tv);
LOCPLINT->showTavernWindow(town);
}
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()))
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 showPuzzleMap();
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 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

View File

@ -3403,38 +3403,36 @@ void CSystemOptionsWindow::show(SDL_Surface *to)
effectsVolume->show(to);
}
CTavernWindow::CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2, const std::string &gossip)
:h1(selected,0,72,299,H1),h2(selected,1,162,299,H2)
CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj)
: 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;
else
selected = -1;
oldSelected = -1;
SDL_Surface *hhlp = BitmapHandler::loadBitmap("TPTAVERN.bmp");
graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID);
bg = SDL_ConvertSurface(hhlp,screen->format,0);
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
SDL_FreeSurface(hhlp);
bg = new CPicture("TPTAVERN.bmp");
bg->colorizeAndConvert(LOCPLINT->playerID);
pos = center(bg->pos);
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???
printAtMiddleWB(gossip,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;
printAtMiddleWB(LOCPLINT->cb->getTavernGossip(tavernObj), 200, 220, FONT_SMALL, 50, zwykly, *bg);
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);
thiefGuild = new AdventureMapButton(CGI->generaltexth->tavernInfo[5],"", boost::bind(&CTavernWindow::thievesguildb, this), pos.x+22, pos.y+428, "TPTAV02.DEF", SDLK_t);
bar = new CGStatusBar(8, 478, "APHLFTRT.bmp", 380);
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
{
@ -3454,7 +3452,7 @@ CTavernWindow::CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2,
}
else
{
if(!H1)
if(!h[0])
recruit->block(1);
}
@ -3467,47 +3465,20 @@ CTavernWindow::CTavernWindow(const CGHeroInstance *H1, const CGHeroInstance *H2,
void CTavernWindow::recruitb()
{
const CGHeroInstance *toBuy = (selected ? h2 : h1).h;
const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
const CGObjectInstance *obj = tavernObj;
close();
LOCPLINT->cb->recruitHero(LOCPLINT->castleInt->town,toBuy);
LOCPLINT->cb->recruitHero(obj, toBuy);
}
void CTavernWindow::thievesguildb()
{
GH.pushInt( new CThievesGuildWindow(LOCPLINT->castleInt->town) );
GH.pushInt( new CThievesGuildWindow(tavernObj) );
}
CTavernWindow::~CTavernWindow()
{
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()
@ -3517,20 +3488,12 @@ void CTavernWindow::close()
void CTavernWindow::show(SDL_Surface * to)
{
blitAt(bg,pos.x,pos.y,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);
CIntObject::show(to);
CGI->videoh->update(pos.x+70, pos.y+56, to, true, false);
if(selected >= 0)
{
HeroPortrait *sel = selected ? &h2 : &h1;
HeroPortrait *sel = selected ? h2 : h1;
if (selected != oldSelected && !recruit->blocked)
{
@ -3549,28 +3512,14 @@ void CTavernWindow::show(SDL_Surface * to)
void CTavernWindow::HeroPortrait::clickLeft(tribool down, bool previousState)
{
if(previousState && !down)
if(previousState && !down && h)
as();
//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)
{
if(down)
if(down && h)
{
adventureInt->heroWindow->setHero(h);
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)
:as(sel,id)
:as(sel,id), h(H)
{
used = LCLICK | RCLICK | HOVER;
h = H;
pos.x = x;
pos.y = y;
pos.w = 58;
pos.h = 64;
if(H)
{
hoverName = CGI->generaltexth->tavernInfo[4];
@ -5370,7 +5321,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner)
SDL_FreeSurface(bg);
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->pos.x += pos.x - 3;
@ -5709,16 +5660,22 @@ CGStatusBar::CGStatusBar(CPicture *BG, EFonts Font /*= FONT_SMALL*/, EAlignment
bg = BG;
moveChild(bg, bg->parent, this);
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:
textOffset = Point(pos.w/2, pos.h/2);
break;
case BOTTOMRIGHT:
textOffset = Point(pos.w, pos.h);
break;
amin(pos.w, maxw);
bg->srcRect = new Rect(0, 0, maxw, pos.h);
}
calcOffset();
}
CGStatusBar::~CGStatusBar()
@ -5737,6 +5694,19 @@ void CGStatusBar::init()
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 )
: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(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();
void calcOffset();
};
class CFocusable
@ -657,31 +659,30 @@ public:
std::string hoverName;
vstd::assigner<int,int> as;
const CGHeroInstance *h;
void activate();
void deactivate();
char descr[100]; // "XXX is a level Y ZZZ with N artifacts"
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
void hover (bool on);
HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H);
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
CStatusBar *bar; //tavern's internal status bar
} *h1, *h2; //recruitable heroes
CPicture *bg; //background
CGStatusBar *bar; //tavern's internal status bar
int selected;//0 (left) or 1 (right)
int oldSelected;//0 (left) or 1 (right)
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
void recruitb();
void close();
void thievesguildb();
void activate();
void deactivate();
void show(SDL_Surface * to);
};
@ -1049,7 +1050,7 @@ class CThievesGuildWindow : public CIntObject
{
const CGObjectInstance * owner;
CStatusBar * statusBar;
CGStatusBar * statusBar;
AdventureMapButton * exitb;
SDL_Surface * background;
CMinorResDataBar * resdatabar;

View File

@ -343,10 +343,12 @@ void HeroRecruited::applyCl( CClient *cl )
CGI->mh->initHeroDef(h);
CGI->mh->printObject(h);
if(vstd::contains(cl->playerint,h->tempOwner))
{
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);
}
case TAVERN_WINDOW:
const CGObjectInstance *obj1 = cl->getObj(id1),
*obj2 = cl->getObj(id2);
INTERFACE_CALL_IF_PRESENT(obj1->tempOwner, showTavernWindow, obj2);
break;
}

View File

@ -383,6 +383,12 @@ bool CGObjectInstance::operator<(const CGObjectInstance & cmp) const //screen p
void CGObjectInstance::initObj()
{
switch(ID)
{
case 95:
blockVisit = true;
break;
}
}
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
{
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

View File

@ -893,7 +893,12 @@ CGTownInstance *CGameState::getTown(int objid)
{
if(objid<0 || objid>=map->objects.size())
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

View File

@ -8,6 +8,7 @@
#include "../hch/CSpellHandler.h"
#include "../lib/VCMI_Lib.h"
#include <boost/random/linear_congruential.hpp>
#include "../hch/CTownHandler.h"
/*
* IGameCallback.cpp, part of VCMI engine
@ -233,3 +234,8 @@ const PlayerState * IGameCallback::getPlayerState( int color )
{
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;
struct TerrainTile;
struct PlayerState;
class CTown;
class DLL_EXPORT IGameCallback
{
@ -67,6 +68,7 @@ public:
virtual int3 getMapSize(); //returns size of the map
virtual TerrainTile * getTile(int3 pos);
virtual const PlayerState * getPlayerState(int color);
virtual const CTown *getNativeTown(int color);
//do sth
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;};
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;
ui32 id1, id2;
@ -1434,12 +1435,13 @@ struct HireHero : public CPackForServer
{
HireHero(){};
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);
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);
h->initObj();
gs->map->addBlockVisTiles(h);
t->visitingHero = h;
h->visitedTown = t;
if(t)
{
t->visitingHero = h;
h->visitedTown = t;
}
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
{
const CTown *nativeTownType = &VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle];
SetAvailableHeroes sah;
sah.player = i->first;
@ -961,7 +959,7 @@ void CGameHandler::newTurn()
CHeroClass *banned = NULL;
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;
h->initArmy(sah.army[j] = new CCreatureSet());
@ -3279,35 +3277,47 @@ bool CGameHandler::setFormation( si32 hid, ui8 formation )
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(t->tempOwner);
const PlayerState *p = gs->getPlayer(player);
const CGTownInstance *t = gs->getTown(obj->id);
if(!vstd::contains(t->builtBuildings,5) && complain("No tavern!")
|| p->resources[6]<2500 && complain("Not enough gold for buying hero!")
|| t->visitingHero && complain("There is visiting hero - no place!")
|| getHeroCount(t->tempOwner,false) >= 8 && complain("Cannot hire hero, only 8 wandering heroes are allowed!")
)
//common prconditions
if( p->resources[6]<2500 && complain("Not enough gold for buying hero!")
|| getHeroCount(player, false) >= 8 && complain("Cannot hire hero, only 8 wandering heroes are allowed!"))
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];
assert(nh);
HeroRecruited hr;
hr.tid = tid;
hr.tid = obj->id;
hr.hid = nh->subID;
hr.player = t->tempOwner;
hr.tile = t->pos - int3(1,0,0);
hr.player = player;
hr.tile = obj->visitablePos() + nh->getVisitableOffset();
sendAndApply(&hr);
std::map<ui32,CGHeroInstance *> pool = gs->unusedHeroesFromPool();
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;
sah.player = t->tempOwner;
sah.player = player;
if(newHero)
{
@ -3322,13 +3332,16 @@ bool CGameHandler::hireHero( ui32 tid, ui8 hid )
sendAndApply(&sah);
SetResource sr;
sr.player = t->tempOwner;
sr.player = player;
sr.resid = 6;
sr.val = p->resources[6] - 2500;
sendAndApply(&sr);
vistiCastleObjects (t, nh);
giveSpells (t,nh);
if(t)
{
vistiCastleObjects (t, nh);
giveSpells (t,nh);
}
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);
bool makeCustomAction(BattleAction &ba);
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 setFormation( si32 hid, ui8 formation );
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 )
{
ERROR_IF_NOT_OWNS(tid);
return gh->hireHero(tid,hid);
const CGObjectInstance *obj = gh->getObj(tid);
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 )