diff --git a/CMT.cpp b/CMT.cpp index e7d0813a9..539746fe6 100644 --- a/CMT.cpp +++ b/CMT.cpp @@ -58,9 +58,11 @@ #else # define SET_BINARY_MODE(file) #endif - +#ifdef _DEBUG +CGameInfo* CGI; +#endif #define CHUNK 16384 -const char * NAME = "VCMI 0.52 \"Tirion\" Techdemo"; +const char * NAME = "VCMI 0.53 \"Tirion\" Techdemo"; SDL_Surface * ekran, * screen, * screen2; extern SDL_Surface * CSDL_Ext::std32bppSurface; @@ -353,7 +355,10 @@ int _tmain(int argc, _TCHAR* argv[]) SDL_WM_SetCaption(NAME,""); //set window title CGameInfo * cgi = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler itp.) - CGameInfo::mainObj = cgi; + CGameInfo::mainObj = cgi; + #ifdef _DEBUG + CGI = cgi; + #endif cgi->consoleh = new CConsoleHandler; cgi->mush = mush; cgi->curh = new CCursorHandler; @@ -761,16 +766,6 @@ int _tmain(int argc, _TCHAR* argv[]) } std::cout<<"done."<scenarioOps.playerInfos.size();pru++) - { - if(cgi->scenarioOps.playerInfos[pru].castle<0) - cgi->scenarioOps.playerInfos[pru].castle = rand()%F_NUMBER; - if(cgi->scenarioOps.playerInfos[pru].hero<0) - cgi->scenarioOps.playerInfos[pru].hero= cgi->scenarioOps.playerInfos[pru].castle*HEROES_PER_TYPE*2+(rand()%(HEROES_PER_TYPE*2));//cgi->scenarioOps.playerInfos[pru].hero = cgi-> - } - - - #define CHOOSE #ifdef CHOOSE CAmbarCendamo * ac = new CAmbarCendamo(initTable); //4gryf diff --git a/CPreGame.cpp b/CPreGame.cpp index 06708c117..f803175fe 100644 Binary files a/CPreGame.cpp and b/CPreGame.cpp differ diff --git a/CPreGame.h b/CPreGame.h index 92e8bb68e..924653271 100644 --- a/CPreGame.h +++ b/CPreGame.h @@ -1,5 +1,7 @@ #ifndef CPREGAME_H #define CPREGAME_H +#include "global.h" +#include #include "SDL.h" #include "StartInfo.h" #include "hch\CSemiDefHandler.h" @@ -156,6 +158,7 @@ class Options : public PreGameTab int nr; }; public: + std::set usedHeroes; Slider<> * turnLength; SDL_Surface * bg, * rHero, * rCastle, * nHero, * nCastle; @@ -169,6 +172,8 @@ public: void hide(); void init(); void showIcon (int what, int nr, bool abs); //what: -1=castle, 0=hero, 1=bonus, 2=all; abs=true -> nr is absolute + bool canUseThisHero(int ID); + int nextAllowedHero(int min, int max, int incl, int dir); //incl 0 - wlacznie; incl 1 - wylacznie; min-max - zakres szukania Options(){inited=showed=false;}; ~Options(); }; diff --git a/global.h b/global.h index ddaadc653..c8c96a621 100644 --- a/global.h +++ b/global.h @@ -22,7 +22,12 @@ enum EHeroClasses {HERO_KNIGHT, HERO_CLERIC, HERO_RANGER, HERO_DRUID, HERO_ALCHE HERO_DEMONIAC, HERO_HERETIC, HERO_DEATHKNIGHT, HERO_NECROMANCER, HERO_WARLOCK, HERO_OVERLORD, HERO_BARBARIAN, HERO_BATTLEMAGE, HERO_BEASTMASTER, HERO_WITCH, HERO_PLANESWALKER, HERO_ELEMENTALIST}; +#ifdef _DEBUG +class CGameInfo; +extern CGameInfo* CGI; +#else #define CGI (CGameInfo::mainObj) +#endif #define CURPLINT (((CPlayerInterface*)((CGameInfo::mainObj)->playerint[(CGameInfo::mainObj)->state->currentPlayer]))) #define LOCPLINT (((CPlayerInterface*)((CGameInfo::mainObj)->playerint[(CGameInfo::mainObj)->localPlayer]))) //CURPLINT gives pointer to the interface of human player which is currently making turn, @@ -60,6 +65,7 @@ const int MAX_BUILDING_PER_TURN = 1; #define DEFBYPASS + #define HANDLE_EXCEPTION \ catch (const std::exception& e) { \ std::cerr << e.what() << std::endl; \ diff --git a/hch/CAmbarCendamo.cpp b/hch/CAmbarCendamo.cpp index b67ef85a2..cac150ddb 100644 --- a/hch/CAmbarCendamo.cpp +++ b/hch/CAmbarCendamo.cpp @@ -210,6 +210,12 @@ void CAmbarCendamo::deh3m() map.players[pom].generateHeroAtMainTown = bufor[i++]; map.players[pom].generateHero = bufor[i++]; } + else + { + map.players[pom].generateHeroAtMainTown = false; + map.players[pom].generateHero = false; + } + map.players[pom].posOfMainTown.x = bufor[i++]; map.players[pom].posOfMainTown.y = bufor[i++]; map.players[pom].posOfMainTown.z = bufor[i++]; @@ -1824,7 +1830,9 @@ void CAmbarCendamo::deh3m() spec->spells.push_back(&(CGameInfo::mainObj->spellh->spells[readNormalNr(i, 1)])); ++i; } int gcre = readNormalNr(i, 1); ++i; //number of gained creatures - spec->creatures = readCreatureSet(i, gcre); i+=4*gcre; + spec->creatures = readCreatureSet(i, gcre); i+=3*gcre; + if(map.version > RoE) + i+=gcre; i+=8; nobj->info = spec; ///////end of copied fragment diff --git a/hch/CCastleHandler.h b/hch/CCastleHandler.h index dd026a9c6..e397357bd 100644 --- a/hch/CCastleHandler.h +++ b/hch/CCastleHandler.h @@ -45,7 +45,7 @@ public: std::vector events; - unsigned char alignment; //what the hell is that?? + unsigned char alignment; //255 - same as owner/random, 0 - same as red, 1 - same as blue, etc }; #endif //CCASTLEHANDLER_H \ No newline at end of file diff --git a/mapHandler.cpp b/mapHandler.cpp index 79bfe2374..d7d320021 100644 --- a/mapHandler.cpp +++ b/mapHandler.cpp @@ -38,6 +38,30 @@ void alphaTransformDef(CGDefInfo * defInfo) } SDL_FreeSurface(alphaTransSurf); } +int CMapHandler::pickHero(int owner) +{ + if(usedHeroes.find(CGI->scenarioOps.getIthPlayersSettings(owner).hero)==usedHeroes.end()) //we haven't used selected hero + { + int h = CGI->scenarioOps.getIthPlayersSettings(owner).hero; + usedHeroes.insert(h); + return h; + } + int f = CGI->scenarioOps.getIthPlayersSettings(owner).castle; + int i=0, h; + do //try to find free hero of our faction + { + i++; + h = CGI->scenarioOps.getIthPlayersSettings(owner).castle*HEROES_PER_TYPE*2+(rand()%(HEROES_PER_TYPE*2));//cgi->scenarioOps.playerInfos[pru].hero = cgi-> + } while((usedHeroes.find(h)!=usedHeroes.end()) && i<175); + if(i>174) //probably no free heroes - there's no point in further search, we'll take first free + { + for(int j=0; j CMapHandler::pickObject(CGObjectInstance *obj) { switch(obj->ID) @@ -53,7 +77,9 @@ std::pair CMapHandler::pickObject(CGObjectInstance *obj) case 69: //random relic artifact return std::pair(5,CGI->arth->relics[rand()%CGI->arth->relics.size()]->id); case 70: //random hero - return std::pair(34,rand()%CGI->heroh->heroes.size()); + { + return std::pair(34,pickHero(obj->tempOwner)); + } case 71: //random monster return std::pair(54,rand()%(CGI->creh->creatures.size())); case 72: //random monster lvl1 @@ -67,7 +93,23 @@ std::pair CMapHandler::pickObject(CGObjectInstance *obj) case 76: //random resource return std::pair(79,rand()%7); //now it's OH3 style, use %8 for mithril case 77: //random town - return std::pair(98,rand()%CGI->townh->towns.size()); + { + int align = ((CCastleObjInfo*)obj->info)->alignment, + f; + if(align>PLAYER_LIMIT-1)//same as owner / random + { + if(obj->tempOwner > PLAYER_LIMIT-1) + f = -1; //random + else + f = CGI->scenarioOps.getIthPlayersSettings(obj->tempOwner).castle; + } + else + { + f = CGI->scenarioOps.getIthPlayersSettings(align).castle; + } + if(f<0) f = rand()%CGI->townh->towns.size(); + return std::pair(98,f); + } case 162: //random monster lvl5 return std::pair(54,CGI->creh->levelCreatures[5][rand()%CGI->creh->levelCreatures[5].size()]->idNumber); case 163: //random monster lvl6 @@ -704,6 +746,7 @@ void CMapHandler::calculateBlockedPos() } void CMapHandler::init() { + //loading castles' defs std::ifstream ifs("config/townsDefs.txt"); int ccc; ifs>>ccc; @@ -720,9 +763,29 @@ void CMapHandler::init() alphaTransformDef(n); } + for(int i=0;iscenarioOps.playerInfos.size();i++) + { + if(CGI->scenarioOps.playerInfos[i].castle==-1) + { + int f; + do + { + f = rand()%F_NUMBER; + }while(!(reader->map.players[CGI->scenarioOps.playerInfos[i].color].allowedFactions & 1<scenarioOps.playerInfos[i].castle = f; + } + } + for(int i=0;imap.players[i].heroesNames.size();j++) + { + usedHeroes.insert(reader->map.players[i].heroesNames[j].heroID); + } + } + + timeHandler th; th.getDif(); - randomizeObjects();//randomizing objects on map std::cout<<"\tRandomizing objects: "<scenarioOps.playerInfos.size()) continue; - CGHeroInstance * nnn = (CGHeroInstance*)createObject(34,CGI->scenarioOps.playerInfos[j].hero,hpos,i); + int h = CGI->scenarioOps.playerInfos[j].hero; + if(h<0) + h=pickHero(i); + CGHeroInstance * nnn = (CGHeroInstance*)createObject(34,h,hpos,i); nnn->defInfo->handler = CGI->heroh->flags1[0]; CGI->heroh->heroInstances.push_back(nnn); CGI->objh->objInstances.push_back(nnn); @@ -1339,14 +1405,14 @@ CGObjectInstance * CMapHandler::createObject(int id, int subid, int3 pos, int ow nobj->type = CGI->heroh->heroes[subid]; for(int i=0;i<6;i++) { - nobj->defInfo->blockMap[i]=1; + nobj->defInfo->blockMap[i]=255; nobj->defInfo->visitMap[i]=0; } nobj->ID = id; nobj->subID = subid; nobj->defInfo->handler=NULL; - nobj->defInfo->blockMap[5] = 0x7f; - nobj->defInfo->visitMap[5] = 0x80; + nobj->defInfo->blockMap[5] = 253; + nobj->defInfo->visitMap[5] = 2; nobj->artifWorn.resize(20); nobj->artifacts.resize(20); nobj->artifWorn[16] = &CGI->arth->artifacts[3]; diff --git a/mapHandler.h b/mapHandler.h index 8de2c54f6..eba85f0ac 100644 --- a/mapHandler.h +++ b/mapHandler.h @@ -62,7 +62,7 @@ public: PseudoV< PseudoV< PseudoV > > ttiles; int3 sizes; CAmbarCendamo * reader; - + std::set usedHeroes; CDefHandler * fullHide; CDefHandler * partialHide; @@ -92,6 +92,7 @@ public: bool recalculateHideVisPos(int3& pos); //recalculates position for hidden / visitable positions bool recalculateHideVisPosUnderObj(CGObjectInstance * obj, bool withBorder = false); //recalculates position for hidden / visitable positions under given object void init(); + int pickHero(int owner); std::pair pickObject(CGObjectInstance *obj); void randomizeObject(CGObjectInstance *cur); void calculateBlockedPos();