From 22ade5efbe56ab2cde02ab68ccf7864cc5c1402d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Wed, 20 Aug 2008 06:57:53 +0000 Subject: [PATCH] * make compatible with boost 1.36.0 (there was breaking change in boost::function) * randomizing spells in towns * fixed reading forbidden structures * support for heroes starting in town garrisons * hopefully fixed problems with wrong town defs (village/fort/capitol) * moved CSpellHandler.* to VCMI_Lib (project files must be updated) * redone reading spell info * added missing features to the fort screen * minor improvements * partially done mage guild screen --- CCastleInterface.cpp | 149 +++++++++++++-- CCastleInterface.h | 33 ++++ CGameInterface.cpp | 7 +- CGameInterface.h | 4 +- CGameState.cpp | 54 +++++- CGameState.h | 4 +- CHeroWindow.cpp | 24 +-- CHeroWindow.h | 2 +- CMT.cpp | 5 +- CPlayerInterface.cpp | 83 +++++--- CPlayerInterface.h | 18 +- client/Client.cpp | 15 +- client/FunctionList.h | 12 +- client/Graphics.cpp | 8 + client/Graphics.h | 1 + client/VCMI_client.vcproj | 12 +- config/mageLevel.txt | 9 + global.h | 1 + hch/CArtHandler.cpp | 1 - hch/CObjectHandler.cpp | 15 ++ hch/CObjectHandler.h | 4 +- hch/CSpellHandler.cpp | 377 +++++-------------------------------- hch/CSpellHandler.h | 24 +-- hch/CTownHandler.cpp | 9 + hch/CTownHandler.h | 1 + lib/Connection.h | 1 + lib/VCMI_Lib.cpp | 13 ++ lib/VCMI_Lib.h | 24 +-- lib/VCMI_lib.vcproj | 8 + map.cpp | 2 +- mapHandler.cpp | 9 +- nodrze.h | 2 +- server/CGameHandler.cpp | 3 +- server/CScriptCallback.cpp | 2 +- server/CScriptCallback.h | 2 +- 35 files changed, 453 insertions(+), 485 deletions(-) create mode 100644 config/mageLevel.txt diff --git a/CCastleInterface.cpp b/CCastleInterface.cpp index 9c8282084..c122358b7 100644 --- a/CCastleInterface.cpp +++ b/CCastleInterface.cpp @@ -1,25 +1,26 @@ #include "stdafx.h" -#include "CCastleInterface.h" -#include "hch/CObjectHandler.h" -#include "CGameInfo.h" -#include "hch/CLodHandler.h" -#include "SDL_Extensions.h" -#include "CAdvmapInterface.h" -#include "hch/CTownHandler.h" #include "AdventureMapButton.h" +#include "CAdvmapInterface.h" +#include "CCallback.h" +#include "CCastleInterface.h" +#include "CGameInfo.h" +#include "CHeroWindow.h" +#include "CMessage.h" +#include "SDL_Extensions.h" +#include "client/CCreatureAnimation.h" +#include "client/Graphics.h" #include "hch/CBuildingHandler.h" #include "hch/CDefHandler.h" -#include -#include "CMessage.h" #include "hch/CGeneralTextHandler.h" -#include "CCallback.h" -#include "client/Graphics.h" -#include "client/CCreatureAnimation.h" -#include "CHeroWindow.h" +#include "hch/CLodHandler.h" +#include "hch/CObjectHandler.h" +#include "hch/CSpellHandler.h" +#include "hch/CTownHandler.h" #include #include #include #include +#include using namespace boost::assign; using namespace CSDL_Ext; @@ -469,6 +470,12 @@ void CCastleInterface::buildingClicked(int building) { switch(building) { + case 0: case 1: case 2: case 3: case 4: + { + deactivate(); + (new CMageGuildScreen(this))->activate(); + break; + } case 7: case 8: case 9: { CFortScreen *fs = new CFortScreen(this); @@ -944,10 +951,6 @@ CHallInterface::CHallInterface(CCastleInterface * owner) } //TODO: check if capital is already built, check if there is water for shipyard - - - - break; } } @@ -1205,6 +1208,8 @@ void CFortScreen::show( SDL_Surface * to) } anim++; exit->show(); + resdatabar.show(); + LOCPLINT->statusbar->show(); } void CFortScreen::activate() @@ -1324,12 +1329,13 @@ void CFortScreen::draw( CCastleInterface * owner, bool first) } void CFortScreen::RecArea::clickLeft (tribool down) { - if(!down) + if(!down && pressedL) { LOCPLINT->curint->deactivate(); CRecrutationWindow *rw = LOCPLINT->castleInt->showRecruitmentWindow(bid); rw->buy->callback += boost::bind(&CFortScreen::draw, static_cast(LOCPLINT->curint), LOCPLINT->castleInt, false); } + ClickableL::clickLeft(down); } void CFortScreen::RecArea::activate() { @@ -1339,3 +1345,110 @@ void CFortScreen::RecArea::deactivate() { ClickableL::deactivate(); } + +CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner) +{ + bg = BitmapHandler::loadBitmap("TPMAGE.bmp"); + exit = new AdventureMapButton(CGI->townh->tcommands[8],"",boost::bind(&CMageGuildScreen::close,this),748,556,"TPMAGE1.DEF",false,NULL,false); + scrolls = CDefHandler::giveDefEss("SPELLSCR.DEF"); + scrolls2 = CDefHandler::giveDefEss("TPMAGES.DEF"); + SDL_Surface *view = BitmapHandler::loadBitmap(graphics->guildBgs[owner->town->subID]); + SDL_SetColorKey(view,SDL_SRCCOLORKEY,SDL_MapRGB(view->format,0,255,255)); + positions.resize(5); + positions[0] += genRect(61,83,222,445), genRect(61,83,312,445), genRect(61,83,402,445), genRect(61,83,520,445), genRect(61,83,610,445), genRect(61,83,700,445); + positions[1] += genRect(61,83,48,53), genRect(61,83,48,147), genRect(61,83,48,241), genRect(61,83,48,335), genRect(61,83,48,429); + positions[2] += genRect(61,83,570,82), genRect(61,83,672,82), genRect(61,83,570,157), genRect(61,83,672,157); + positions[3] += genRect(61,83,183,42), genRect(61,83,183,148), genRect(61,83,183,253); + positions[4] += genRect(61,83,491,325), genRect(61,83,591,325); + blitAt(view,332,76,bg); + for(int i=0; itown->town->mageLevel; i++) + { + int sp = 5 - i; //how many spells are available at this level + if(owner->town->subID==2 && vstd::contains(owner->town->builtBuildings,22)) sp++; //magic library in tower + for(int j=0; jtown->mageGuildLevel()) + { + spells.push_back(Scroll(&CGI->spellh->spells[owner->town->spells[i][j]])); + spells[spells.size()-1].pos = positions[i][j]; + blitAt(scrolls->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],bg); + } + else + { + blitAt(scrolls2->ourImages[1].bitmap,positions[i][j],bg); + } + } + } + SDL_FreeSurface(view); + delete scrolls2; +} +CMageGuildScreen::~CMageGuildScreen() +{ + delete exit; + delete scrolls; + SDL_FreeSurface(bg); +} +void CMageGuildScreen::close() +{ + deactivate(); + delete this; + LOCPLINT->castleInt->activate(); + LOCPLINT->castleInt->showAll(); +} +void CMageGuildScreen::show(SDL_Surface * to) +{ + blitAt(bg,0,0); + resdatabar.show(); + exit->show(); +} +void CMageGuildScreen::activate() +{ + LOCPLINT->objsToBlit += this; + LOCPLINT->castleInt->subInt = this; + exit->activate(); + for(int i=0;iobjsToBlit -= this; + exit->deactivate(); + for(int i=0;ifree = true; + vinya->bitmap = CMessage::drawBoxTextBitmapSub + (LOCPLINT->playerID, + spell->descriptions[0], + static_cast(LOCPLINT->castleInt->subInt)->scrolls->ourImages[spell->id].bitmap, + spell->name); + vinya->pos.x = screen->w/2 - vinya->bitmap->w/2; + vinya->pos.y = screen->h/2 - vinya->bitmap->h/2; + vinya->activate(); + } +} +void CMageGuildScreen::Scroll::hover(bool on) +{ + +} +void CMageGuildScreen::Scroll::activate() +{ + ClickableL::activate(); + ClickableR::activate(); + Hoverable::activate(); +} +void CMageGuildScreen::Scroll::deactivate() +{ + ClickableL::deactivate(); + ClickableR::deactivate(); + Hoverable::deactivate(); +} \ No newline at end of file diff --git a/CCastleInterface.h b/CCastleInterface.h index b654c34c4..874617bfc 100644 --- a/CCastleInterface.h +++ b/CCastleInterface.h @@ -7,6 +7,7 @@ class CGTownInstance; class CTownHandler; class CHallInterface; struct Structure; +class CSpell; class AdventureMapButton; class CBuildingRect : public Hoverable, public MotionInterested, public ClickableL, public ClickableR//, public TimeInterested { @@ -171,4 +172,36 @@ public: void show(SDL_Surface * to=NULL); void activate(); void deactivate(); +}; + +class CMageGuildScreen : public IShowActivable +{ +public: + class Scroll : public ClickableL, public Hoverable, public ClickableR + { + public: + CSpell *spell; + + Scroll(CSpell *Spell):spell(Spell){}; + void clickLeft (tribool down); + void clickRight (tribool down); + void hover(bool on); + void activate(); + void deactivate(); + }; + std::vector > positions; + + SDL_Surface *bg; + CDefEssential *scrolls, *scrolls2; + AdventureMapButton *exit; + std::vector spells; + CMinorResDataBar resdatabar; + + + CMageGuildScreen(CCastleInterface * owner); + ~CMageGuildScreen(); + void close(); + void show(SDL_Surface * to=NULL); + void activate(); + void deactivate(); }; \ No newline at end of file diff --git a/CGameInterface.cpp b/CGameInterface.cpp index 0a847d999..bd5d417cb 100644 --- a/CGameInterface.cpp +++ b/CGameInterface.cpp @@ -34,7 +34,10 @@ CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname) if (!dll) { std::cout << "Cannot open AI library ("<init(cb); #else diff --git a/CGameInterface.h b/CGameInterface.h index 6d27ce018..6ba2326fe 100644 --- a/CGameInterface.h +++ b/CGameInterface.h @@ -54,8 +54,8 @@ public: virtual void tileRevealed(int3 pos){}; virtual void tileHidden(int3 pos){}; virtual void receivedResource(int type, int val){}; - virtual void showInfoDialog(std::string &text, std::vector &components){}; - virtual void showSelDialog(std::string &text, std::vector &components, ui32 askID){}; + virtual void showInfoDialog(std::string &text, const std::vector &components){}; + virtual void showSelDialog(std::string &text, const std::vector &components, ui32 askID){}; virtual void garrisonChanged(const CGObjectInstance * obj){}; virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id diff --git a/CGameState.cpp b/CGameState.cpp index 8ded2aa40..3699673ff 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -7,6 +7,7 @@ #include "hch/CDefObjInfoHandler.h" #include "hch/CArtHandler.h" #include "hch/CTownHandler.h" +#include "hch/CSpellHandler.h" #include "hch/CHeroHandler.h" #include "hch/CObjectHandler.h" #include "hch/CCreatureHandler.h" @@ -19,6 +20,8 @@ #include boost::rand48 ran; + + CGObjectInstance * createObject(int id, int subid, int3 pos, int owner) { CGObjectInstance * nobj; @@ -1018,6 +1021,8 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) vti->town = &VLC->townh->towns[vti->subID]; if (vti->name.length()==0) // if town hasn't name we draw it vti->name=vti->town->names[ran()%vti->town->names.size()]; + + //init buildings if(vti->builtBuildings.find(-50)!=vti->builtBuildings.end()) //give standard set of buildings { vti->builtBuildings.erase(-50); @@ -1027,6 +1032,39 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) if(ran()%2) vti->builtBuildings.insert(31); } + + //init spells + vti->spells.resize(SPELL_LEVELS); + CSpell *s; + for(int z=0; zobligatorySpells.size();z++) + { + s = &VLC->spellh->spells[vti->obligatorySpells[z]]; + vti->spells[s->level-1].push_back(s->id); + vti->possibleSpells -= s->id; + } + while(vti->possibleSpells.size()) + { + ui32 total=0, sel=-1; + for(int ps=0;pspossibleSpells.size();ps++) + total += VLC->spellh->spells[vti->possibleSpells[ps]].probabilities[vti->subID]; + int r = (total)? ran()%total : -1; + for(int ps=0; pspossibleSpells.size();ps++) + { + r -= VLC->spellh->spells[vti->possibleSpells[ps]].probabilities[vti->subID]; + if(r<0) + { + sel = ps; + break; + } + } + if(sel<0) + sel=0; + + CSpell *s = &VLC->spellh->spells[vti->possibleSpells[sel]]; + vti->spells[s->level-1].push_back(s->id); + vti->possibleSpells -= s->id; + } + players[vti->getOwner()].towns.push_back(vti); } @@ -1048,7 +1086,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) } } - //init visiting heroes + //init visiting and garrisoned heroes for(int l=0; lsecond.heroes.size();l++) { for(int m=0; msecond.towns.size();m++) @@ -1057,9 +1095,21 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) if(vistile == k->second.heroes[l]->pos) { k->second.towns[m]->visitingHero = k->second.heroes[l]; - break; + 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; } } +mainplheloop:; } } } diff --git a/CGameState.h b/CGameState.h index 63447f79e..526cdca2d 100644 --- a/CGameState.h +++ b/CGameState.h @@ -2,7 +2,7 @@ #define CGAMESTATE_H #include "global.h" #ifndef _MSC_VER -#include "../hch/CCreatureHandler.h" +#include "hch/CCreatureHandler.h" #include "lib/VCMI_Lib.h" #endif #include @@ -152,7 +152,7 @@ private: UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos); public: int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month - + friend class CCallback; friend class CPathfinder;; friend class CLuaCallback; diff --git a/CHeroWindow.cpp b/CHeroWindow.cpp index 4fac2287b..492730a0d 100644 --- a/CHeroWindow.cpp +++ b/CHeroWindow.cpp @@ -8,6 +8,7 @@ #include "SDL.h" #include "SDL_Extensions.h" #include "CAdvmapInterface.h" +#include "CCastleInterface.h" #include "hch/CLodHandler.h" #include "AdventureMapButton.h" #include "hch/CObjectHandler.h" @@ -39,7 +40,7 @@ CHeroWindow::CHeroWindow(int playerColor): garInt = NULL; ourBar = new CStatusBar(72, 567, "ADROLLVR.bmp", 660); - quitButton = new AdventureMapButton(CGI->generaltexth->heroscrn[17], std::string(), boost::bind(&CHeroWindow::quit,this), 674, 524, "hsbtns.def", false, NULL, false); + quitButton = new AdventureMapButton(CGI->generaltexth->heroscrn[17], std::string(), boost::function(), 674, 524, "hsbtns.def", false, NULL, false); dismissButton = new AdventureMapButton(std::string(), CGI->generaltexth->heroscrn[28], boost::bind(&CHeroWindow::dismissCurrent,this), 519, 437, "hsbtns2.def", false, NULL, false); questlogButton = new AdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CHeroWindow::questlog,this), 379, 437, "hsbtns4.def", false, NULL, false); @@ -509,24 +510,16 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero) void CHeroWindow::quit() { - for(int i=0; iobjsToBlit.size(); ++i) - { - if( dynamic_cast( LOCPLINT->objsToBlit[i] ) ) - { - LOCPLINT->objsToBlit.erase(LOCPLINT->objsToBlit.begin()+i); - } - } + LOCPLINT->objsToBlit -= this; + deactivate(); + if(LOCPLINT->curint == LOCPLINT->castleInt) + LOCPLINT->castleInt->subInt = NULL; LOCPLINT->curint->activate(); SDL_FreeSurface(curBack); curBack = NULL; - /*for(int v=0; vlclickable.size(); ++v) - { - if(dynamic_cast(LOCPLINT->lclickable[v])) - LOCPLINT->lclickable.erase(LOCPLINT->lclickable.begin()+v); - }*/ for(int g=0; g comp; - LOCPLINT->showInfoDialog(text, comp); + LOCPLINT->showInfoDialog(text, std::vector()); } } void LRClickableAreaWText::clickRight(boost::logic::tribool down) @@ -1097,7 +1089,7 @@ void LRClickableAreaWTextComp::clickLeft(boost::logic::tribool down) { if((!down) && pressedL) { - std::vector comp(1, new SComponent(SComponent::Etype(baseType), type, bonus)); + std::vector comp(1, new SComponent(SComponent::Etype(baseType), type, bonus)); LOCPLINT->showInfoDialog(text, comp); } ClickableL::clickLeft(down); diff --git a/CHeroWindow.h b/CHeroWindow.h index b5c00d691..0b459d1ef 100644 --- a/CHeroWindow.h +++ b/CHeroWindow.h @@ -80,7 +80,7 @@ public: ~CArtPlace(); }; -class CHeroWindow: public IActivable, public IShowable, public virtual CIntObject +class CHeroWindow: public IShowActivable, public virtual CIntObject { SDL_Surface * background, * curBack; const CGHeroInstance * curHero; diff --git a/CMT.cpp b/CMT.cpp index befcda09c..f3dd262a9 100644 --- a/CMT.cpp +++ b/CMT.cpp @@ -101,6 +101,7 @@ int main(int argc, _TCHAR* argv[]) CGI->townh = VLC->townh; CGI->heroh = VLC->heroh; CGI->objh = VLC->objh; + CGI->spellh = VLC->spellh; CGI->dobjinfo = VLC->dobjinfo; CGI->buildh = VLC->buildh; THC std::cout<<"Initializing VCMI_Lib: "< server_log.txt")); //runs server executable; //TODO: will it work on non-windows platforms? THC tmh.getDif();pomtime.getDif();//reset timers - CSpellHandler * spellh = new CSpellHandler; - spellh->loadSpells(); - cgi->spellh = spellh; - THC std::cout<<"\tSpell handler: "<pathf = new CPathfinder(); THC std::cout<<"\tPathfinder: "<consoleh->runConsole(); diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index f8da7b448..665818efd 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -165,13 +165,19 @@ void CGarrisonSlot::clickLeft(tribool down) boost::bind(&CCallback::upgradeCreature,LOCPLINT->cb,getObj(),ID,pom.newID[0]), //if upgrade is possible we'll bind proper function in callback boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID),&pom)) ->activate(); - LOCPLINT->curint->deactivate(); } else { (new CCreInfoWindow (creature->idNumber,1,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(); + } + else + { LOCPLINT->curint->deactivate(); } owner->highlighted = NULL; @@ -479,7 +485,7 @@ void CGarrisonInt::deactivate() deactiveteSlots(); } -CInfoWindow::CInfoWindow(std::string text, int player, int charperline, std::vector &comps, std::vector > > &Buttons) +CInfoWindow::CInfoWindow(std::string text, int player, int charperline, const std::vector &comps, std::vector > > &Buttons) { for(int i=0;iresdatabar.draw(); } -void CPlayerInterface::showSelDialog(std::string &text, std::vector &components, ui32 askID) +void CPlayerInterface::showSelDialog(std::string &text, const std::vector &components, ui32 askID) //void CPlayerInterface::showSelDialog(std::string text, std::vector & components, int askID) { boost::unique_lock un(*pim); @@ -1970,26 +1976,12 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town) if(town->garrisonHero) { CGI->mh->hideObject(town->garrisonHero); - if(adventureInt->heroList.items.size()==1) //it was the only hero - adventureInt->townList.select(0); - else - { - for(int i=0; iheroList.items.size();i++) - { - if(adventureInt->heroList.items[i].first == town->garrisonHero) - { - adventureInt->heroList.items.erase(adventureInt->heroList.items.begin()+i); - adventureInt->heroList.selected = adventureInt->heroList.items.size()-1; - break; - } - } - } } if(town->visitingHero) { CGI->mh->printObject(town->visitingHero); - adventureInt->heroList.items.push_back(std::pair(town->visitingHero,NULL)); } + adventureInt->heroList.updateHList(); CCastleInterface *c = dynamic_cast(curint); if(c) @@ -2039,7 +2031,11 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj) SDL_FreeSurface(graphics->townWins[tt->id]); graphics->townWins[tt->id] = infoWin(tt); } - + if(tt->visitingHero) + { + SDL_FreeSurface(graphics->heroWins[tt->visitingHero->subID]); + graphics->heroWins[tt->visitingHero->subID] = infoWin(tt->visitingHero); + } if(LOCPLINT->castleInt) { LOCPLINT->castleInt->garr->highlighted = NULL; @@ -2049,11 +2045,20 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj) } void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID, int what) //what: 1 - built, 2 - demolished { + boost::unique_lock un(*pim); + switch (buildingID) + { + case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 15: + { + SDL_FreeSurface(graphics->townWins[town->id]); + graphics->townWins[town->id] = infoWin(town); + break; + } + } if(curint!=castleInt) return; if(castleInt->town!=town) return; - boost::unique_lock un(*pim); switch(what) { case 1: @@ -2156,14 +2161,14 @@ void CPlayerInterface::showComp(SComponent comp) adventureInt->infoBar.showComp(&comp,4000); } -void CPlayerInterface::showInfoDialog(std::string &text, std::vector &components) +void CPlayerInterface::showInfoDialog(std::string &text, const std::vector &components) { std::vector intComps; for(int i=0;i & components) +void CPlayerInterface::showInfoDialog(std::string &text, const std::vector & components) { showingDialog->set(true); curint->deactivate(); //dezaktywacja starego interfejsu @@ -2176,7 +2181,7 @@ void CPlayerInterface::showInfoDialog(std::string &text, std::vectoractivate(); LOCPLINT->objsToBlit.push_back(temp); } -void CPlayerInterface::showYesNoDialog(std::string &text, std::vector & components, CFunctionList onYes, CFunctionList onNo, bool deactivateCur, bool DelComps) +void CPlayerInterface::showYesNoDialog(std::string &text, const std::vector & components, CFunctionList onYes, CFunctionList onNo, bool deactivateCur, bool DelComps) { if(deactivateCur) curint->deactivate(); //dezaktywacja starego interfejsu @@ -2216,6 +2221,10 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero) adventureInt->heroWindow->setHero(hero); this->objsToBlit.push_back(adventureInt->heroWindow); curint->deactivate(); + if(curint == castleInt) + castleInt->subInt = adventureInt->heroWindow; + adventureInt->heroWindow->quitButton->callback.funcs.clear(); + adventureInt->heroWindow->quitButton->callback += boost::bind(&CHeroWindow::quit,adventureInt->heroWindow); adventureInt->heroWindow->activate(); } CStatusBar::CStatusBar(int x, int y, std::string name, int maxw) @@ -2318,7 +2327,9 @@ void CHeroList::genList() int howMany = LOCPLINT->cb->howManyHeroes(); for (int i=0;i(LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,i,0),NULL)); + const CGHeroInstance * h = LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,i,0); + if(!h->inTownGarrison) + items.push_back(std::pair(h,NULL)); } } void CHeroList::select(int which) @@ -2506,15 +2517,16 @@ void CHeroList::draw() blitAt(empty,posporx,pospory+i*32); continue; } - int pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->movement)/100; + const CGHeroInstance *cur = items[iT].first; + int pom = cur->movement / 100; if (pom>25) pom=25; if (pom<0) pom=0; blitAt(mobile->ourImages[pom].bitmap,posmobx,posmoby+i*32); //move point - pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->mana)/5; //bylo: .../10; + pom = cur->mana / 5; //bylo: .../10; if (pom>25) pom=25; if (pom<0) pom=0; blitAt(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana - SDL_Surface * temp = graphics->portraitSmall[LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->portrait]; + SDL_Surface * temp = graphics->portraitSmall[cur->portrait]; blitAt(temp,posporx,pospory+i*32); if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)) { @@ -2860,7 +2872,7 @@ void CRecrutationWindow::show(SDL_Surface * to) cancel->show(); slider->show(); char pom[15]; - SDL_itoa(creatures[which].amount,pom,10); //available + SDL_itoa(creatures[which].amount-slider->value,pom,10); //available printAtMiddle(pom,pos.x+205,pos.y+252,GEOR13,zwykly,screen); SDL_itoa(slider->value,pom,10); //recruit printAtMiddle(pom,pos.x+279,pos.y+252,GEOR13,zwykly,screen); @@ -3228,9 +3240,18 @@ void CCreInfoWindow::close() { deactivate(); CCastleInterface *c = dynamic_cast(LOCPLINT->curint); - if(c) c->showAll(); - if(type) - LOCPLINT->curint->activate(); + if(c && dynamic_cast(c->subInt)) + { + if(type) + c->subInt->activate(); + } + else + { + if(c) + c->showAll(); + if(type) + LOCPLINT->curint->activate(); + } delete this; } void CCreInfoWindow::clickRight(boost::logic::tribool down) diff --git a/CPlayerInterface.h b/CPlayerInterface.h index 28b67098f..c6a10b53f 100644 --- a/CPlayerInterface.h +++ b/CPlayerInterface.h @@ -24,7 +24,7 @@ class CCreatureSet; class CGObjectInstance; class CSlider; struct UpgradeInfo; -template struct CondSh; +template struct CondSh; namespace boost { @@ -174,7 +174,7 @@ public: virtual void show(SDL_Surface * to = NULL); void activate(); void deactivate(); - CInfoWindow(std::string text, int player, int charperline, std::vector &comps, std::vector > > &Buttons); + CInfoWindow(std::string text, int player, int charperline, const std::vector &comps, std::vector > > &Buttons); CInfoWindow(); ~CInfoWindow(); }; @@ -341,8 +341,8 @@ public: void heroCreated(const CGHeroInstance* hero); void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val); void receivedResource(int type, int val); - void showInfoDialog(std::string &text, std::vector &components); - void showSelDialog(std::string &text, std::vector &components, ui32 askID); + void showInfoDialog(std::string &text, const std::vector &components); + void showSelDialog(std::string &text, const std::vector &components, ui32 askID); void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town); void garrisonChanged(const CGObjectInstance * obj); void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished @@ -374,9 +374,9 @@ public: void handleMouseMotion(SDL_Event *sEvent); void init(ICallback * CB); int3 repairScreenPos(int3 pos); - void removeObjToBlit(IShowable* obj); - void showInfoDialog(std::string &text, std::vector & components); - void showYesNoDialog(std::string &text, std::vector & components, CFunctionList onYes, CFunctionList onNo, bool deactivateCur, bool DelComps); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close + void removeObjToBlit(IShowable* obj); + void showInfoDialog(std::string &text, const std::vector & components); + void showYesNoDialog(std::string &text, const std::vector & components, CFunctionList onYes, CFunctionList onNo, bool deactivateCur, bool DelComps); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close CPlayerInterface(int Player, int serial);//c-tor ~CPlayerInterface();//d-tor @@ -565,7 +565,7 @@ public: std::vector comps; //skills to select AdventureMapButton *ok; boost::function cb; - + void close(); CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback); ~CLevelWindow(); @@ -586,4 +586,4 @@ public: extern CPlayerInterface * LOCPLINT; -#endif //CPLAYERINTERFACE_H \ No newline at end of file +#endif //CPLAYERINTERFACE_H diff --git a/client/Client.cpp b/client/Client.cpp index f1aae09d0..2b5f59fee 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -323,10 +323,21 @@ void CClient::process(int what) { NewStructures ns; *serv >> ns; - std::cout << "New structure(s) in " << ns.tid << " - " << *ns.bid.begin() << std::endl; + CGTownInstance *town = static_cast(gs->map->objects[ns.tid]); + std::cout << "New structure(s) in " << ns.tid <<" " << town->name << " - " << *ns.bid.begin() << std::endl; gs->apply(&ns); BOOST_FOREACH(si32 bid, ns.bid) - playerint[gs->map->objects[ns.tid]->tempOwner]->buildChanged(static_cast(gs->map->objects[ns.tid]),bid,1); + { + if(bid==13) //for or capitol + { + town->defInfo = gs->capitols[town->subID]; + } + if(bid ==7) + { + town->defInfo = gs->forts[town->subID]; + } + playerint[town->tempOwner]->buildChanged(town,bid,1); + } break; } case 506: diff --git a/client/FunctionList.h b/client/FunctionList.h index 8ab5f7f25..0a8c324ec 100644 --- a/client/FunctionList.h +++ b/client/FunctionList.h @@ -1,24 +1,24 @@ #pragma once #include -template > +template class CFunctionList { public: - std::vector > funcs; + std::vector > funcs; CFunctionList(int){}; CFunctionList(){}; - CFunctionList(const boost::function &first) + CFunctionList(const boost::function &first) { funcs.push_back(first); } - CFunctionList & operator+=(const boost::function &first) + CFunctionList & operator+=(const boost::function &first) { funcs.push_back(first); return *this; } - const boost::function & operator=(const boost::function &first) + const boost::function & operator=(const boost::function &first) { funcs.push_back(first); return first; @@ -29,7 +29,7 @@ public: } void operator()() const { - std::vector > funcs2 = funcs; //backup + std::vector > funcs2 = funcs; //backup for(int i=0;ir = 0x84; neutralColor->g = 0x84; neutralColor->b = 0x84; neutralColor->unused = 0x0;//gray + + std::ifstream bback("config/mageBg.txt"); + while(!bback.eof()) + { + bback >> pals; + guildBgs.push_back(pals); + } + bback.close(); } void Graphics::initializeBattleGraphics() { diff --git a/client/Graphics.h b/client/Graphics.h index 5bfe2a862..ce620c715 100644 --- a/client/Graphics.h +++ b/client/Graphics.h @@ -38,6 +38,7 @@ public: //for battles std::vector< std::vector< std::string > > battleBacks; //battleBacks[terType] - vector of possible names for certain terrain type std::vector< std::string > battleHeroes; //battleHeroes[hero type] - name of def that has hero animation for battle + std::vector guildBgs;// name of bitmaps with imgs for mage guild screen //functions Graphics(); void initializeBattleGraphics(); diff --git a/client/VCMI_client.vcproj b/client/VCMI_client.vcproj index d8481fd0d..1950cc62d 100644 --- a/client/VCMI_client.vcproj +++ b/client/VCMI_client.vcproj @@ -362,10 +362,6 @@ RelativePath="..\hch\CSndHandler.cpp" > - - @@ -512,10 +508,6 @@ RelativePath="..\hch\CSndHandler.h" > - - @@ -565,6 +557,10 @@ > + + diff --git a/config/mageLevel.txt b/config/mageLevel.txt new file mode 100644 index 000000000..cfc9dd7eb --- /dev/null +++ b/config/mageLevel.txt @@ -0,0 +1,9 @@ +4 +5 +5 +5 +5 +5 +3 +3 +5 \ No newline at end of file diff --git a/global.h b/global.h index 998da54a2..2aaa59692 100644 --- a/global.h +++ b/global.h @@ -61,6 +61,7 @@ const int NEUTRAL_PLAYER=255; const int NAMES_PER_TOWN=16; const int CREATURES_PER_TOWN = 7; //without upgrades const int MAX_BUILDING_PER_TURN = 1; +const int SPELL_LEVELS = 5; #define MARK_BLOCKED_POSITIONS false #define MARK_VISITABLE_POSITIONS false diff --git a/hch/CArtHandler.cpp b/hch/CArtHandler.cpp index 06c989ed2..27c97638e 100644 --- a/hch/CArtHandler.cpp +++ b/hch/CArtHandler.cpp @@ -5,7 +5,6 @@ #include #include #include "../lib/VCMI_Lib.h" -void loadToIt(std::string &dest, std::string &src, int &iter, int mode); extern CLodHandler *bitmaph; using namespace boost::assign; CArtHandler::CArtHandler() diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 6b943ce1a..a1e1f4880 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -271,6 +271,20 @@ int CGTownInstance::hallLevel() const // -1 - none, 0 - village, 1 - town, 2 - c return 0; return -1; } +int CGTownInstance::mageGuildLevel() const +{ + if ((builtBuildings.find(4))!=builtBuildings.end()) + return 5; + if ((builtBuildings.find(3))!=builtBuildings.end()) + return 4; + if ((builtBuildings.find(2))!=builtBuildings.end()) + return 3; + if ((builtBuildings.find(1))!=builtBuildings.end()) + return 2; + if ((builtBuildings.find(0))!=builtBuildings.end()) + return 1; + return 0; +} bool CGTownInstance::creatureDwelling(const int & level, bool upgraded) const { return builtBuildings.find(30+level+upgraded*7)!=builtBuildings.end(); @@ -349,6 +363,7 @@ CGObjectInstance::~CGObjectInstance() } CGHeroInstance::CGHeroInstance() { + inTownGarrison = false; portrait = level = exp = -1; isStanding = true; moveDir = 4; diff --git a/hch/CObjectHandler.h b/hch/CObjectHandler.h index ac3f33651..5fcb7eab3 100644 --- a/hch/CObjectHandler.h +++ b/hch/CObjectHandler.h @@ -141,7 +141,8 @@ public: int identifier; //special identifier from h3m (only > RoE maps) int alignment; std::set forbiddenBuildings, builtBuildings; - std::vector possibleSpells, obligatorySpells, availableSpells; + std::vector possibleSpells, obligatorySpells; + std::vector > spells; //spells[level] -> vector of spells, first will be available in guild struct StrInfo { @@ -158,6 +159,7 @@ public: int getSightDistance() const; //returns sight distance int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol + int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol bool creatureDwelling(const int & level, bool upgraded=false) const; int getHordeLevel(const int & HID) const; //HID - 0 or 1; returns creature level or -1 if that horde structure is not present int creatureGrowth(const int & level) const; diff --git a/hch/CSpellHandler.cpp b/hch/CSpellHandler.cpp index 244969e48..9677cfb7f 100644 --- a/hch/CSpellHandler.cpp +++ b/hch/CSpellHandler.cpp @@ -1,359 +1,70 @@ - #include "../stdafx.h" +#define VCMI_DLL +#include "../stdafx.h" #include "CSpellHandler.h" -#include "../CGameInfo.h" #include "CLodHandler.h" - +#include "../lib/VCMI_Lib.h" +#include +extern CLodHandler *bitmaph; void CSpellHandler::loadSpells() { - std::string buf = CGI->bitmaph->getTextFile("SPTRAITS.TXT"); - int andame = buf.size(); - int i=0; //buf iterator - int hmcr=0; - for(i; igetTextFile("SPTRAITS.TXT"), pom; + int andame = buf.size(), i=0; //buf iterator + for(int z=0; z<5; ++z) + loadToIt(pom,buf,i,3); + bool combSpells=false; //true, if we are reading combat spells while(i costs; //per skill level: 0 - none, 1 - basic, etc + std::vector powers; //[er skill level: 0 - none, 1 - basic, etc + std::vector probabilities; //% chance to gain for castles + std::vector AIVals; //AI values: per skill level: 0 - none, 1 - basic, etc + std::vector descriptions; //descriptions of spell for skill levels: 0 - none, 1 - basic, etc std::string attributes; //reference only attributes bool combatSpell; //is this spell combat (true) or adventure (false) }; -class CSpellHandler +class DLL_EXPORT CSpellHandler { public: std::vector spells; diff --git a/hch/CTownHandler.cpp b/hch/CTownHandler.cpp index e99640166..baeecb39f 100644 --- a/hch/CTownHandler.cpp +++ b/hch/CTownHandler.cpp @@ -248,6 +248,15 @@ void CTownHandler::loadNames() of.close(); of.clear(); + itr=0; + of.open("config/mageLevel.txt"); + while(!of.eof()) + { + of >> towns[itr++].mageLevel; + } + of.close(); + of.clear(); + of.open("config/requirements.txt"); while(!of.eof()) { diff --git a/hch/CTownHandler.h b/hch/CTownHandler.h index 2cf895980..7793d9098 100644 --- a/hch/CTownHandler.h +++ b/hch/CTownHandler.h @@ -14,6 +14,7 @@ public: std::vector basicCreatures; //level (from 0) -> ID std::vector upgradedCreatures; //level (from 0) -> ID std::map hordeLvl; //[0] - first horde building creature level; [1] - second horde building (-1 if not present) + ui32 mageLevel; //max available mage guild level int bonus; //pic number int typeID; }; diff --git a/lib/Connection.h b/lib/Connection.h index a071f7dd0..b08659666 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/lib/VCMI_Lib.cpp b/lib/VCMI_Lib.cpp index c6e208609..e98801ae5 100644 --- a/lib/VCMI_Lib.cpp +++ b/lib/VCMI_Lib.cpp @@ -8,6 +8,7 @@ #include "../hch/CObjectHandler.h" #include "../hch/CTownHandler.h" #include "../hch/CBuildingHandler.h" +#include "../hch/CSpellHandler.h" class CLodHandler; LibClasses * VLC = NULL; CLodHandler * bitmaph=NULL; @@ -50,6 +51,11 @@ DLL_EXPORT void initDLL(CLodHandler *b) VLC->buildh = new CBuildingHandler; VLC->buildh->loadBuildings(); THC std::cout<<"\tBuilding handler: "<loadSpells(); + VLC->spellh = spellh; + THC std::cout<<"\tSpell handler: "< playerint; - //std::vector playerColors; - //SDL_Color neutralColor; - //StartInfo scenarioOps; }; extern DLL_EXPORT LibClasses * VLC; +DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode); +DLL_EXPORT void loadToIt(si32 &dest, std::string &src, int &iter, int mode); DLL_EXPORT void initDLL(CLodHandler *b); diff --git a/lib/VCMI_lib.vcproj b/lib/VCMI_lib.vcproj index 5866f4d8a..caed98595 100644 --- a/lib/VCMI_lib.vcproj +++ b/lib/VCMI_lib.vcproj @@ -294,6 +294,10 @@ RelativePath=".\Connection.cpp" > + + @@ -360,6 +364,10 @@ RelativePath=".\Connection.h" > + + diff --git a/map.cpp b/map.cpp index 5ac8eb204..7e84a7862 100644 --- a/map.cpp +++ b/map.cpp @@ -900,7 +900,7 @@ void Mapa::loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i ) { for(int bit=0;bit<8;bit++) if(bufor[i] & (1<forbiddenBuildings.insert(byte*8+bit); + nt->forbiddenBuildings.insert((byte-6)*8+bit); i++; } nt->builtBuildings = convertBuildings(nt->builtBuildings,nt->subID); diff --git a/mapHandler.cpp b/mapHandler.cpp index 1b2fd5d0f..fcd50a405 100644 --- a/mapHandler.cpp +++ b/mapHandler.cpp @@ -413,9 +413,8 @@ void CMapHandler::initObjectRects() //initializing objects / rects for(int f=0; fobjects.size(); ++f) { - /*map->objects[f]->pos.x+=1; - map->objects[f]->pos.y+=1;*/ - if(!map->objects[f]->defInfo) + if((map->objects[f]->ID==34 && static_cast(map->objects[f])->inTownGarrison) + || !map->objects[f]->defInfo) { continue; } @@ -489,7 +488,7 @@ void processDef (CGDefInfo* def) def->width = def->handler->ourImages[0].bitmap->w/32; def->height = def->handler->ourImages[0].bitmap->h/32; CGDefInfo* pom = CGI->dobjinfo->gobjs[def->id][def->subid]; - if(pom) + if(pom && def->id!=98) { pom->handler = def->handler; pom->width = pom->handler->ourImages[0].bitmap->w/32; @@ -566,8 +565,6 @@ void CMapHandler::init() std::cout<<"\tPreparing FoW, roads, rivers,borders: "< > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, SDL_Rect * extRect) diff --git a/nodrze.h b/nodrze.h index c9bf38f77..396f2dd6b 100644 --- a/nodrze.h +++ b/nodrze.h @@ -189,7 +189,7 @@ template void nodrze::wypiszObficie(std::ostream & strum) template T* operator%(nodrze & drzewko, X co) { CLOG ("Szukam " <gl->loguj); #endif wezel * w = drzewko.korzen; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index fc29d8fe4..5beb651c3 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -168,7 +168,6 @@ void CGameHandler::changeSecSkill(int ID, ui16 which, int val, bool abs) sps.val = val; sendAndApply(&sps); } - void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs) { SetPrimSkill sps; @@ -677,7 +676,7 @@ upgend: CCreatureSet csn = town->visitingHero->army, cso = town->army; while(!cso.slots.empty())//while there are unmoved creatures { - int pos = csn.getSlotFor(cso.slots.begin()->first); + int pos = csn.getSlotFor(cso.slots.begin()->second.first); if(pos<0) goto handleConEnd; if(csn.slots.find(pos)!=csn.slots.end()) //add creatures to the existing stack diff --git a/server/CScriptCallback.cpp b/server/CScriptCallback.cpp index f5c1d61d2..bb9a6ba0a 100644 --- a/server/CScriptCallback.cpp +++ b/server/CScriptCallback.cpp @@ -73,7 +73,7 @@ void CScriptCallback::showInfoDialog(InfoWindow *iw) gh->sendToAllClients(iw); } -void CScriptCallback::showSelectionDialog(SelectionDialog *iw, boost::function > &callback) +void CScriptCallback::showSelectionDialog(SelectionDialog *iw, boost::function &callback) { gh->ask(iw,iw->player,callback); } diff --git a/server/CScriptCallback.h b/server/CScriptCallback.h index c79daf17b..ca4f42744 100644 --- a/server/CScriptCallback.h +++ b/server/CScriptCallback.h @@ -41,7 +41,7 @@ public: void setHoverName(int objid, MetaString * name); void changePrimSkill(int ID, int which, int val, bool abs=false); void showInfoDialog(InfoWindow *iw); - void showSelectionDialog(SelectionDialog *iw, boost::function > &callback); //returns question id + void showSelectionDialog(SelectionDialog *iw, boost::function &callback); //returns question id void giveResource(int player, int which, int val); void showCompInfo(ShowInInfobox * comp); void heroVisitCastle(int obj, int heroID);