From 6613955463a27ffec7c4a2c9ddaa26f461cf83f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Mon, 25 Aug 2008 10:25:16 +0000 Subject: [PATCH] * hero placed in the town starts as visiting hero, not garrisoned * if hero doesn't have a spell book, he can buy one in a mage guild * improvements in closing * fixed crash on picking artifact * added event message when picking artifact * fixed problems with disappearing pikemen * InfoWindow will be properly centered * hero portraits again visible in PreGame * fixed problems with handling Pandora's Box * support for Campfires * minor changes --- AdventureMapButton.cpp | 8 ++-- AdventureMapButton.h | 2 +- CAdvmapInterface.cpp | 2 +- CAdvmapInterface.h | 4 +- CBattleInterface.h | 2 +- CCallback.cpp | 6 +++ CCallback.h | 2 + CCastleInterface.cpp | 57 +++++++++++++++++++++------- CCastleInterface.h | 7 ++-- CGameInterface.h | 1 + CGameState.cpp | 38 ++++++++++++------- CHeroWindow.cpp | 3 +- CLua.cpp | 21 ++++++++++ CMT.cpp | 3 +- CMessage.cpp | 2 +- CPlayerInterface.cpp | 69 ++++++++++++++++----------------- CPlayerInterface.h | 8 +++- CPreGame.cpp | 6 +-- ChangeLog | 5 ++- client/Client.cpp | 12 +++++- client/Client.h | 1 + client/FunctionList.h | 15 +++++--- client/Graphics.cpp | 2 +- global.h | 11 ++++++ hch/CArtHandler.h | 2 - hch/CGeneralTextHandler.cpp | 13 ++++--- hch/CGeneralTextHandler.h | 2 + hch/CObjectHandler.cpp | 2 +- lib/Connection.cpp | 13 +++++-- lib/Connection.h | 1 + map.cpp | 2 - server/CGameHandler.cpp | 76 ++++++++++++++++++++----------------- server/CScriptCallback.cpp | 32 ++++++---------- server/VCMI_server.vcproj | 6 --- 34 files changed, 271 insertions(+), 165 deletions(-) diff --git a/AdventureMapButton.cpp b/AdventureMapButton.cpp index 558137356..6425c58f4 100644 --- a/AdventureMapButton.cpp +++ b/AdventureMapButton.cpp @@ -16,10 +16,10 @@ AdventureMapButton::AdventureMapButton () state=0; actOnDown = false; } -AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, boost::function Callback, int x, int y, std::string defName, bool activ, std::vector * add, bool playerColoredButton) -{ - init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ); -} +//AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, boost::function Callback, int x, int y, std::string defName, bool activ, std::vector * add, bool playerColoredButton) +//{ +// init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ); +//} AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, CFunctionList Callback, int x, int y, std::string defName, bool activ, std::vector * add, bool playerColoredButton ) { init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ); diff --git a/AdventureMapButton.h b/AdventureMapButton.h index 47b94505f..32aeb895d 100644 --- a/AdventureMapButton.h +++ b/AdventureMapButton.h @@ -22,7 +22,7 @@ public: AdventureMapButton(); //c-tor AdventureMapButton( std::string Name, std::string HelpBox, CFunctionList Callback, int x, int y, std::string defName, bool activ=false, std::vector * add = NULL, bool playerColoredButton = false );//c-tor - AdventureMapButton( std::string Name, std::string HelpBox, boost::function Callback, int x, int y, std::string defName, bool activ=false, std::vector * add = NULL, bool playerColoredButton = false );//c-tor + //AdventureMapButton( std::string Name, std::string HelpBox, boost::function Callback, int x, int y, std::string defName, bool activ=false, std::vector * add = NULL, bool playerColoredButton = false );//c-tor void init( CFunctionList Callback, std::string Name, std::string HelpBox, bool playerColoredButton, std::string defName, std::vector * add, int x, int y, bool activ ); }; diff --git a/CAdvmapInterface.cpp b/CAdvmapInterface.cpp index bb234e0a0..fab22d271 100644 --- a/CAdvmapInterface.cpp +++ b/CAdvmapInterface.cpp @@ -980,7 +980,7 @@ void CAdvMapInt::deactivate() { hide(); } -void CAdvMapInt::show() +void CAdvMapInt::show(SDL_Surface *to) { blitAt(bg,0,0); diff --git a/CAdvmapInterface.h b/CAdvmapInterface.h index 11d13bbe8..e33dd0948 100644 --- a/CAdvmapInterface.h +++ b/CAdvmapInterface.h @@ -98,7 +98,7 @@ public: CDefHandler * getAnim(int mode); }; /*****************************/ -class CAdvMapInt : public IActivable //adventure map interface +class CAdvMapInt : public CMainInterface //adventure map interface { public: CAdvMapInt(int Player); @@ -166,7 +166,7 @@ public: void activate(); void deactivate(); - void show(); //shows and activates adv. map interface + void show(SDL_Surface * to=NULL); //shows and activates adv. map interface void hide(); //deactivates advmap interface void update(); //redraws terrain diff --git a/CBattleInterface.h b/CBattleInterface.h index 3501538d4..c52ffd53e 100644 --- a/CBattleInterface.h +++ b/CBattleInterface.h @@ -69,7 +69,7 @@ public: void scrollDown(unsigned int by = 1); //scrolls console up by 'by' positions }; -class CBattleInterface : public IActivable, public IShowable +class CBattleInterface : public CMainInterface { private: SDL_Surface * background, * menu, * amountBasic, * amountNormal; diff --git a/CCallback.cpp b/CCallback.cpp index a874bce18..1cadc72a9 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -512,4 +512,10 @@ void CCallback::swapGarrisonHero( const CGTownInstance *town ) { if(town->tempOwner != player) return; *cl->serv << ui16(508) << si32(town->id); +} + +void CCallback::buyArtifact(const CGHeroInstance *hero, int aid) +{ + if(hero->tempOwner != player) return; + *cl->serv << ui16(510) << hero->id << ui32(aid); } \ No newline at end of file diff --git a/CCallback.h b/CCallback.h index b88655290..5c7df4e7e 100644 --- a/CCallback.h +++ b/CCallback.h @@ -40,6 +40,7 @@ public: 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; + virtual void buyArtifact(const CGHeroInstance *hero, int aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith) //get info virtual bool verifyPath(CPath * path, bool blockSea)=0; @@ -113,6 +114,7 @@ public: bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1); void endTurn(); void swapGarrisonHero(const CGTownInstance *town); + void buyArtifact(const CGHeroInstance *hero, int aid); //get info bool verifyPath(CPath * path, bool blockSea); diff --git a/CCastleInterface.cpp b/CCastleInterface.cpp index 63f70427f..50802af17 100644 --- a/CCastleInterface.cpp +++ b/CCastleInterface.cpp @@ -233,27 +233,33 @@ void CHeroGSlot::clickRight (boost::logic::tribool down) } void CHeroGSlot::clickLeft(boost::logic::tribool down) { + CHeroGSlot *other = upg ? &owner->hslotup : &owner->hslotdown; 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) + else if(other->hero && other->highlight) { other->highlight = highlight = false; LOCPLINT->cb->swapGarrisonHero(owner->town); } + else if(hero) + { + highlight = true; + owner->garr->highlighted = NULL; + owner->showAll(); + } hover(false);hover(true); //refresh statusbar } + if(indeterminate(down) && !isItIn(&other->pos,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y)) + { + other->highlight = highlight = false; + show(); + } } void CHeroGSlot::activate() { @@ -374,7 +380,6 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate) { LOCPLINT->objsToBlit.push_back(this); activate(); - showAll(); } std::string defname; @@ -473,8 +478,28 @@ void CCastleInterface::buildingClicked(int building) { case 0: case 1: case 2: case 3: case 4: { - deactivate(); - (new CMageGuildScreen(this))->activate(); + if(town->visitingHero && !vstd::contains(town->visitingHero->artifWorn,ui16(17))) //visiting hero doesn't have spellboks + { + if(LOCPLINT->cb->getResourceAmount(6) < 500) //not enough gold to buy spellbook + { + LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[213],std::vector()); + } + else + { + CFunctionList fl = boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,town->visitingHero,0); + fl += boost::bind(&CCastleInterface::enterMageGuild,this); + std::vector vvv(1,new SComponent(SComponent::artifact,0,0)); + LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[214],vvv, + fl,boost::bind(&CCastleInterface::activate,this), + true,true); + } + } + else + { + deactivate(); + enterMageGuild(); + + } break; } case 7: case 8: case 9: @@ -629,6 +654,8 @@ void CCastleInterface::activate() subInt->activate(); return; } + else + subInt = NULL; showing = true; townlist->activate(); garr->activate(); @@ -640,6 +667,7 @@ void CCastleInterface::activate() buildings[i]->activate(); hslotdown.activate(); hslotup.activate(); + showAll(0,true); } void CCastleInterface::deactivate() { @@ -807,6 +835,11 @@ CRecrutationWindow * CCastleInterface::showRecruitmentWindow( int building ) rw->activate(); return rw; } + +void CCastleInterface::enterMageGuild() +{ + (new CMageGuildScreen(this))->activate(); +} void CHallInterface::CBuildingBox::hover(bool on) { Hoverable::hover(on); @@ -995,7 +1028,6 @@ void CHallInterface::close() deactivate(); delete this; LOCPLINT->castleInt->activate(); - LOCPLINT->castleInt->showAll(); } void CHallInterface::show(SDL_Surface * to) { @@ -1055,7 +1087,6 @@ void CHallInterface::CBuildWindow::Buy() LOCPLINT->cb->buildBuilding(LOCPLINT->castleInt->town,bid); delete this; delete LOCPLINT->castleInt->subInt; - LOCPLINT->castleInt->showAll(); } void CHallInterface::CBuildWindow::close() { @@ -1252,7 +1283,6 @@ void CFortScreen::close() deactivate(); delete this; LOCPLINT->castleInt->activate(); - LOCPLINT->castleInt->showAll(); } CFortScreen::CFortScreen( CCastleInterface * owner ) { @@ -1406,7 +1436,6 @@ void CMageGuildScreen::close() delete this; LOCPLINT->castleInt->subInt = NULL; LOCPLINT->castleInt->activate(); - LOCPLINT->castleInt->showAll(); } void CMageGuildScreen::show(SDL_Surface * to) { diff --git a/CCastleInterface.h b/CCastleInterface.h index 874617bfc..62f8078e5 100644 --- a/CCastleInterface.h +++ b/CCastleInterface.h @@ -47,7 +47,7 @@ public: ~CHeroGSlot(); }; -class CCastleInterface : public IShowable, public IActivable +class CCastleInterface : public CMainInterface { public: bool showing; @@ -56,7 +56,6 @@ public: SDL_Surface * cityBg; const CGTownInstance * town; CStatusBar * statusbar; - IShowActivable * subInt; unsigned char animval, count; CDefHandler *hall,*fort, *flag; @@ -76,7 +75,7 @@ public: void show(SDL_Surface * to=NULL); void showAll(SDL_Surface * to=NULL, bool forceTotalRedraw = false); void buildingClicked(int building); - + void enterMageGuild(); CRecrutationWindow * showRecruitmentWindow(int building); void enterHall(); void close(); @@ -145,7 +144,7 @@ public: void deactivate(); }; -class CFortScreen : public IShowActivable +class CFortScreen : public CMainInterface { class RecArea : public ClickableL { diff --git a/CGameInterface.h b/CGameInterface.h index e77166e38..b44462e16 100644 --- a/CGameInterface.h +++ b/CGameInterface.h @@ -46,6 +46,7 @@ public: virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished virtual void garrisonChanged(const CGObjectInstance * obj){}; + virtual void heroArtifactSetChanged(const CGHeroInstance*hero){}; virtual void heroCreated(const CGHeroInstance*){}; virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &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){}; diff --git a/CGameState.cpp b/CGameState.cpp index 3ec74f004..9ffac4454 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -417,7 +417,18 @@ void CGameState::applyNL(IPack * pack) { SetGarrisons * n = static_cast(pack); for(std::map::iterator i = n->garrs.begin(); i!=n->garrs.end(); i++) - static_cast(map->objects[i->first])->army = i->second; + { + CArmedInstance *ai = static_cast(map->objects[i->first]); + ai->army = i->second; + if(ai->ID==98 && (static_cast(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army + const_cast((static_cast(ai))->garrisonHero)->army = i->second; + else if(ai->ID==34) + { + CGHeroInstance *h = static_cast(ai); + if(h->visitedTown && h->inTownGarrison) + h->visitedTown->army = i->second; + } + } break; } case 503: @@ -1101,24 +1112,25 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) for(int m=0; msecond.towns.size();m++) { int3 vistile = k->second.towns[m]->pos; vistile.x--; //tile next to the entrance - if(vistile == k->second.heroes[l]->pos) + if(vistile == k->second.heroes[l]->pos || k->second.heroes[l]->pos==k->second.towns[m]->pos) { k->second.towns[m]->visitingHero = k->second.heroes[l]; k->second.heroes[l]->visitedTown = k->second.towns[m]; k->second.heroes[l]->inTownGarrison = false; - goto mainplheloop; - } - else if(k->second.heroes[l]->pos == k->second.towns[m]->pos) - { - k->second.towns[m]->garrisonHero = k->second.heroes[l]; - k->second.towns[m]->army = k->second.heroes[l]->army; - k->second.heroes[l]->visitedTown = k->second.towns[m]; - k->second.heroes[l]->inTownGarrison = true; - k->second.heroes[l]->pos.x -= 1; - goto mainplheloop; + if(k->second.heroes[l]->pos==k->second.towns[m]->pos) + k->second.heroes[l]->pos.x -= 1; + break; } + //else if(k->second.heroes[l]->pos == k->second.towns[m]->pos) + //{ + // k->second.towns[m]->garrisonHero = k->second.heroes[l]; + // k->second.towns[m]->army = k->second.heroes[l]->army; + // k->second.heroes[l]->visitedTown = k->second.towns[m]; + // k->second.heroes[l]->inTownGarrison = true; + // k->second.heroes[l]->pos.x -= 1; + // goto mainplheloop; + //} } -mainplheloop:; } } } diff --git a/CHeroWindow.cpp b/CHeroWindow.cpp index d8b16942a..88534c026 100644 --- a/CHeroWindow.cpp +++ b/CHeroWindow.cpp @@ -508,6 +508,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero) void CHeroWindow::quit() { + LOCPLINT->curint->subInt = NULL; LOCPLINT->objsToBlit -= this; deactivate(); @@ -535,7 +536,7 @@ void CHeroWindow::quit() void CHeroWindow::activate() { - //LOCPLINT->curint = this; + LOCPLINT->curint->subInt = this; quitButton->activate(); dismissButton->activate(); questlogButton->activate(); diff --git a/CLua.cpp b/CLua.cpp index c948700b0..b0c219b81 100644 --- a/CLua.cpp +++ b/CLua.cpp @@ -588,6 +588,26 @@ void CPickable::onHeroVisit(int objid, int heroID) case 5: //artifact { cb->giveHeroArtifact(os->subID,heroID,-1); //TODO: na pozycje + InfoWindow iw; + iw.player = cb->getHeroOwner(heroID); + iw.components.push_back(Component(4,os->subID,0,0)); + iw.text << std::pair(12,os->subID); + cb->showInfoDialog(&iw); + break; + } + case 12: //campfire + { + int val = (rand()%3) + 4, //4 - 6 + res = rand()%6, + owner = cb->getHeroOwner(heroID); + cb->giveResource(owner,res,val); //non-gold resource + cb->giveResource(owner,6,val*100);//gold + InfoWindow iw; + iw.player = owner; + iw.components.push_back(Component(2,6,val*100,0)); + iw.components.push_back(Component(2,res,val,0)); + iw.text << std::pair(11,23); + cb->showInfoDialog(&iw); break; } case 79: //resource @@ -691,6 +711,7 @@ std::vector CPickable::yourObjects() //returns IDs of objects which are han std::vector ret; ret.push_back(79); //resource ret.push_back(5); //artifact + ret.push_back(12); //resource ret.push_back(101); //treasure chest / commander stone return ret; } diff --git a/CMT.cpp b/CMT.cpp index f3dd262a9..bbd814918 100644 --- a/CMT.cpp +++ b/CMT.cpp @@ -171,7 +171,8 @@ int main(int argc, _TCHAR* argv[]) SDL_WaitEvent(&ev); if(ev.type==SDL_QUIT) { - t.interrupt(); + cl.close(); + SDL_Delay(750); exit(0); } eventsM.lock(); diff --git a/CMessage.cpp b/CMessage.cpp index 6274c691f..3cf42c976 100644 --- a/CMessage.cpp +++ b/CMessage.cpp @@ -426,7 +426,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int ret->bitmap = drawBox1(txts.first+70,txts.second+70,0); ret->pos.h=ret->bitmap->h; ret->pos.w=ret->bitmap->w; - ret->pos.x=300-(ret->pos.w/2); + ret->pos.x=400-(ret->pos.w/2); ret->pos.y=300-(ret->pos.h/2); int curh = 30; //gorny margines blitTextOnSur(txtg,curh,ret->bitmap); diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index 2b7e71ad6..a5e4c3bdd 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -12,6 +12,7 @@ #include "hch/CLodHandler.h" #include "CPathfinder.h" #include +#include "hch/CArtHandler.h" #include "hch/CAbilityHandler.h" #include "hch/CHeroHandler.h" #include "hch/CTownHandler.h" @@ -172,14 +173,10 @@ void CGarrisonSlot::clickLeft(tribool down) (creature->idNumber,1,count,NULL,0, boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID),NULL) ) ->activate(); } - if(LOCPLINT->curint == LOCPLINT->castleInt && dynamic_cast(LOCPLINT->castleInt->subInt)) - { - LOCPLINT->castleInt->subInt->deactivate(); - } + if(LOCPLINT->curint->subInt) + LOCPLINT->curint->subInt->deactivate(); else - { LOCPLINT->curint->deactivate(); - } owner->highlighted = NULL; show(); refr = true; @@ -263,8 +260,8 @@ void CGarrisonSlot::show() printTo(buf,pos.x+56,pos.y+62,GEOR16,zwykly); if(owner->highlighted==this) blitAt(graphics->bigImgs[-1],pos); - if(owner->update) - updateRect(&pos,screen); + //if(owner->update) + // updateRect(&pos,screen); delete [] buf; } else @@ -273,8 +270,8 @@ void CGarrisonSlot::show() SDL_BlitSurface(owner->sur,&jakis1,screen,&jakis2); if(owner->splitting) blitAt(graphics->bigImgs[-1],pos); - if(owner->update) - SDL_UpdateRect(screen,pos.x,pos.y,pos.w,pos.h); + //if(owner->update) + // SDL_UpdateRect(screen,pos.x,pos.y,pos.w,pos.h); } } CGarrisonInt::~CGarrisonInt() @@ -588,6 +585,10 @@ void SComponent::init(Etype Type, int Subtype, int Val) std::ostringstream oss; switch (Type) { + case artifact: + description = CGI->arth->artifacts[Subtype].description; + subtitle = CGI->arth->artifacts[Subtype].name; + break; case primskill: description = CGI->generaltexth->arraytxt[2+Subtype]; oss << ((Val>0)?("+"):("-")) << Val << " " << CGI->heroh->pskillsn[Subtype]; @@ -645,6 +646,9 @@ SDL_Surface * SComponent::getImg() { switch (type) { + case artifact: + return graphics->artDefs->ourImages[subtype].bitmap; + break; case primskill: return graphics->pskillsb->ourImages[subtype].bitmap; break; @@ -1942,6 +1946,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int void CPlayerInterface::receivedResource(int type, int val) { + boost::unique_lock un(*pim); adventureInt->resdatabar.draw(); } @@ -2017,13 +2022,13 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj) SDL_FreeSurface(graphics->heroWins[hh->subID]); graphics->heroWins[hh->subID] = infoWin(hh); } - CHeroWindow * hw = dynamic_cast(curint); + CHeroWindow * hw = dynamic_cast(curint->subInt); if(hw) { hw->garInt->recreateSlots(); hw->garInt->show(); } - else if(castleInt) //opened town window - redraw town garrsion slots (change is within hero garr) + if(castleInt) //opened town window - redraw town garrsion slots (change is within hero garr) { castleInt->garr->highlighted = NULL; castleInt->garr->recreateSlots(); @@ -2128,9 +2133,9 @@ BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn void CPlayerInterface::battleEnd(BattleResult *br) { boost::unique_lock un(*pim); - dynamic_cast(curint)->deactivate(); - LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),dynamic_cast(curint))); - delete dynamic_cast(curint); + curint->deactivate(); + objsToBlit -= curint; + delete curint; curint = adventureInt; adventureInt->activate(); } @@ -2257,6 +2262,16 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero) adventureInt->heroWindow->quitButton->callback += boost::bind(&CHeroWindow::quit,adventureInt->heroWindow); adventureInt->heroWindow->activate(); } + +void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero) +{ + boost::unique_lock un(*pim); + if(curint->subInt == adventureInt->heroWindow) + { + //TODO: update hero window properly + + } +} CStatusBar::CStatusBar(int x, int y, std::string name, int maxw) { bg=BitmapHandler::loadBitmap(name); @@ -2827,9 +2842,6 @@ void CRecrutationWindow::close() deactivate(); delete this; LOCPLINT->curint->activate(); - CCastleInterface *pom; - if(pom=dynamic_cast(LOCPLINT->curint)) - pom->showAll(); } void CRecrutationWindow::Max() { @@ -3055,9 +3067,6 @@ void CSplitWindow::close() deactivate(); delete this; LOCPLINT->curint->activate(); - - CCastleInterface *c = dynamic_cast(LOCPLINT->curint); - if(c) c->showAll(); } void CSplitWindow::sliderMoved(int to) { @@ -3210,12 +3219,6 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState CFunctionList fs[2]; fs[0] += Upg; fs[0] += boost::bind(&CCreInfoWindow::close,this); - - CCastleInterface *pom; - if(pom=dynamic_cast(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 cfl; cfl = boost::bind(&CCreInfoWindow::deactivate,this); @@ -3236,12 +3239,6 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState //on dismiss confirmed fs[0] += Dsm; //dismiss fs[0] += boost::bind(&CCreInfoWindow::close,this);//close this window - - CCastleInterface *pom; - if(pom=dynamic_cast(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 cfl; cfl = boost::bind(&CCreInfoWindow::deactivate,this); @@ -3282,14 +3279,14 @@ void CCreInfoWindow::activate() void CCreInfoWindow::close() { deactivate(); - CCastleInterface *c = dynamic_cast(LOCPLINT->curint); - if(c && dynamic_cast(c->subInt)) + if(dynamic_cast(LOCPLINT->curint->subInt)) { if(type) - c->subInt->activate(); + LOCPLINT->curint->subInt->activate(); } else { + CCastleInterface *c = dynamic_cast(LOCPLINT->curint); if(c) c->showAll(); if(type) diff --git a/CPlayerInterface.h b/CPlayerInterface.h index 6221bd3dd..b992e0263 100644 --- a/CPlayerInterface.h +++ b/CPlayerInterface.h @@ -60,6 +60,11 @@ class IShowActivable : public IShowable, public IActivable public: virtual ~IShowActivable(){}; }; +class CMainInterface : public IShowActivable +{ +public: + IShowActivable *subInt; +}; class CIntObject //interface object { public: @@ -315,7 +320,7 @@ public: boost::mutex *pim; bool makingTurn; SDL_Event * current; - IActivable *curint; + CMainInterface *curint; CAdvMapInt * adventureInt; CCastleInterface * castleInt; FPSmanager * mainFPSmng; @@ -335,6 +340,7 @@ public: //overloaded funcs from CGameInterface void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished void garrisonChanged(const CGObjectInstance * obj); + void heroArtifactSetChanged(const CGHeroInstance*hero); void heroCreated(const CGHeroInstance* hero); void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback); void heroInGarrisonChange(const CGTownInstance *town); diff --git a/CPreGame.cpp b/CPreGame.cpp index 312ca4b0c..468ff495d 100644 --- a/CPreGame.cpp +++ b/CPreGame.cpp @@ -615,8 +615,7 @@ void Options::showIcon (int what, int nr, bool abs) //what: -1=castle, 0=hero, 1 { if(ourOpt->heroPortrait>=0) { - //TODO: restore drawing hero portrait - //blitAtWR(CGI->heroh->heroes[ourOpt->heroPortrait]->portraitSmall,252,130+50*se); + blitAtWR(graphics->portraitSmall[ourOpt->heroPortrait],252,130+50*se); } else { @@ -625,8 +624,7 @@ void Options::showIcon (int what, int nr, bool abs) //what: -1=castle, 0=hero, 1 } else { - //TODO: restore drawing hero portrait - //blitAtWR(CGI->heroh->heroes[pom]->portraitSmall,252,130+50*se); + blitAtWR(graphics->portraitSmall[pom],252,130+50*se); } break; } diff --git a/ChangeLog b/ChangeLog index a6dc49e2c..3e491471a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ 0.61 -> 0.62 General: * restructured to the server-client model -* support for heroes starting in town garrisons +* support for heroes placed in towns * upgrading creatures * working gaining levels for heroes (including dialog with skill selection) * added graphical cursor @@ -16,6 +16,7 @@ Castles: * viewing hero window in the town screen * possibility of moving hero into the garrison * partially done mage guild screen +* if hero doesn't have a spell book, he can buy one in a mage guild Adventure Interface: * hopefully fixed problems with wrong town defs (village/fort/capitol) @@ -44,6 +45,8 @@ PreGame: Objects: * support for the Tree of knowledge +* support for Campfires +* added event message when picking artifact 0.6 -> 0.61 (Jun 15 2008) Improvements: diff --git a/client/Client.cpp b/client/Client.cpp index 5b79eadeb..d3aa18e84 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -77,6 +77,10 @@ std::string toString(MetaString &ms) break; case 11: vec = &CGI->objh->advobtxt; + break; + case 12: + vec = &CGI->generaltexth->artifEvents; + break; } ret += (*vec)[ser]; } @@ -366,7 +370,9 @@ void CClient::process(int what) *serv >> sha; std::cout << "Setting artifacts of hero " << sha.hid << std::endl; gs->apply(&sha); - //TODO: inform interfaces + CGHeroInstance *t = gs->getHero(sha.hid); + if(vstd::contains(playerint,t->tempOwner)) + playerint[t->tempOwner]->heroArtifactSetChanged(t); break; } case 1001: @@ -537,3 +543,7 @@ void CClient::run() } HANDLE_EXCEPTION } +void CClient::close() +{ + serv->close(); +} diff --git a/client/Client.h b/client/Client.h index 5e5faa6fe..c6c597836 100644 --- a/client/Client.h +++ b/client/Client.h @@ -46,6 +46,7 @@ public: CClient(CConnection *con, StartInfo *si); ~CClient(void); + void close(); void process(int what); void run(); diff --git a/client/FunctionList.h b/client/FunctionList.h index 5c42020b2..cc82eac03 100644 --- a/client/FunctionList.h +++ b/client/FunctionList.h @@ -9,6 +9,11 @@ public: CFunctionList(int){}; CFunctionList(){}; + template + CFunctionList(const Functor &f) + { + funcs.push_back(boost::function(f)); + } CFunctionList(const boost::function &first) { funcs.push_back(first); @@ -22,11 +27,11 @@ public: funcs.push_back(first); return *this; } - const boost::function & operator=(const boost::function &first) - { - funcs.push_back(first); - return first; - } + //CFunctionList & operator=(const boost::function &first) + //{ + // funcs.push_back(first); + // return first; + //} operator bool() const { return funcs.size(); diff --git a/client/Graphics.cpp b/client/Graphics.cpp index b54fbab92..3bbd93b03 100644 --- a/client/Graphics.cpp +++ b/client/Graphics.cpp @@ -71,7 +71,7 @@ SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh) printAtMiddle(buf,167,70,GEORM,zwykly,ret); for (std::map >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++) { - if(!i->second.first) + if(!i->second.second) continue; blitAt(graphics->smallImgs[(*i).second.first],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret); SDL_itoa((*i).second.second,buf,10); diff --git a/global.h b/global.h index 2aaa59692..478e65eb2 100644 --- a/global.h +++ b/global.h @@ -92,6 +92,17 @@ const int SPELL_LEVELS = 5; delete e; \ } +#define HANDLE_EXCEPTIONC(COMMAND) \ + catch (const std::exception& e) { \ + COMMAND; \ + std::cerr << e.what() << std::endl; \ + } \ + catch (const std::exception * e) \ + { \ + COMMAND; \ + std::cerr << e->what()<< std::endl; \ + delete e; \ + } namespace vstd { diff --git a/hch/CArtHandler.h b/hch/CArtHandler.h index c1d8352c8..ac4342dca 100644 --- a/hch/CArtHandler.h +++ b/hch/CArtHandler.h @@ -14,7 +14,6 @@ public: std::string name; std::string description; //std::string desc2; - std::string eventText; unsigned int price; bool spellBook, warMachine1, warMachine2, warMachine3, warMachine4, misc1, misc2, misc3, misc4, misc5, feet, lRing, rRing, torso, lHand, rHand, neck, shoulders, head; EartClass aClass; @@ -27,7 +26,6 @@ public: std::vector treasures, minors, majors, relics; std::vector artifacts; void loadArtifacts(); - bool loadArtEvents(); CArtHandler(); }; diff --git a/hch/CGeneralTextHandler.cpp b/hch/CGeneralTextHandler.cpp index 60c888a46..b2ebe1a88 100644 --- a/hch/CGeneralTextHandler.cpp +++ b/hch/CGeneralTextHandler.cpp @@ -6,7 +6,7 @@ void CGeneralTextHandler::load() { - std::string buf = CGI->bitmaph->getTextFile("GENRLTXT.TXT"); + std::string buf = CGI->bitmaph->getTextFile("GENRLTXT.TXT"), tmp; int andame = buf.size(); int i=0; //buf iterator for(i; ibitmaph->getTextFile("PRISKILL.TXT"); for(int hh=0; hh<4; ++hh) { - std::string tmp; loadToIt(tmp, strin, itr, 3); primarySkillNames.push_back(tmp); } @@ -46,7 +44,6 @@ void CGeneralTextHandler::load() std::string strin2 = CGI->bitmaph->getTextFile("JKTEXT.TXT"); for(int hh=0; hh<45; ++hh) { - std::string tmp; loadToIt(tmp, strin2, itr, 3); jktexts.push_back(tmp); } @@ -55,8 +52,14 @@ void CGeneralTextHandler::load() std::string strin3 = CGI->bitmaph->getTextFile("HEROSCRN.TXT"); for(int hh=0; hh<33; ++hh) { - std::string tmp; loadToIt(tmp, strin3, itr, 3); heroscrn.push_back(tmp); } + + strin3 = CGI->bitmaph->getTextFile("ARTEVENT.TXT"); + for(itr = 0; itr primarySkillNames; std::vector jktexts; std::vector heroscrn; + std::vector artifEvents; + void load(); }; diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 7215a5f0b..a1454224c 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -257,7 +257,7 @@ void CGHeroInstance::setArtAtPos(ui16 pos, int art) if(pos<19) artifWorn.erase(pos); else - artifacts -= artifacts[pos]; + artifacts -= artifacts[pos-19]; } else { diff --git a/lib/Connection.cpp b/lib/Connection.cpp index ee5234704..33fc1a5f2 100644 --- a/lib/Connection.cpp +++ b/lib/Connection.cpp @@ -79,14 +79,21 @@ int CConnection::read(void * data, unsigned size) } CConnection::~CConnection(void) { - if(socket) - socket->close(); - delete socket; + close(); delete io_service; delete wmx; delete rmx; } +void CConnection::close() +{ + if(socket) + { + socket->close(); + delete socket; + socket = NULL; + } +} template <> void CConnection::saveSerializable(const std::string &data) { diff --git a/lib/Connection.h b/lib/Connection.h index b08659666..0fc244f96 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -372,6 +372,7 @@ public: int write(const void * data, unsigned size); int read(void * data, unsigned size); int readLine(void * data, unsigned maxSize); + void close(); ~CConnection(void); }; diff --git a/map.cpp b/map.cpp index 7e84a7862..3e8484502 100644 --- a/map.cpp +++ b/map.cpp @@ -2128,8 +2128,6 @@ void Mapa::readObjects( unsigned char * bufor, int &i) } int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures spec->creatures = readCreatureSet(bufor,i,gcre,(version>RoE)); - if(version > RoE) - i+=gcre; i+=8; nobj->info = spec; ///////end of copied fragment diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index a4d1f7b90..68cc5ce1f 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -477,9 +477,9 @@ void CGameHandler::handleConnection(std::set players, CConnection &c) S2->slots[p2].second = S1->slots[p1].second; S1->slots[p1].second = pom2; - if(!S1->slots[p1].first) + if(!S1->slots[p1].second) S1->slots.erase(p1); - if(!S2->slots[p2].first) + if(!S2->slots[p2].second) S2->slots.erase(p2); } else if(what==2)//merge @@ -618,7 +618,6 @@ void CGameHandler::handleConnection(std::set players, CConnection &c) { sg.garrs[objid].slots[slot].second += cram; } - sendAndApply(&sr); sendAndApply(&sac); sendAndApply(&sg); @@ -708,28 +707,30 @@ upgend: } 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); + + //town will be empty + SetGarrisons sg; + sg.garrs[tid] = CCreatureSet(); + sendAndApply(&sg); } else if (town->garrisonHero && town->visitingHero) //swap visiting and garrison hero { SetGarrisons sg; sg.garrs[town->id] = town->visitingHero->army; - sendAndApply(&sg); + sg.garrs[town->garrisonHero->id] = town->garrisonHero->army; + //sg.garrs[town->visitingHero->id] = town->visitingHero->army; SetHeroesInTown intown; intown.tid = tid; intown.garrison = town->visitingHero->id; intown.visiting = town->garrisonHero->id; sendAndApply(&intown); + sendAndApply(&sg); } else { @@ -737,7 +738,7 @@ upgend: } break; } - case 509: + case 509: //swap artifacts { si32 hid1, hid2; ui16 slot1, slot2; @@ -749,28 +750,6 @@ upgend: h2->setArtAtPos(slot2,a1); h1->setArtAtPos(slot1,a2); -// if(std::max(slot1,slot2) < 19) -// { -// if(vstd::contains(h1->artifWorn,slot1) && vstd::contains(h1->artifWorn,slot2)) -// std::swap(h1->artifWorn[slot1],h2->artifWorn[slot2]); -// if(vstd::contains(h1->artifWorn,slot1)) -// { -// h2->artifWorn[slot2] = h1->artifWorn[slot1]; -// h1->artifWorn.erase(slot1); -// } -// else if(vstd::contains(h2->artifWorn,slot2)) -// { -// h1->artifWorn[slot1] = h2->artifWorn[slot2]; -// h2->artifWorn.erase(slot2); -// } -// else -// { -// std::cout << "Warning, wrong artifact swap command!" << std::endl; -// } -// } -// else -// { -// } SetHeroArtifacts sha; sha.hid = hid1; sha.artifacts = h1->artifacts; @@ -783,6 +762,35 @@ upgend: sha.artifWorn = h2->artifWorn; sendAndApply(&sha); } + break; + } + case 510: //buy artifact + { + ui32 hid; + si32 aid, bid; + c >> hid >> aid; + CGHeroInstance *hero = gs->getHero(hid); + CGTownInstance *town = hero->visitedTown; + if(aid==0) + { + if(!vstd::contains(town->builtBuildings,si32(0))) + break; + SetResource sr; + sr.player = hero->tempOwner; + sr.resid = 6; + sr.val = gs->players[hero->tempOwner].resources[6] - 500; + sendAndApply(&sr); + + SetHeroArtifacts sha; + sha.hid = hid; + sha.artifacts = hero->artifacts; + sha.artifWorn = hero->artifWorn; + sha.artifWorn[17] = 0; + sendAndApply(&sha); + } + + //TODO: war machines + break; } case 2001: { @@ -1100,12 +1108,12 @@ void CGameHandler::run() while(states.players[i->first].makingTurn && !end2) { boost::posix_time::time_duration p; - p= boost::posix_time::seconds(1); + p = boost::posix_time::milliseconds(200); #ifdef _MSC_VER states.cv.timed_wait(lock,p); #else boost::xtime time={0,0}; - time.sec = static_cast(p.total_seconds()); + time.nsec = static_cast(p.total_nanoseconds()); states.cv.timed_wait(lock,time); #endif } diff --git a/server/CScriptCallback.cpp b/server/CScriptCallback.cpp index 60952bb11..534ad4229 100644 --- a/server/CScriptCallback.cpp +++ b/server/CScriptCallback.cpp @@ -128,28 +128,20 @@ void CScriptCallback::stopHeroVisitCastle(int obj, int heroID) } void CScriptCallback::giveHeroArtifact(int artid, int hid, int position) //pos==-1 - first free slot in backpack { - CGHeroInstance* h = gh->gs->map->getHero(hid,0); + const CGHeroInstance* h = getHero(hid); + + SetHeroArtifacts sha; + sha.hid = hid; + sha.artifacts = h->artifacts; + sha.artifWorn = h->artifWorn; if(position<0) - { - for(unsigned i=0;iartifacts.size();i++) - { - if(!h->artifacts[i]) - { - h->artifacts[i] = artid; - return; - } - } - h->artifacts.push_back(artid); - return; - } + sha.artifacts.push_back(artid); else - { - if(h->artifWorn[position]) //slot is occupied - { - giveHeroArtifact(h->artifWorn[position],hid,-1); - } - h->artifWorn[position] = artid; - } + if(!vstd::contains(sha.artifWorn,ui16(position))) + sha.artifWorn[position] = artid; + else + sha.artifacts.push_back(artid); + gh->sendAndApply(&sha); } void CScriptCallback::startBattle(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2) //use hero=NULL for no hero diff --git a/server/VCMI_server.vcproj b/server/VCMI_server.vcproj index a113034bd..cbb4e0350 100644 --- a/server/VCMI_server.vcproj +++ b/server/VCMI_server.vcproj @@ -288,12 +288,6 @@ > - -