diff --git a/CCallback.cpp b/CCallback.cpp index 3280624a9..21a98ec13 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -801,6 +801,11 @@ CCallback::CCallback( CGameState * GS, int Player, CClient *C ) waitTillRealize = false; } +const CMapHeader * CCallback::getMapHeader() const +{ + return gs->map; +} + InfoAboutHero::InfoAboutHero() { details = NULL; diff --git a/CCallback.h b/CCallback.h index de69c92ad..bb2291260 100644 --- a/CCallback.h +++ b/CCallback.h @@ -39,6 +39,7 @@ struct TerrainTile; class CHeroClass; class IShipyard; struct CPackForServer; +class CMapHeader; struct InfoAboutHero { @@ -125,6 +126,7 @@ public: virtual int getMySerial()const =0; virtual int getHeroSerial(const CGHeroInstance * hero)const =0; virtual const StartInfo * getStartInfo()const =0; + virtual const CMapHeader * getMapHeader()const =0; virtual int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const =0; //when called during battle, takes into account creatures' spell cost reduction //hero @@ -246,6 +248,7 @@ public: const CCreatureSet* getGarrison(const CGObjectInstance *obj) const; UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos) const; const StartInfo * getStartInfo() const; + const CMapHeader * getMapHeader()const ; int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos) const; diff --git a/client/AdventureMapButton.cpp b/client/AdventureMapButton.cpp index 351c584b1..b68e44bd8 100644 --- a/client/AdventureMapButton.cpp +++ b/client/AdventureMapButton.cpp @@ -151,10 +151,13 @@ void AdventureMapButton::clickRight(tribool down, bool previousState) void AdventureMapButton::hover (bool on) { + if(blocked) + return; + if(hoverable) { if(on) - state = 2; + state = 3; else state = 0; } @@ -164,14 +167,14 @@ void AdventureMapButton::hover (bool on) if(on) state = 1; else - state = hoverable ? 2 : 0; + state = hoverable ? 3 : 0; } ////Hoverable::hover(on); std::string *name = (vstd::contains(hoverTexts,state)) ? (&hoverTexts[state]) : (vstd::contains(hoverTexts,0) ? (&hoverTexts[0]) : NULL); - if(LOCPLINT && name && blocked!=1) //if there is no name, there is nohing to display also + if(LOCPLINT && name && name->size() && blocked!=1) //if there is no name, there is nohing to display also { if (LOCPLINT->battleInt) //for battle buttons { @@ -283,6 +286,7 @@ void CHighlightableButton::select(bool on) { selected = on; state = selected ? 3 : 0; + if(selected) callback(); else @@ -299,7 +303,7 @@ void CHighlightableButton::clickLeft(tribool down, bool previousState) if(blocked) return; if (down) - state=1; + state = 1; else state = selected ? 3 : 0; show(screenBuf); @@ -325,6 +329,15 @@ CHighlightableButton::CHighlightableButton( const std::pair &onSelect, int x, int y, const std::string &defName, int myid, int key/*=0*/, std::vector * add /*= NULL*/, bool playerColoredButton /*= false */ ) +: onlyOn(false), selected(false) // TODO: callback2(???) +{ + ID = myid; + std::map pom; + pom[0] = Name; + init(onSelect, pom,HelpBox, playerColoredButton, defName, add, x, y, key); +} + void CHighlightableButtonsGroup::addButton(CHighlightableButton* bt) { bt->callback += boost::bind(&CHighlightableButtonsGroup::selectionChanged,this,bt->ID); @@ -411,6 +424,14 @@ void CHighlightableButtonsGroup::showAll( SDL_Surface * to ) show(to); } +void CHighlightableButtonsGroup::block( ui8 on ) +{ + for(size_t i=0;iblock(on); + } +} + void CSlider::sliderClicked() { if(!moving) @@ -547,17 +568,20 @@ CSlider::CSlider(int x, int y, int totalw, boost::function Moved, int right = new AdventureMapButton; slider = new AdventureMapButton; + pos.x += x; + pos.y += y; + if(horizontal) { - left->pos.y = slider->pos.y = right->pos.y = pos.y = y; - left->pos.x = pos.x = x; - right->pos.x = x + totalw - 16; + left->pos.y = slider->pos.y = right->pos.y = pos.y; + left->pos.x = pos.x; + right->pos.x = pos.x + totalw - 16; } else { - left->pos.x = slider->pos.x = right->pos.x = pos.x = x; - left->pos.y = pos.y = y; - right->pos.y = y + totalw - 16; + left->pos.x = slider->pos.x = right->pos.x = pos.x; + left->pos.y = pos.y; + right->pos.y = pos.y + totalw - 16; } left->callback = boost::bind(&CSlider::moveLeft,this); @@ -606,6 +630,7 @@ void CSlider::block( bool on ) void CSlider::setAmount( int to ) { + amount = to; positions = to - capacity; amax(positions, 1); } diff --git a/client/AdventureMapButton.h b/client/AdventureMapButton.h index c7e5fa241..792a439a0 100644 --- a/client/AdventureMapButton.h +++ b/client/AdventureMapButton.h @@ -83,6 +83,7 @@ class CHighlightableButton public: CHighlightableButton(const CFunctionList &onSelect, const CFunctionList &onDeselect, const std::map &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector * add, int x, int y, int key=0); CHighlightableButton(const std::pair help, const CFunctionList &onSelect, int x, int y, const std::string &defName, int myid, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor + CHighlightableButton(const std::string &Name, const std::string &HelpBox, const CFunctionList &onSelect, int x, int y, const std::string &defName, int myid, int key=0, std::vector * add = NULL, bool playerColoredButton = false );//c-tor bool onlyOn, selected; CFunctionList callback2; //when de-selecting void select(bool on); @@ -107,6 +108,7 @@ public: void selectionChanged(int to); void show(SDL_Surface * to); void showAll(SDL_Surface * to); + void block(ui8 on); }; diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index 9d809af6f..d4452ba4e 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -24,6 +24,7 @@ #include #include #include +#include "CPreGame.h" #ifdef _MSC_VER #pragma warning (disable : 4355) @@ -1426,6 +1427,7 @@ void CAdvMapInt::fshowSpellbok() void CAdvMapInt::fadventureOPtions() { + GH.pushInt(new CAdventureOptions); } void CAdvMapInt::fsystemOptions() @@ -1624,6 +1626,14 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key) ui8 Dir; switch(key.keysym.sym) { + case SDLK_i: + if(active) + CAdventureOptions::showScenarioInfo(); + return; + case SDLK_s: + if(active) + GH.pushInt(new CSelectionScreen(saveGame)); + return; case SDLK_UP: Dir = UP; break; @@ -1662,7 +1672,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key) case SDLK_t: { //act on key down if marketplace windows is not already opened - if(key.state != SDL_PRESSED || dynamic_cast(GH.topInt())) return; + if(key.state != SDL_PRESSED || GH.topInt()->type & BLOCK_ADV_HOTKEYS) return; //check if we have aby marketplace std::vector towns = LOCPLINT->cb->getTownsInfo(); @@ -1786,4 +1796,27 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent ) scrollingDir &= ~DOWN; } } +} + +CAdventureOptions::CAdventureOptions() +{ + OBJ_CONSTRUCTION_CAPTURING_ALL; + bg = new CPicture(BitmapHandler::loadBitmap("ADVOPTS.bmp"), 0, 0); + graphics->blueToPlayersAdv(bg->bg, LOCPLINT->playerID); + pos = bg->center(); + exit = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally, &GH, this), 204, 313, "IOK6432.DEF",SDLK_RETURN); + + //scenInfo = new AdventureMapButton("","", boost::bind(&CGuiHandler::popIntTotally, &GH, this), 24, 24, "ADVINFO.DEF",SDLK_i); + scenInfo = new AdventureMapButton("","", boost::bind(&CGuiHandler::popIntTotally, &GH, this), 24, 198, "ADVINFO.DEF",SDLK_i); + scenInfo->callback += CAdventureOptions::showScenarioInfo; + //viewWorld = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally, &GH, this), 204, 313, "IOK6432.DEF",SDLK_RETURN); +} + +CAdventureOptions::~CAdventureOptions() +{ +} + +void CAdventureOptions::showScenarioInfo() +{ + GH.pushInt(new CScenarioInfo(LOCPLINT->cb->getMapHeader(), LOCPLINT->cb->getStartInfo())); } \ No newline at end of file diff --git a/client/CAdvmapInterface.h b/client/CAdvmapInterface.h index 5c5bad4d1..c6c33d932 100644 --- a/client/CAdvmapInterface.h +++ b/client/CAdvmapInterface.h @@ -25,6 +25,18 @@ class CHeroWindow; * */ +class CAdventureOptions : public CIntObject +{ +public: + CPicture *bg; + AdventureMapButton *exit, *viewWorld, *puzzle, *dig, *scenInfo, *replay; + + CAdventureOptions(); + ~CAdventureOptions(); + static void showScenarioInfo(); +}; + + class CMinimap : public CIntObject { public: diff --git a/client/CMT.cpp b/client/CMT.cpp index 077bcd987..24bffce72 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -287,7 +287,7 @@ void processCommand(const std::string &message) // std::string &name = CPG->ourScenSel->mapsel.ourGames[num]->filename; // client->load(name.substr(0, name.size()-6)); //} - else if(cn=="resolution") + else if(cn=="resolution" || cn == "r") { if(LOCPLINT) { diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index ee8708894..4635019a1 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -25,6 +25,8 @@ #include "AdventureMapButton.h" #include "GUIClasses.h" #include "../hch/CCreatureHandler.h" +#include "CPlayerInterface.h" +#include "../CCallback.h" /* * CPreGame.cpp, part of VCMI engine * @@ -35,13 +37,17 @@ * */ namespace fs = boost::filesystem; +using boost::bind; +using boost::ref; void startGame(StartInfo * options); CGPreGame * CGP; -static const CMapInfo *curMap = NULL; +static const CMapHeader *curMap = NULL; static StartInfo *curOpts = NULL; static int playerColor; +static std::string selectedName; //set when game is started/loaded + CMenuScreen::CMenuScreen( EState which ) { OBJ_CONSTRUCTION; @@ -133,7 +139,7 @@ void CGPreGame::run() CGPreGame::CGPreGame() { - GH.defActionsDef = 31; + GH.defActionsDef = 63; CGP = this; mainbg = BitmapHandler::loadBitmap("ZPIC1005.bmp"); @@ -177,17 +183,31 @@ void CGPreGame::disposeGraphics() CSelectionScreen::CSelectionScreen( EState Type ) { - OBJ_CONSTRUCTION; + OBJ_CONSTRUCTION_CAPTURING_ALL; + IShowActivable::type = BLOCK_ADV_HOTKEYS; + pos.w = 762; + pos.h = 584; + if(Type == saveGame) + { + center(pos); + } + else + { + pos.x = 3; + pos.y = 6; + bg = new CPicture(BitmapHandler::loadBitmap(rand()%2 ? "ZPIC1000.bmp" : "ZPIC1001.bmp"), -3, -6, true); + } + CGP->loadGraphics(); type = Type; curOpts = &sInfo; + sInfo.difficulty = 1; current = NULL; sInfo.mode = (Type == newGame ? 0 : 1); sInfo.turnTime = 0; curTab = NULL; - bg = new CPicture(BitmapHandler::loadBitmap(rand()%2 ? "ZPIC1000.bmp" : "ZPIC1001.bmp"), 0, 0, true); card = new InfoCard(type); opt = new OptionsTab(type/*, sInfo*/); opt->recActions = DISPOSE; @@ -200,31 +220,38 @@ CSelectionScreen::CSelectionScreen( EState Type ) { card->difficulty->onChange = bind(&CSelectionScreen::difficultyChange, this, _1); card->difficulty->select(1, 0); - AdventureMapButton *select = new AdventureMapButton(CGI->generaltexth->zelp[45], bind(&CSelectionScreen::toggleTab, this, sel), 414, 81, "GSPBUTT.DEF", SDLK_s); + AdventureMapButton *select = new AdventureMapButton(CGI->generaltexth->zelp[45], bind(&CSelectionScreen::toggleTab, this, sel), 411, 75, "GSPBUTT.DEF", SDLK_s); select->addTextOverlay(CGI->generaltexth->allTexts[500], FONT_SMALL); - AdventureMapButton *opts = new AdventureMapButton(CGI->generaltexth->zelp[46], bind(&CSelectionScreen::toggleTab, this, opt), 414, 509, "GSPBUTT.DEF", SDLK_a); + AdventureMapButton *opts = new AdventureMapButton(CGI->generaltexth->zelp[46], bind(&CSelectionScreen::toggleTab, this, opt), 411, 503, "GSPBUTT.DEF", SDLK_a); opts->addTextOverlay(CGI->generaltexth->allTexts[501], FONT_SMALL); - AdventureMapButton *random = new AdventureMapButton(CGI->generaltexth->zelp[47], bind(&CSelectionScreen::toggleTab, this, sel), 414, 105, "GSPBUTT.DEF", SDLK_r); + AdventureMapButton *random = new AdventureMapButton(CGI->generaltexth->zelp[47], bind(&CSelectionScreen::toggleTab, this, sel), 411, 99, "GSPBUTT.DEF", SDLK_r); random->addTextOverlay(CGI->generaltexth->allTexts[740], FONT_SMALL); - start = new AdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 414, 535, "SCNRBEG.DEF", SDLK_b); + start = new AdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 529, "SCNRBEG.DEF", SDLK_b); } break; - case loadGame: sel->recActions = 255; - start = new AdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 414, 535, "SCNRLOD.DEF", SDLK_b); + start = new AdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 529, "SCNRLOD.DEF", SDLK_l); + break; + case saveGame: + sel->recActions = 255; + start = new AdventureMapButton("", CGI->generaltexth->zelp[103].second, bind(&CSelectionScreen::startGame, this), 411, 529, "SCNRSAV.DEF"); break; } - back = new AdventureMapButton(CGI->generaltexth->zelp[105], bind(&CGuiHandler::popIntTotally, &GH, this), 584, 535, "SCNRBACK.DEF", SDLK_ESCAPE); + start->assignedKeys.insert(SDLK_RETURN); + + back = new AdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 581, 529, "SCNRBACK.DEF", SDLK_ESCAPE); } CSelectionScreen::~CSelectionScreen() { - + curMap = NULL; + curOpts = NULL; + playerColor = -1; } void CSelectionScreen::toggleTab(CIntObject *tab) @@ -250,6 +277,8 @@ void CSelectionScreen::toggleTab(CIntObject *tab) void CSelectionScreen::changeSelection( const CMapInfo *to ) { curMap = current = to; + if(to && type == loadGame) + curOpts->difficulty = to->seldiff; updateStartInfo(to); card->changeSelection(to); opt->changeSelection(to); @@ -257,6 +286,7 @@ void CSelectionScreen::changeSelection( const CMapInfo *to ) void CSelectionScreen::updateStartInfo( const CMapInfo * to ) { + if(!to) return; sInfo.mapname = to->filename; sInfo.playerInfos.clear(); sInfo.playerInfos.resize(to->playerAmnt); @@ -317,17 +347,29 @@ void CSelectionScreen::updateStartInfo( const CMapInfo * to ) void CSelectionScreen::startGame() { - if(!current) - return; + if(type != saveGame) + { + if(!current) + return; - //CGP->disposeGraphics(); - StartInfo *si = new StartInfo(sInfo); - GH.popIntTotally(this); - GH.popIntTotally(GH.topInt()); - curMap = NULL; - curOpts = NULL; - ::startGame(si); - delete si; //rather won't be called... + selectedName = sInfo.mapname; + StartInfo *si = new StartInfo(sInfo); + GH.popIntTotally(this); + GH.popIntTotally(GH.topInt()); + curMap = NULL; + curOpts = NULL; + ::startGame(si); + delete si; //rather won't be called... + } + else + { + if(!(sel && sel->txt && sel->txt->text.size())) + return; + + selectedName = sel->txt->text; + LOCPLINT->cb->save(sel->txt->text); + GH.popIntTotally(this); + } } void CSelectionScreen::difficultyChange( int to ) @@ -339,7 +381,7 @@ void CSelectionScreen::difficultyChange( int to ) // A new size filter (Small, Medium, ...) has been selected. Populate // selMaps with the relevant data. -void SelectionTab::filter( int size ) +void SelectionTab::filter( int size, bool selectFirst ) { curItems.clear(); @@ -352,8 +394,11 @@ void SelectionTab::filter( int size ) slider->block(false); slider->setAmount(curItems.size()); sort(); - slider->moveTo(0); - onSelect(curItems[0]); + if(selectFirst) + { + slider->moveTo(0); + onSelect(curItems[0]); + } } else { @@ -435,10 +480,15 @@ SelectionTab::SelectionTab(EState Type, const boost::function { OBJ_CONSTRUCTION; selectionPos = 0; - used = LCLICK | WHEEL | KEYBOARD | DOUBLECLICK; slider = NULL; + txt = NULL; type = Type; + + bg = new CPicture(BitmapHandler::loadBitmap("SCSELBCK.bmp"), 0, 0, true); + pos.w = bg->pos.w; + pos.h = bg->pos.h; + std::vector toParse; switch(type) { @@ -459,38 +509,55 @@ SelectionTab::SelectionTab(EState Type, const boost::function else { positions = 16; - } + } + if(type == saveGame) + txt = new CTextInput(Rect(32, 539, 350, 20), Point(-32, -25), "GSSTRIP.bmp", 0); break; default: assert(0); } - bg = new CPicture(BitmapHandler::loadBitmap("SCSELBCK.bmp"), 3, 6, true); - pos = bg->pos; //size filter buttons { int sizes[] = {36, 72, 108, 144, 0}; const char * names[] = {"SCSMBUT.DEF", "SCMDBUT.DEF", "SCLGBUT.DEF", "SCXLBUT.DEF", "SCALBUT.DEF"}; for(int i = 0; i < 5; i++) - new AdventureMapButton(CGI->generaltexth->zelp[54+i], bind(&SelectionTab::filter, this, sizes[i]), 161 + 47*i, 52, names[i]); + new AdventureMapButton("", CGI->generaltexth->zelp[54+i].second, bind(&SelectionTab::filter, this, sizes[i], true), 158 + 47*i, 46, names[i]); } { - int xpos[] = {26, 58, 91, 124, 309, 342}; + int xpos[] = {23, 55, 88, 121, 306, 339}; const char * names[] = {"SCBUTT1.DEF", "SCBUTT2.DEF", "SCBUTCP.DEF", "SCBUTT3.DEF", "SCBUTT4.DEF", "SCBUTT5.DEF"}; for(int i = 0; i < 6; i++) - new AdventureMapButton(CGI->generaltexth->zelp[107+i], bind(&SelectionTab::sortBy, this, i), xpos[i], 92, names[i]); + new AdventureMapButton("", CGI->generaltexth->zelp[107+i].second, bind(&SelectionTab::sortBy, this, i), xpos[i], 86, names[i]); } - slider = new CSlider(375, 92, 480, bind(&SelectionTab::sliderMove, this, _1), positions, curItems.size(), 0, false, 1); + slider = new CSlider(372, 86, type != saveGame ? 480 : 430, bind(&SelectionTab::sliderMove, this, _1), positions, curItems.size(), 0, false, 1); format = CDefHandler::giveDef("SCSELC.DEF"); sortingBy = _format; ascending = true; filter(0); - select(0); + //select(0); + switch(type) + { + case newGame: + selectFName("Maps/Arrogance.h3m"); + break; + case loadGame: + select(0); + break; + case saveGame:; + if(selectedName.size()) + { + if(selectedName[0] == 'M') + txt->setText("NEWGAME"); + else + selectFName("Games/" + selectedName + ".vlgm1"); + } + } } SelectionTab::~SelectionTab() @@ -526,6 +593,8 @@ void SelectionTab::sort() void SelectionTab::select( int position ) { + if(!curItems.size()) return; + // New selection. py is the index in curItems. int py = position + slider->value; amax(py, 0); @@ -539,9 +608,17 @@ void SelectionTab::select( int position ) else if(position >= positions) slider->moveTo(slider->value + position - positions + 1); + if(txt) + txt->setText(curItems[py]->filename.substr(6,curItems[py]->filename.size()-12)); + onSelect(curItems[py]); } +void SelectionTab::selectAbs( int position ) +{ + select(position - slider->value); +} + int SelectionTab::getPosition( int x, int y ) { return -1; @@ -661,15 +738,9 @@ void SelectionTab::showAll( SDL_Surface * to ) void SelectionTab::clickLeft( tribool down, bool previousState ) { - Point clickPos(GH.current->button.x, GH.current->button.y); - clickPos -= pos.topLeft(); - - if (clickPos.y > 115 && clickPos.y < 564 && clickPos.x > 52 && clickPos.x < 366) - { - int line = (clickPos.y-115) / 25; //which line + int line = getLine(); + if(line != -1) select(line); - - } } void SelectionTab::wheelScrolled( bool down, bool in ) @@ -703,34 +774,76 @@ void SelectionTab::keyPressed( const SDL_KeyboardEvent & key ) case SDLK_END: select(curItems.size() - slider->value); return; + default: + return; } select(selectionPos - slider->value + moveBy); } void SelectionTab::onDoubleClick() { - //act as start button was pressed - (static_cast(parent))->start->callback(); + if(getLine() != -1) //double clicked scenarios list + { + //act as start button was pressed + (static_cast(parent))->start->callback(); + } +} + +int SelectionTab::getLine() +{ + int line = -1; + Point clickPos(GH.current->button.x, GH.current->button.y); + clickPos -= pos.topLeft(); + + if (clickPos.y > 115 && clickPos.y < 564 && clickPos.x > 52 && clickPos.x < 366) + { + line = (clickPos.y-115) / 25; //which line + } + + return line; +} + +void SelectionTab::selectFName( const std::string &fname ) +{ + for(int i = curItems.size() - 1; i >= 0; i--) + { + if(curItems[i]->filename == fname) + { + slider->moveTo(i); + selectAbs(i); + return; + } + } + + selectAbs(0); } InfoCard::InfoCard( EState Type ) { OBJ_CONSTRUCTION; + pos.x += 393; used = RCLICK; sizes = CDefHandler::giveDef("SCNRMPSZ.DEF"); sFlags = CDefHandler::giveDef("ITGFLAGS.DEF"); type = Type; - bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 396, 6, true); - pos = bg->pos; + bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 0, 0, true); + pos.w = bg->pos.w; + pos.h = bg->pos.h; + difficulty = new CHighlightableButtonsGroup(0); { + static const char *difButns[] = {"GSPBUT3.DEF", "GSPBUT4.DEF", "GSPBUT5.DEF", "GSPBUT6.DEF", "GSPBUT7.DEF"}; BLOCK_CAPTURING; - difficulty->addButton(new CHighlightableButton(CGI->generaltexth->zelp[24], 0, 506, 456, "GSPBUT3.DEF", 0)); - difficulty->addButton(new CHighlightableButton(CGI->generaltexth->zelp[25], 0, 538, 456, "GSPBUT4.DEF", 1)); - difficulty->addButton(new CHighlightableButton(CGI->generaltexth->zelp[26], 0, 570, 456, "GSPBUT5.DEF", 2)); - difficulty->addButton(new CHighlightableButton(CGI->generaltexth->zelp[27], 0, 602, 456, "GSPBUT6.DEF", 3)); - difficulty->addButton(new CHighlightableButton(CGI->generaltexth->zelp[28], 0, 634, 456, "GSPBUT7.DEF", 4)); + + for(int i = 0; i < 5; i++) + { + difficulty->addButton(new CHighlightableButton("", CGI->generaltexth->zelp[24+i].second, 0, 110 + i*32, 450, difButns[i], i)); + difficulty->buttons.back()->pos += pos.topLeft(); + } } + + if(type != newGame) + difficulty->block(true); } InfoCard::~InfoCard() @@ -760,10 +873,10 @@ void InfoCard::showAll( SDL_Surface * to ) { for (int i = 0; i < difficulty->buttons.size(); i++) { - if(i == curMap->difficulty) - difficulty->buttons[i]->state = 3; - else - difficulty->buttons[i]->state = 2; + //if(i == curMap->difficulty) + // difficulty->buttons[i]->state = 3; + //else + // difficulty->buttons[i]->state = 2; difficulty->buttons[i]->showAll(to); } @@ -817,13 +930,13 @@ void InfoCard::showAll( SDL_Surface * to ) blitAtLoc(sizes->ourImages[temp].bitmap, 318, 22, to); temp = curMap->victoryCondition.condition; if (temp>12) temp=11; - blitAt(CGP->victory->ourImages[temp].bitmap, 420, 308, to); //vicotry cond descr + blitAtLoc(CGP->victory->ourImages[temp].bitmap, 24, 302, to); //vicotry cond descr temp=curMap->lossCondition.typeOfLossCon; if (temp>12) temp=3; - blitAt(CGP->loss->ourImages[temp].bitmap, 420, 365, to); //loss cond + blitAtLoc(CGP->loss->ourImages[temp].bitmap, 24, 359, to); //loss cond if(type == loadGame) - printToLoc(curMap->date,308,34, FONT_SMALL, zwykly, to); + printToLoc((static_cast(curMap))->date,308,34, FONT_SMALL, zwykly, to); //print flags int fx=64, ex=244, myT; @@ -839,7 +952,7 @@ void InfoCard::showAll( SDL_Surface * to ) } std::string tob; - switch (type != newGame ? curMap->seldiff : curOpts->difficulty) + switch (curOpts->difficulty) { case 0: tob="80%"; @@ -863,15 +976,15 @@ void InfoCard::showAll( SDL_Surface * to ) void InfoCard::changeSelection( const CMapInfo *to ) { - if(type == loadGame) - difficulty->select(curMap->seldiff, 0); + if(to/* && type != newGame*/) + difficulty->select(curOpts->difficulty, 0); GH.totalRedraw(); } void InfoCard::clickRight( tribool down, bool previousState ) { static const Rect flagArea(19, 397, 335, 23); - if(down && isItInLoc(flagArea, GH.current->motion.x, GH.current->motion.y)) + if(down && curMap && isItInLoc(flagArea, GH.current->motion.x, GH.current->motion.y)) showTeamsPopup(); } @@ -904,12 +1017,14 @@ void InfoCard::showTeamsPopup() } OptionsTab::OptionsTab( EState Type) +:type(Type) { OBJ_CONSTRUCTION; - bg = new CPicture(BitmapHandler::loadBitmap("ADVOPTBK.bmp"), 3, 6, true); + bg = new CPicture(BitmapHandler::loadBitmap("ADVOPTBK.bmp"), 0, 0, true); pos = bg->pos; - turnDuration = new CSlider(pos.x + 55, pos.y + 551, 194, bind(&OptionsTab::setTurnLength, this, _1), 1, 11, 11, true, 1); + if(type == newGame) + turnDuration = new CSlider(55, 551, 194, bind(&OptionsTab::setTurnLength, this, _1), 1, 11, 11, true, 1); } OptionsTab::~OptionsTab() @@ -1072,7 +1187,7 @@ void OptionsTab::nextBonus( int player, int dir ) redraw(); } -void OptionsTab::changeSelection( const CMapInfo *to ) +void OptionsTab::changeSelection( const CMapHeader *to ) { for(int i = 0; i < entries.size(); i++) { @@ -1132,18 +1247,21 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet "ADOPOPNL.bmp", "ADOPPPNL.bmp", "ADOPTPNL.bmp", "ADOPSPNL.bmp"}; bg = new CPicture(BitmapHandler::loadBitmap(bgs[s.color]), 0, 0, true); - btns[0] = new AdventureMapButton(CGI->generaltexth->zelp[132], bind(&OptionsTab::nextCastle, owner, s.serial, -1), 107, 5, "ADOPLFA.DEF"); - btns[1] = new AdventureMapButton(CGI->generaltexth->zelp[133], bind(&OptionsTab::nextCastle, owner, s.serial, +1), 168, 5, "ADOPRTA.DEF"); - btns[2] = new AdventureMapButton(CGI->generaltexth->zelp[148], bind(&OptionsTab::nextHero, owner, s.serial, -1), 183, 5, "ADOPLFA.DEF"); - btns[3] = new AdventureMapButton(CGI->generaltexth->zelp[149], bind(&OptionsTab::nextHero, owner, s.serial, +1), 244, 5, "ADOPRTA.DEF"); - btns[4] = new AdventureMapButton(CGI->generaltexth->zelp[164], bind(&OptionsTab::nextBonus, owner, s.serial, -1), 259, 5, "ADOPLFA.DEF"); - btns[5] = new AdventureMapButton(CGI->generaltexth->zelp[165], bind(&OptionsTab::nextBonus, owner, s.serial, +1), 320, 5, "ADOPRTA.DEF"); + if(owner->type == newGame) + { + btns[0] = new AdventureMapButton(CGI->generaltexth->zelp[132], bind(&OptionsTab::nextCastle, owner, s.serial, -1), 107, 5, "ADOPLFA.DEF"); + btns[1] = new AdventureMapButton(CGI->generaltexth->zelp[133], bind(&OptionsTab::nextCastle, owner, s.serial, +1), 168, 5, "ADOPRTA.DEF"); + btns[2] = new AdventureMapButton(CGI->generaltexth->zelp[148], bind(&OptionsTab::nextHero, owner, s.serial, -1), 183, 5, "ADOPLFA.DEF"); + btns[3] = new AdventureMapButton(CGI->generaltexth->zelp[149], bind(&OptionsTab::nextHero, owner, s.serial, +1), 244, 5, "ADOPRTA.DEF"); + btns[4] = new AdventureMapButton(CGI->generaltexth->zelp[164], bind(&OptionsTab::nextBonus, owner, s.serial, -1), 259, 5, "ADOPLFA.DEF"); + btns[5] = new AdventureMapButton(CGI->generaltexth->zelp[165], bind(&OptionsTab::nextBonus, owner, s.serial, +1), 320, 5, "ADOPRTA.DEF"); + } fixedHero = s.hero != -1; //if we doesn't start with "random hero" it must be fixed or none selectButtons(false); - if(curMap->players[s.color].canHumanPlay) + if(owner->type != scenarioInfo && curMap->players[s.color].canHumanPlay) { flag = new AdventureMapButton(CGI->generaltexth->zelp[180], bind(&OptionsTab::flagPressed, owner, s.serial), -43, 2, flags[s.color]); flag->hoverable = true; @@ -1168,6 +1286,9 @@ void OptionsTab::PlayerOptionsEntry::showAll( SDL_Surface * to ) void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero) { + if(type != newGame) + return; + if(!onlyHero && s.castle != -1) { btns[0]->disable(); @@ -1458,4 +1579,89 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState ) blitAt(getImg(), 104, 60, bmp); GH.pushInt(new CInfoPopup(bmp, true)); +} + +CScenarioInfo::CScenarioInfo( const CMapHeader *mapInfo, const StartInfo *startInfo ) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL; + + for(size_t i = 0; i < startInfo->playerInfos.size(); i++) + if(startInfo->playerInfos[i].human) + playerColor = startInfo->playerInfos[i].color; + + pos.w = 762; + pos.h = 584; + center(pos); + + curMap = mapInfo; + curOpts = (StartInfo*)startInfo; + + card = new InfoCard(scenarioInfo); + opt = new OptionsTab(scenarioInfo); + opt->changeSelection(0); + + card->difficulty->select(startInfo->difficulty, 0); + back = new AdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 584, 535, "SCNRBACK.DEF", SDLK_ESCAPE); +} + +CScenarioInfo::~CScenarioInfo() +{ +} + +CTextInput::CTextInput() +{ + bg = NULL; + used = 0; +} + +CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList &CB ) +:cb(CB) +{ + pos += Pos; + OBJ_CONSTRUCTION; + bg = new CPicture(bgName, bgOffset.x, bgOffset.y); + used = LCLICK | KEYBOARD; +} + +CTextInput::~CTextInput() +{ + +} + +void CTextInput::showAll( SDL_Surface * to ) +{ + CIntObject::showAll(to); + CSDL_Ext::printAt(text + "_", pos.x, pos.y, FONT_SMALL, zwykly, to); +} + +void CTextInput::clickLeft( tribool down, bool previousState ) +{ + //TODO + +} + +void CTextInput::keyPressed( const SDL_KeyboardEvent & key ) +{ + switch(key.keysym.sym) + { + case SDLK_BACKSPACE: + if(text.size()) + text.resize(text.size()-1); + break; + default: + char c = key.keysym.unicode; + if(std::isprint(c)) + text += c; + break; + } + redraw(); + cb(text); +} + +void CTextInput::setText( const std::string &nText, bool callCb ) +{ + text = nText; + redraw(); + if(callCb) + cb(text); } \ No newline at end of file diff --git a/client/CPreGame.h b/client/CPreGame.h index e71049cec..9e1d8d5fa 100644 --- a/client/CPreGame.h +++ b/client/CPreGame.h @@ -6,10 +6,9 @@ #include "../StartInfo.h" #include "CMessage.h" #include "../lib/map.h" -#include -#include #include #include "GUIBase.h" +#include "FunctionList.h" /* * CPreGame.h, part of VCMI engine @@ -22,14 +21,29 @@ */ struct CMusicHandler; -using boost::bind; -using boost::ref; enum EState { //where are we? - mainMenu, newGame, loadGame, ScenarioList, saveGame + mainMenu, newGame, loadGame, ScenarioList, saveGame, scenarioInfo }; +class CTextInput : public CIntObject +{ +public: + CPicture *bg; + std::string text; + CFunctionList cb; + + void setText(const std::string &nText, bool callCb = false); + + CTextInput(); + CTextInput(const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList &CB); + ~CTextInput(); + void showAll(SDL_Surface * to); + void clickLeft(tribool down, bool previousState); + void keyPressed(const SDL_KeyboardEvent & key); +}; + class CMenuScreen : public CIntObject { public: @@ -83,16 +97,21 @@ public: CDefHandler *format; + CTextInput *txt; + void getFiles(std::vector &out, const std::string &dirname, const std::string &ext); void parseMaps(std::vector &files, int start = 0, int threads = 1); void parseGames(std::vector &files); - void filter(int size); //0 - all + void filter(int size, bool selectFirst = false); //0 - all void select(int position); //position: <0 - positions> position on the screen + void selectAbs(int position); //position: absolute position in curItems vector int getPosition(int x, int y); //convert mouse coords to entry position; -1 means none void sliderMove(int slidPos); void sortBy(int criteria); void sort(); void printMaps(SDL_Surface *to); + int getLine(); + void selectFName(const std::string &fname); void showAll(SDL_Surface * to); void clickLeft(tribool down, bool previousState); @@ -135,6 +154,7 @@ public: void selectButtons(bool onlyHero = true); //hides unavailable buttons void showAll(SDL_Surface * to); }; + EState type; CPicture *bg; CSlider *turnDuration; @@ -148,7 +168,7 @@ public: void setTurnLength(int npos); void flagPressed(int player); - void changeSelection(const CMapInfo *to); + void changeSelection(const CMapHeader *to); OptionsTab(EState Type/*, StartInfo &Opts*/); ~OptionsTab(); void showAll(SDL_Surface * to); @@ -181,6 +201,17 @@ public: void difficultyChange(int to); }; +class CScenarioInfo : public CIntObject +{ +public: + AdventureMapButton *back; + InfoCard *card; + OptionsTab *opt; + + CScenarioInfo(const CMapHeader *mapInfo, const StartInfo *startInfo); + ~CScenarioInfo(); +}; + class CGPreGame : public CIntObject { public: diff --git a/client/GUIBase.cpp b/client/GUIBase.cpp index 76e6f9bd3..5817446af 100644 --- a/client/GUIBase.cpp +++ b/client/GUIBase.cpp @@ -6,6 +6,7 @@ #include #include "CGameInfo.h" #include "CCursorHandler.h" +#include "CBitmapHandler.h" /* * GUIBase.cpp, part of VCMI engine * @@ -620,6 +621,20 @@ void CIntObject::onDoubleClick() { } +const Rect & CIntObject::center( const Rect &r ) +{ + pos.w = r.w; + pos.h = r.h; + pos.x = screen->w/2 - r.w/2; + pos.y = screen->h/2 - r.h/2; + return pos; +} + +const Rect & CIntObject::center() +{ + return center(pos); +} + CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free ) { bg = BG; @@ -630,6 +645,16 @@ CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free ) pos.h = BG->h; } +CPicture::CPicture( const std::string &bmpname, int x, int y ) +{ + bg = BitmapHandler::loadBitmap(bmpname); + freeSurf = true;; + pos.x += x; + pos.y += y; + pos.w = bg->w; + pos.h = bg->h; +} + CPicture::~CPicture() { if(freeSurf) @@ -656,15 +681,18 @@ ObjectConstruction::~ObjectConstruction() GH.captureChildren = GH.createdObj.size(); } -BlockCapture::BlockCapture() +SetCaptureState::SetCaptureState(bool allow, ui8 actions) { - previous = GH.captureChildren; + previousCapture = GH.captureChildren; GH.captureChildren = false; + prevActions = GH.defActionsDef; + GH.defActionsDef = actions; } -BlockCapture::~BlockCapture() +SetCaptureState::~SetCaptureState() { - GH.captureChildren = previous; + GH.captureChildren = previousCapture; + GH.defActionsDef = prevActions; } void IShowable::redraw() diff --git a/client/GUIBase.h b/client/GUIBase.h index 3dec3118c..3f6753511 100644 --- a/client/GUIBase.h +++ b/client/GUIBase.h @@ -263,7 +263,7 @@ public: class IShowActivable : public IShowable, public IActivable { public: - enum {WITH_GARRISON = 1}; + enum {WITH_GARRISON = 1, BLOCK_ADV_HOTKEYS = 2}; int type; //bin flags using etype IShowActivable(); virtual ~IShowActivable(){}; //d-tor @@ -353,6 +353,8 @@ public: void blitAtLoc(SDL_Surface * src, int x, int y, SDL_Surface * dst); bool isItInLoc(const SDL_Rect &rect, int x, int y); bool isItInLoc(const SDL_Rect &rect, const Point &p); + const Rect & center(const Rect &r); //sets pos so that r will be in the center of screen, returns new position + const Rect & center(); //centers when pos.w and pos.h are set, returns new position }; //class for binding keys to left mouse button clicks @@ -392,7 +394,8 @@ public: SDL_Surface *bg; bool freeSurf; - CPicture(SDL_Surface *BG, int x, int y, bool Free); + CPicture(SDL_Surface *BG, int x, int y, bool Free = true); + CPicture(const std::string &bmpname, int x, int y); ~CPicture(); void showAll(SDL_Surface * to); }; @@ -448,14 +451,16 @@ struct ObjectConstruction ~ObjectConstruction(); }; -struct BlockCapture +struct SetCaptureState { - bool previous; - BlockCapture(); - ~BlockCapture(); + bool previousCapture; + ui8 prevActions; + SetCaptureState(bool allow, ui8 actions); + ~SetCaptureState(); }; #define OBJ_CONSTRUCTION ObjectConstruction obj__i(this) -#define BLOCK_CAPTURING BlockCapture obj__i +#define OBJ_CONSTRUCTION_CAPTURING_ALL defActions = 255; SetCaptureState obj__i1(true, 255); ObjectConstruction obj__i(this) +#define BLOCK_CAPTURING SetCaptureState obj__i(false, 0) #endif //__GUIBASE_H__ diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 25e440b3f..314d79117 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -2576,6 +2576,7 @@ void CMarketplaceWindow::clear() CMarketplaceWindow::CMarketplaceWindow(int Mode) { + type = BLOCK_ADV_HOTKEYS; mode = Mode; bg = NULL; ok = max = deal = NULL; @@ -3116,13 +3117,14 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key) switch(key.keysym.sym) { case SDLK_TAB: + case SDLK_ESCAPE: { if(captureAllKeys) { captureAllKeys = false; endEnteringText(false); } - else + else if(SDLK_TAB) { captureAllKeys = true; startEnteringText(); diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index f1d3718b0..6948417b8 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1090,7 +1090,11 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) break; if(j == scenarioOps->playerInfos.size()) continue; + int h=pickHero(i); + if(scenarioOps->playerInfos[j].hero == -1) + scenarioOps->playerInfos[j].hero = h; + CGHeroInstance * nnn = static_cast(createObject(HEROI_TYPE,h,hpos,i)); nnn->id = map->objects.size(); hpos = map->players[i].posOfMainTown;hpos.x+=2; diff --git a/lib/map.cpp b/lib/map.cpp index ef21943ab..e11990532 100644 --- a/lib/map.cpp +++ b/lib/map.cpp @@ -256,6 +256,13 @@ void CMapHeader::initFromMemory( unsigned char *bufor, int &i ) players[rr].team = bufor[i++]; } } + else//no alliances + { + for(int i=0;i void serialize(Handler &h, const int Version)