diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index c3a5f22bd..72f65af24 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -2289,6 +2289,8 @@ void CBonusSelection::showAll( SDL_Surface * to ) { CIntObject::showAll(to); blitAt(background, pos.x, pos.y, to); + + show(to); } void CBonusSelection::loadPositionsOfGraphics() @@ -2333,7 +2335,7 @@ void CBonusSelection::selectMap( int whichOne ) int i = 0; delete ourHeader; ourHeader = new CMapHeader(); - ourHeader->initFromMemory((const unsigned char*)ourCampaign->mapPieces[whichOne].c_str(), i); + ourHeader->initFromMemory((const unsigned char*)ourCampaign->mapPieces.find(whichOne)->second.c_str(), i); CMapInfo *mapInfo = const_cast(curMap); mapInfo->mapHeader = ourHeader; mapInfo->countPlayers(); @@ -2490,7 +2492,35 @@ void CBonusSelection::updateBonusSelection() break; case 7: //resource - //TODO + { + int serialResID = 0; + switch(bonDescs[i].info1) + { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: + serialResID = bonDescs[i].info1; + break; + case 0xFD: //wood + ore + serialResID = 7; + break; + case 0xFE: //rare resources + serialResID = 8; + break; + } + surfToDuplicate = de->ourImages[serialResID].bitmap; + + desc = CGI->generaltexth->allTexts[717]; + boost::algorithm::replace_first(desc, "%d", boost::lexical_cast(bonDescs[i].info2)); + std::string replacement; + if (serialResID <= 6) + { + replacement = CGI->generaltexth->restypes[serialResID]; + } + else + { + replacement = CGI->generaltexth->allTexts[714 + serialResID]; + } + boost::algorithm::replace_first(desc, "%s", replacement); + } break; case 8: //player //TODO @@ -2517,8 +2547,10 @@ void CBonusSelection::updateBonusSelection() delete de; } } - - bonuses->select(0, 0); + if (bonDescs.size() > 0) + { + bonuses->select(0, 0); + } delete twcp; diff --git a/hch/CCampaignHandler.cpp b/hch/CCampaignHandler.cpp index 4c8e7741c..05a2bac95 100644 --- a/hch/CCampaignHandler.cpp +++ b/hch/CCampaignHandler.cpp @@ -100,26 +100,34 @@ CCampaign * CCampaignHandler::getCampaign( const std::string & name, bool fromLo std::vector h3mStarts = locateH3mStarts(cmpgn, it, realSize); assert(h3mStarts.size() <= howManyScenarios); - //it looks like we can have less scenarios than we should.. - //if(h3mStarts.size() != howManyScenarios) - //{ - // tlog1<<"Our heuristic for h3m start points gave wrong results for campaign " << name < howManyScenarios) + { + tlog1<<"Our heuristic for h3m start points gave wrong results for campaign " << name <scenarios[scenarioID].isNotVoid()) //skip void scenarios + { + scenarioID++; + } + //set map piece appropriately if(g == h3mStarts.size() - 1) { - ret->mapPieces.push_back(std::string( cmpgn + h3mStarts[g], cmpgn + realSize )); + ret->mapPieces[scenarioID] = std::string( cmpgn + h3mStarts[g], cmpgn + realSize ); } else { - ret->mapPieces.push_back(std::string( cmpgn + h3mStarts[g], cmpgn + h3mStarts[g+1] )); + ret->mapPieces[scenarioID] = std::string( cmpgn + h3mStarts[g], cmpgn + h3mStarts[g+1] ); } + scenarioID++; } delete [] cmpgn; @@ -423,6 +431,12 @@ unsigned char * CCampaignHandler::getFile( const std::string & name, bool fromLo bool CCampaign::conquerable( int whichScenario ) const { + //check for void scenraio + if (!scenarios[whichScenario].isNotVoid()) + { + return false; + } + if (scenarios[whichScenario].conquered) { return false; @@ -440,4 +454,9 @@ bool CCampaign::conquerable( int whichScenario ) const CCampaign::CCampaign() { -} \ No newline at end of file +} + +bool CCampaignScenario::isNotVoid() const +{ + return mapName.size() > 0; +} diff --git a/hch/CCampaignHandler.h b/hch/CCampaignHandler.h index 977e09a77..c9be3328c 100644 --- a/hch/CCampaignHandler.h +++ b/hch/CCampaignHandler.h @@ -94,6 +94,8 @@ public: CScenarioTravel travelOptions; + bool isNotVoid() const; + template void serialize(Handler &h, const int formatVersion) { h & mapName & packedMapSize & preconditionRegion & regionColor & difficulty & conquered & regionText & @@ -106,7 +108,7 @@ class DLL_EXPORT CCampaign public: CCampaignHeader header; std::vector scenarios; - std::vector mapPieces; //binary h3ms + std::map mapPieces; //binary h3ms, scenario number -> map data template void serialize(Handler &h, const int formatVersion) { diff --git a/hch/CGeneralTextHandler.h b/hch/CGeneralTextHandler.h index 25a8c1238..9c48389e7 100644 --- a/hch/CGeneralTextHandler.h +++ b/hch/CGeneralTextHandler.h @@ -59,7 +59,7 @@ public: std::vector creGens4; //names of multiple creatures' generators std::vector advobtxt; std::vector xtrainfo; - std::vector restypes; + std::vector restypes; //names of resources std::vector terrainNames; std::vector randsign; std::vector > mines; //first - name; second - event description diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index d785435c9..89d656c01 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -3090,6 +3090,11 @@ int CGameState::victoryCheck( ui8 player ) const if(player == checkForStandardWin()) return -1; + if (p->enteredWinningCheatCode) + { //cheater or tester, but has entered the code... + return 1; + } + if(p->human || map->victoryCondition.appliesToAI) { switch(map->victoryCondition.condition) @@ -3428,6 +3433,11 @@ int CGameState::lossCheck( ui8 player ) const if(checkForStandardLoss(player)) return -1; + if (p->enteredLosingCheatCode) + { + return 1; + } + if(p->human) //special loss condition applies only to human player { switch(map->lossCondition.typeOfLossCon) @@ -3879,7 +3889,8 @@ CMP_stack::CMP_stack( int Phase /*= 1*/, int Turn ) } PlayerState::PlayerState() - : color(-1), currentSelection(0xffffffff), status(INGAME), daysWithoutCastle(0) + : color(-1), currentSelection(0xffffffff), status(INGAME), daysWithoutCastle(0), + enteredLosingCheatCode(0), enteredWinningCheatCode(0) { } @@ -3979,7 +3990,10 @@ void CCampaignState::initNewCampaign( const StartInfo &si ) campaignName = si.mapname; currentMap = si.whichMapInCampaign; - camp = CCampaignHandler::getCampaign(campaignName, true); //TODO lod??? + //check if campaign is in lod or not + bool inLod = campaignName.find('/') == std::string::npos; + + camp = CCampaignHandler::getCampaign(campaignName, inLod); //TODO lod??? for (ui8 i = 0; i < camp->mapPieces.size(); i++) mapsRemaining.push_back(i); } diff --git a/lib/CGameState.h b/lib/CGameState.h index 89d047aa6..f03e28ef2 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -127,6 +127,7 @@ public: std::vector availableHeroes; //heroes available in taverns std::vector dwellings; //used for town growth + ui8 enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory ui8 status; //0 - in game, 1 - loser, 2 - winner <- uses EStatus enum ui8 daysWithoutCastle; @@ -140,6 +141,7 @@ public: { h & color & serial & human & currentSelection & fogOfWarMap & resources & status; h & heroes & towns & availableHeroes & dwellings & bonuses & status & daysWithoutCastle; + h & enteredLosingCheatCode & enteredWinningCheatCode; h & static_cast(*this); } }; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 9303cd6c3..6560b1ec2 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -3898,11 +3898,21 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message ) fc.tiles.insert(int3(i,j,k)); sendAndApply(&fc); } - else if(message == "vcmiglorfindel") + else if(message == "vcmiglorfindel") //selected hero gains a new level { CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection); changePrimSkill(hero->id,4,VLC->heroh->reqExp(hero->level+1) - VLC->heroh->reqExp(hero->level)); } + else if(message == "vcmisilmaril") //player wins + { + gs->getPlayer(player)->enteredWinningCheatCode = 1; + checkLossVictory(player); + } + else if(message == "vcmimelkor") //player looses + { + gs->getPlayer(player)->enteredLosingCheatCode = 1; + checkLossVictory(player); + } else cheated = false; if(cheated)