From 720deba838f2048e7e47cee55c85365e77cb38f5 Mon Sep 17 00:00:00 2001 From: beegee1 Date: Fri, 26 Oct 2012 17:51:05 +0000 Subject: [PATCH] * Added comments to map.h * Refactoring(renamed attributes, some steps towards coding guidelines, ..) --- AI/VCAI/VCAI.cpp | 2 +- client/CAdvmapInterface.cpp | 2 +- client/CGameInfo.h | 4 +- client/CMusicHandler.cpp | 2 +- client/CPlayerInterface.cpp | 4 +- client/CPreGame.cpp | 10 +- client/mapHandler.cpp | 40 +- client/mapHandler.h | 4 +- lib/CGameState.cpp | 62 +-- lib/CGameState.h | 6 +- lib/CMapInfo.cpp | 2 +- lib/CObjectHandler.cpp | 14 +- lib/IGameCallback.cpp | 8 +- lib/map.cpp | 962 ++++++++++++++++---------------- lib/map.h | 1036 ++++++++++++++++++++++++++--------- server/CGameHandler.cpp | 10 +- 16 files changed, 1364 insertions(+), 804 deletions(-) diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 8c9017db5..c79b34037 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -2737,7 +2737,7 @@ TSubgoal CGoal::whatToDoToAchieve() { case WIN: { - const CVictoryCondition &vc = cb->getMapHeader()->victoryCondition; + const VictoryCondition &vc = cb->getMapHeader()->victoryCondition; EVictoryConditionType::EVictoryConditionType cond = vc.condition; if(!vc.appliesToAI) diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index f6d793bf9..f3da8fdbf 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -1385,7 +1385,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) { if(pnode->land) { - if(LOCPLINT->cb->getTile(h->getPosition(false))->tertype != TerrainTile::water) + if(LOCPLINT->cb->getTile(h->getPosition(false))->tertype != ETerrainType::WATER) CCS->curh->changeGraphic(0, 4 + turns*6); else CCS->curh->changeGraphic(0, 7 + turns*6); //anchor diff --git a/client/CGameInfo.h b/client/CGameInfo.h index 681bef28a..6e16d250f 100644 --- a/client/CGameInfo.h +++ b/client/CGameInfo.h @@ -44,7 +44,7 @@ public: }; extern CClientState * CCS; -struct Mapa; +struct CMap; /// CGameInfo class /// for allowing different functions for accessing game informations @@ -67,7 +67,7 @@ public: void setFromLib(); friend class CClient; - friend void initVillagesCapitols(Mapa * map); + friend void initVillagesCapitols(CMap * map); CGameInfo(); }; diff --git a/client/CMusicHandler.cpp b/client/CMusicHandler.cpp index 4f2939053..0aa98f85b 100644 --- a/client/CMusicHandler.cpp +++ b/client/CMusicHandler.cpp @@ -87,7 +87,7 @@ CSoundHandler::CSoundHandler(): pickupSounds += soundBase::pickup01, soundBase::pickup02, soundBase::pickup03, soundBase::pickup04, soundBase::pickup05, soundBase::pickup06, soundBase::pickup07; - horseSounds += // must be the same order as terrains (see EterrainType); + horseSounds += // must be the same order as terrains (see ETerrainType); soundBase::horseDirt, soundBase::horseSand, soundBase::horseGrass, soundBase::horseSnow, soundBase::horseSwamp, soundBase::horseRough, soundBase::horseSubterranean, soundBase::horseLava, diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 5ce09b11c..03dffbdb5 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1223,8 +1223,8 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path ) boost::unique_lock un(stillMoveHero.mx); stillMoveHero.data = CONTINUE_MOVE; - enum TerrainTile::EterrainType currentTerrain = TerrainTile::border; // not init yet - enum TerrainTile::EterrainType newTerrain; + enum ETerrainType::ETerrainType currentTerrain = ETerrainType::BORDER; // not init yet + enum ETerrainType::ETerrainType newTerrain; int sh = -1; const TerrainTile * curTile = cb->getTile(CGHeroInstance::convertPosition(h->pos, false)); diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index 9a2824c1a..ca1f0f320 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -1048,7 +1048,7 @@ void SelectionTab::parseMaps(const std::vector &files, int start, in { try { - TInputStreamPtr stream(Mapa::getMapStream(files[start].getName())); + TInputStreamPtr stream(CMap::getMapStream(files[start].getName())); int read = stream->read(mapBuffer, 1500); if(read < 50 || !mapBuffer[4]) @@ -1360,16 +1360,16 @@ void SelectionTab::printMaps(SDL_Surface *to) int temp=-1; switch (currentItem->mapHeader->version) { - case CMapHeader::RoE: + case EMapFormat::ROE: temp=0; break; - case CMapHeader::AB: + case EMapFormat::AB: temp=1; break; - case CMapHeader::SoD: + case EMapFormat::SOD: temp=2; break; - case CMapHeader::WoG: + case EMapFormat::WOG: temp=3; break; default: diff --git a/client/mapHandler.cpp b/client/mapHandler.cpp index 985ba6543..35d6a8552 100644 --- a/client/mapHandler.cpp +++ b/client/mapHandler.cpp @@ -34,39 +34,39 @@ extern SDL_Surface * screen; std::string nameFromType (int typ) { - switch(static_cast(typ)) + switch(static_cast(typ)) { - case TerrainTile::dirt: + case ETerrainType::DIRT: return std::string("DIRTTL.DEF"); - case TerrainTile::sand: + case ETerrainType::SAND: return std::string("SANDTL.DEF"); - case TerrainTile::grass: + case ETerrainType::GRASS: return std::string("GRASTL.DEF"); - case TerrainTile::snow: + case ETerrainType::SNOW: return std::string("SNOWTL.DEF"); - case TerrainTile::swamp: + case ETerrainType::SWAMP: return std::string("SWMPTL.DEF"); - case TerrainTile::rough: + case ETerrainType::ROUGH: return std::string("ROUGTL.DEF"); - case TerrainTile::subterranean: + case ETerrainType::SUBTERRANEAN: return std::string("SUBBTL.DEF"); - case TerrainTile::lava: + case ETerrainType::LAVA: return std::string("LAVATL.DEF"); - case TerrainTile::water: + case ETerrainType::WATER: return std::string("WATRTL.DEF"); - case TerrainTile::rock: + case ETerrainType::ROCK: return std::string("ROCKTL.DEF"); - case TerrainTile::border: + case ETerrainType::BORDER: //TODO use me break; default: @@ -378,7 +378,7 @@ void CMapHandler::init() } } - std::for_each(map->defy.begin(),map->defy.end(),processDef); //load h3m defs + std::for_each(map->customDefs.begin(),map->customDefs.end(),processDef); //load h3m defs tlog0<<"\tUnpacking and handling defs: "<ourImages[tinfo.rivDir].bitmap,rtile, extSurf, sr, (tinfo.siodmyTajemniczyBajt>>2)%4); + blitterWithRotationAndAlpha(staticRiverDefs[tinfo.riverType-1]->ourImages[tinfo.riverDir].bitmap,rtile, extSurf, sr, (tinfo.extTileFlags>>2)%4); } //Roads are shifted by 16 pixels to bottom. We have to draw both parts separately - if (pos.y > 0 && map->terrain[pos.x][pos.y-1][pos.z].malle) + if (pos.y > 0 && map->terrain[pos.x][pos.y-1][pos.z].roadType) { //part from top tile const TerrainTile &topTile = map->terrain[pos.x][pos.y-1][pos.z]; Rect source(0, 16, 32, 16); Rect dest(sr.x, sr.y, sr.w, sr.h/2); - blitterWithRotationAndAlpha(roadDefs[topTile.malle-1]->ourImages[topTile.roadDir].bitmap, source, extSurf, dest, (topTile.siodmyTajemniczyBajt>>4)%4); + blitterWithRotationAndAlpha(roadDefs[topTile.roadType-1]->ourImages[topTile.roadDir].bitmap, source, extSurf, dest, (topTile.extTileFlags>>4)%4); } - if(tinfo.malle) //print road from this tile + if(tinfo.roadType) //print road from this tile { Rect source(0, 0, 32, 32); Rect dest(sr.x, sr.y+16, sr.w, sr.h/2); - blitterWithRotationAndAlpha(roadDefs[tinfo.malle-1]->ourImages[tinfo.roadDir].bitmap, source, extSurf, dest, (tinfo.siodmyTajemniczyBajt>>4)%4); + blitterWithRotationAndAlpha(roadDefs[tinfo.roadType-1]->ourImages[tinfo.roadDir].bitmap, source, extSurf, dest, (tinfo.extTileFlags>>4)%4); } //blit objects diff --git a/client/mapHandler.h b/client/mapHandler.h index d0e823495..d177844ba 100644 --- a/client/mapHandler.h +++ b/client/mapHandler.h @@ -15,7 +15,7 @@ class CGObjectInstance; class CGHeroInstance; -struct Mapa; +struct CMap; class CGDefInfo; class CGObjectInstance; class CDefHandler; @@ -73,7 +73,7 @@ class CMapHandler public: PseudoV< PseudoV< PseudoV > > ttiles; //informations about map tiles int3 sizes; //map size (x = width, y = height, z = number of levels) - const Mapa * map; + const CMap * map; // Max number of tiles that will fit in the map screen. Tiles // can be partial on each edges. diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index be2f22211..6f0411103 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -465,7 +465,7 @@ int CGameState::pickHero(int owner) { int h=-1; const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner); - if(!map->getHero(h = ps.hero,0) && h>=0) //we haven't used selected hero + if(!map->getHero(h = ps.hero) && h>=0) //we haven't used selected hero return h; if(scenarioOps->mode == StartInfo::CAMPAIGN) @@ -699,7 +699,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur) cur->ID = ran.first; cur->subID = ran.second; map->removeBlockVisTiles(cur); //recalculate blockvis tiles - picked object might have different than random placeholder - map->defy.push_back(cur->defInfo = VLC->dobjinfo->gobjs[ran.first][ran.second]); + map->customDefs.push_back(cur->defInfo = VLC->dobjinfo->gobjs[ran.first][ran.second]); if(!cur->defInfo) { tlog1<<"*BIG* WARNING: Missing def declaration for "<ID<<" "<subID<getTile(tile); int terrain = t.tertype; if(t.isCoastal() && !t.isWater()) - terrain = TerrainTile::sand; + terrain = ETerrainType::SAND; int terType = battleGetBattlefieldType(tile); return BattleInfo::setupBattle(tile, terrain, terType, armies, heroes, creatureBank, town); @@ -865,7 +865,7 @@ void CGameState::init(StartInfo * si) switch(scenarioOps->mode) { case StartInfo::NEW_GAME: - map = new Mapa(scenarioOps->mapname); + map = new CMap(scenarioOps->mapname); break; case StartInfo::CAMPAIGN: { @@ -873,7 +873,7 @@ void CGameState::init(StartInfo * si) assert(vstd::contains(campaign->camp->mapPieces, scenarioOps->campState->currentMap)); std::string &mapContent = campaign->camp->mapPieces[scenarioOps->campState->currentMap]; - map = new Mapa(); + map = new CMap(); map->initFromBytes((const ui8*)mapContent.c_str(), mapContent.size()); } break; @@ -926,8 +926,8 @@ void CGameState::init(StartInfo * si) const TerrainTile &t = map->terrain[i][j][k]; if(!t.blocked && !t.visitable - && t.tertype != TerrainTile::water - && t.tertype != TerrainTile::rock + && t.tertype != ETerrainType::WATER + && t.tertype != ETerrainType::ROCK && map->grailPos.dist2d(int3(i,j,k)) <= map->grailRadious) allowedPos.push_back(int3(i,j,k)); } @@ -974,7 +974,7 @@ void CGameState::init(StartInfo * si) { int3 pos = obj->pos - int3(i,j,0); if(map->isInTheMap(pos)) - map->getTile(pos).siodmyTajemniczyBajt |= 128; + map->getTile(pos).extTileFlags |= 128; } } //std::cout<<"\tRandomizing objects: "<name = town.second.clientInfo.advMapCapitol; - map->defy.push_back(villages[town.first]); - map->defy.push_back(forts[town.first]); - map->defy.push_back(capitols[town.first]); + map->customDefs.push_back(villages[town.first]); + map->customDefs.push_back(forts[town.first]); + map->customDefs.push_back(capitols[town.first]); } } @@ -1819,19 +1819,19 @@ void CGameState::getNeighbours(const TerrainTile &srct, int3 tile, std::vectorgetTile(hlp1).tertype != TerrainTile::water || map->getTile(hlp2).tertype != TerrainTile::water) + if(map->getTile(hlp1).tertype != ETerrainType::WATER || map->getTile(hlp2).tertype != ETerrainType::WATER) continue; } - if((indeterminate(onLand) || onLand == (hlpt.tertype!=TerrainTile::water) ) - && hlpt.tertype != TerrainTile::rock) + if((indeterminate(onLand) || onLand == (hlpt.tertype!=ETerrainType::WATER) ) + && hlpt.tertype != ETerrainType::ROCK) { vec.push_back(hlp); } @@ -1858,7 +1858,7 @@ int CGameState::getMovementCost(const CGHeroInstance *h, const int3 &src, const ret *= 1.4; //40% penalty for movement over blocked tile } } - else if (d.tertype == TerrainTile::water) + else if (d.tertype == ETerrainType::WATER) { if(h->boat && s.hasFavourableWinds() && d.hasFavourableWinds()) //Favourable Winds ret *= 0.666; @@ -1882,7 +1882,7 @@ int CGameState::getMovementCost(const CGHeroInstance *h, const int3 &src, const if(checkLast && left > 0 && remainingMovePoints-ret < 250) //it might be the last tile - if no further move possible we take all move points { std::vector vec; - getNeighbours(d, dest, vec, s.tertype != TerrainTile::water, true); + getNeighbours(d, dest, vec, s.tertype != ETerrainType::WATER, true); for(size_t i=0; i < vec.size(); i++) { int fcost = getMovementCost(h,dest,vec[i],left,false); @@ -1952,7 +1952,7 @@ int3 CGameState::guardingCreaturePosition (int3 pos) const if (map->isInTheMap(pos)) { TerrainTile &tile = map->terrain[pos.x][pos.y][pos.z]; - if (tile.visitable && (tile.tertype == TerrainTile::water) == (posTile.tertype == TerrainTile::water)) + if (tile.visitable && (tile.tertype == ETerrainType::WATER) == (posTile.tertype == ETerrainType::WATER)) { BOOST_FOREACH (CGObjectInstance* obj, tile.visitableObjects) { @@ -2809,7 +2809,7 @@ DuelParameters::SideSettings::SideSettings() DuelParameters::DuelParameters() { - terType = TerrainTile::dirt; + terType = ETerrainType::DIRT; bfieldType = 15; } @@ -2928,7 +2928,7 @@ void CPathfinder::initializeGraph() node.coord.x = i; node.coord.y = j; node.coord.z = k; - node.land = tinfo->tertype != TerrainTile::water; + node.land = tinfo->tertype != ETerrainType::WATER; node.theNodeBefore = NULL; } } @@ -3101,7 +3101,7 @@ CGPathNode::EAccessibility CPathfinder::evaluateAccessibility(const TerrainTile CGPathNode::EAccessibility ret = (tinfo->blocked ? CGPathNode::BLOCKED : CGPathNode::ACCESSIBLE); - if(tinfo->tertype == TerrainTile::rock || !FoW[curPos.x][curPos.y][curPos.z]) + if(tinfo->tertype == ETerrainType::ROCK || !FoW[curPos.x][curPos.y][curPos.z]) return CGPathNode::BLOCKED; if(tinfo->visitable) diff --git a/lib/CGameState.h b/lib/CGameState.h index 411b9cb6d..d35061c38 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -44,7 +44,7 @@ class CGDefInfo; class CObjectScript; class CGObjectInstance; class CCreature; -struct Mapa; +struct CMap; struct StartInfo; struct SDL_Surface; class CMapHandler; @@ -386,7 +386,7 @@ public: ui8 currentPlayer; //ID of player currently having turn ConstTransitivePtr curB; //current battle ui32 day; //total number of days in game - ConstTransitivePtr map; + ConstTransitivePtr map; bmap players; bmap teams; bmap > villages, forts, capitols; //def-info for town graphics @@ -461,7 +461,7 @@ public: friend class CCallback; friend class CLuaCallback; friend class CClient; - friend void initGameState(Mapa * map, CGameInfo * cgi); + friend void initGameState(CMap * map, CGameInfo * cgi); friend class IGameCallback; friend class CMapHandler; friend class CGameHandler; diff --git a/lib/CMapInfo.cpp b/lib/CMapInfo.cpp index 774e238cd..fc11df470 100644 --- a/lib/CMapInfo.cpp +++ b/lib/CMapInfo.cpp @@ -38,7 +38,7 @@ void CMapInfo::mapInit(const std::string &fname, const ui8 *map ) fileURI = fname; int i = 0; mapHeader = new CMapHeader(); - mapHeader->version = CMapHeader::invalid; + mapHeader->version = EMapFormat::INVALID; try { diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 7eb40b798..9420e696a 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -530,18 +530,18 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainTile &fro unsigned ret = 100; //if there is road both on dest and src tiles - use road movement cost - if(dest.malle && from.malle) + if(dest.roadType && from.roadType) { - int road = std::min(dest.malle,from.malle); //used road ID + int road = std::min(dest.roadType,from.roadType); //used road ID switch(road) { - case TerrainTile::dirtRoad: + case ERoadType::DIRT_ROAD: ret = 75; break; - case TerrainTile::grazvelRoad: + case ERoadType::GRAVEL_ROAD: ret = 65; break; - case TerrainTile::cobblestoneRoad: + case ERoadType::COBBLESTONE_ROAD: ret = 50; break; default: @@ -1502,7 +1502,7 @@ CGHeroInstance::ECanDig CGHeroInstance::diggingStatus() const { if(movement < maxMovePoints(true)) return LACK_OF_MOVEMENT; - else if(cb->getTile(getPosition(false))->tertype == TerrainTile::water) + else if(cb->getTile(getPosition(false))->tertype == ETerrainType::WATER) return WRONG_TERRAIN; else { @@ -6530,7 +6530,7 @@ int3 IBoatGenerator::bestLocation() const { if (const TerrainTile *tile = IObjectInterface::cb->getTile(o->pos + offsets[i], false)) //tile is in the map { - if (tile->tertype == TerrainTile::water && (!tile->blocked || tile->blockingObjects.front()->ID == 8)) //and is water and is not blocked or is blocked by boat + if (tile->tertype == ETerrainType::WATER && (!tile->blocked || tile->blockingObjects.front()->ID == 8)) //and is water and is not blocked or is blocked by boat return o->pos + offsets[i]; } } diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index d031ee61a..1d96deb94 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -430,9 +430,9 @@ bool CGameInfoCallback::verifyPath(CPath * path, bool blockSea) const continue; const TerrainTile *prev = getTile(path->nodes[i-1].coord); //tile of previous node on the path - if (( t->tertype == TerrainTile::water && prev->tertype != TerrainTile::water) - || (t->tertype != TerrainTile::water && prev->tertype == TerrainTile::water) - || prev->tertype == TerrainTile::rock + if (( t->tertype == ETerrainType::WATER && prev->tertype != ETerrainType::WATER) + || (t->tertype != ETerrainType::WATER && prev->tertype == ETerrainType::WATER) + || prev->tertype == ETerrainType::ROCK ) return false; } @@ -594,7 +594,7 @@ int CGameInfoCallback::canBuildStructure( const CGTownInstance *t, int ID ) { const TerrainTile *tile = getTile(t->bestLocation(), false); - if(!tile || tile->tertype != TerrainTile::water ) + if(!tile || tile->tertype != ETerrainType::WATER) return EBuildingState::NO_WATER; //lack of water } diff --git a/lib/map.cpp b/lib/map.cpp index 20608ea15..77cf1677d 100644 --- a/lib/map.cpp +++ b/lib/map.cpp @@ -89,7 +89,7 @@ static ui8 reverse(ui8 arg) return ret; } -void readCreatureSet(CCreatureSet *out, const ui8 * bufor, int &i, int number, bool version) //version==true for >RoE maps +void readCreatureSet(CCreatureSet *out, const ui8 * buffer, int &i, int number, bool version) //version==true for >RoE maps { const int bytesPerCre = version ? 4 : 3, maxID = version ? 0xffff : 0xff; @@ -101,13 +101,13 @@ void readCreatureSet(CCreatureSet *out, const ui8 * bufor, int &i, int number, b if (version) { - creID = read_le_u16(bufor + i+ir*bytesPerCre); - count = read_le_u16(bufor + i+ir*bytesPerCre + 2); + creID = read_le_u16(buffer + i+ir*bytesPerCre); + count = read_le_u16(buffer + i+ir*bytesPerCre + 2); } else { - creID = bufor[i+ir*bytesPerCre]; - count = read_le_u16(bufor + i+ir*bytesPerCre + 1); + creID = buffer[i+ir*bytesPerCre]; + count = read_le_u16(buffer + i+ir*bytesPerCre + 1); } if(creID == maxID) //empty slot @@ -131,6 +131,40 @@ void readCreatureSet(CCreatureSet *out, const ui8 * bufor, int &i, int number, b out->validTypes(true); } +PlayerInfo::PlayerInfo(): p7(0), p8(0), p9(0), canHumanPlay(0), canComputerPlay(0), + AITactic(0), isFactionRandom(0), + mainHeroPortrait(0), hasMainTown(0), generateHeroAtMainTown(0), + team(255), generateHero(0) +{ + +} + +si8 PlayerInfo::defaultCastle() const +{ + assert(!allowedFactions.empty()); // impossible? + + if(allowedFactions.size() == 1) + { + // only one faction is available - pick it + return *allowedFactions.begin(); + } + + // set to random + return -1; +} + +si8 PlayerInfo::defaultHero() const +{ + // we will generate hero in front of main town + if((generateHeroAtMainTown && hasMainTown) || p8) + { + //random hero + return -1; + } + + return -2; +} + CMapHeader::CMapHeader(const ui8 *map) { int i=0; @@ -143,33 +177,34 @@ CMapHeader::CMapHeader() height = width = twoLevel = -1; } -void CMapHeader::initFromMemory( const ui8 *bufor, int &i ) +void CMapHeader::initFromMemory( const ui8 *buffer, int &i ) { - version = (Eformat)(read_le_u32(bufor + i)); i+=4; //map version - if(version != RoE && version != AB && version != SoD && version != WoG) + version = (EMapFormat::EMapFormat)(read_le_u32(buffer + i)); i+=4; //map version + if(version != EMapFormat::ROE && version != EMapFormat::AB && version != EMapFormat::SOD + && version != EMapFormat::WOG) { throw std::runtime_error("Invalid map format!"); } - areAnyPLayers = readChar(bufor,i); //invalid on some maps - height = width = (read_le_u32(bufor + i)); i+=4; // dimensions of map - twoLevel = readChar(bufor,i); //if there is underground + areAnyPLayers = readChar(buffer,i); //invalid on some maps + height = width = (read_le_u32(buffer + i)); i+=4; // dimensions of map + twoLevel = readChar(buffer,i); //if there is underground int pom; - name = readString(bufor,i); - description= readString(bufor,i); - difficulty = readChar(bufor,i); // reading map difficulty - if(version != RoE) - levelLimit = readChar(bufor,i); // hero level limit + name = readString(buffer,i); + description= readString(buffer,i); + difficulty = readChar(buffer,i); // reading map difficulty + if(version != EMapFormat::ROE) + levelLimit = readChar(buffer,i); // hero level limit else levelLimit = 0; - loadPlayerInfo(pom, bufor, i); - loadViCLossConditions(bufor, i); + loadPlayerInfo(pom, buffer, i); + loadViCLossConditions(buffer, i); - howManyTeams=bufor[i++]; //read number of teams + howManyTeams=buffer[i++]; //read number of teams if(howManyTeams>0) //read team numbers { for(int rr=0; rr<8; ++rr) { - players[rr].team = bufor[i++]; + players[rr].team = buffer[i++]; } } else//no alliances @@ -182,69 +217,70 @@ void CMapHeader::initFromMemory( const ui8 *bufor, int &i ) pom = i; allowedHeroes.resize(GameConstants::HEROES_QUANTITY,false); - for(; iRoE) //probably reserved for further heroes + if(version > EMapFormat::ROE) //probably reserved for further heroes { - int placeholdersQty = read_le_u32(bufor + i); i+=4; + int placeholdersQty = read_le_u32(buffer + i); i+=4; for(int p = 0; p < placeholdersQty; p++) - placeholdedHeroes.push_back(bufor[i++]); + placeholdedHeroes.push_back(buffer[i++]); } } -void CMapHeader::loadPlayerInfo( int &pom, const ui8 * bufor, int &i ) +void CMapHeader::loadPlayerInfo( int &pom, const ui8 * buffer, int &i ) { players.resize(8); for (pom=0;pom<8;pom++) { - players[pom].canHumanPlay = bufor[i++]; - players[pom].canComputerPlay = bufor[i++]; + players[pom].canHumanPlay = buffer[i++]; + players[pom].canComputerPlay = buffer[i++]; if ((!(players[pom].canHumanPlay || players[pom].canComputerPlay))) //if nobody can play with this player { switch(version) { - case SoD: case WoG: + case EMapFormat::SOD: + case EMapFormat::WOG: i+=13; break; - case AB: + case EMapFormat::AB: i+=12; break; - case RoE: + case EMapFormat::ROE: i+=6; break; } continue; } - players[pom].AITactic = bufor[i++]; + players[pom].AITactic = buffer[i++]; - if(version == SoD || version == WoG) - players[pom].p7= bufor[i++]; + if(version == EMapFormat::SOD || version == EMapFormat::WOG) + players[pom].p7= buffer[i++]; else players[pom].p7= -1; //factions this player can choose - ui16 allowedFactions = bufor[i++]; - if(version != RoE) - allowedFactions += (bufor[i++])*256; + ui16 allowedFactions = buffer[i++]; + if(version != EMapFormat::ROE) + allowedFactions += (buffer[i++])*256; for (size_t fact=0; fact<16; fact++) if (allowedFactions & (1 << fact)) players[pom].allowedFactions.insert(fact); - players[pom].isFactionRandom = bufor[i++]; - players[pom].hasMainTown = bufor[i++]; + players[pom].isFactionRandom = buffer[i++]; + players[pom].hasMainTown = buffer[i++]; if (players[pom].hasMainTown) { - if(version != RoE) + if(version != EMapFormat::ROE) { - players[pom].generateHeroAtMainTown = bufor[i++]; - players[pom].generateHero = bufor[i++]; + players[pom].generateHeroAtMainTown = buffer[i++]; + players[pom].generateHero = buffer[i++]; } else { @@ -252,34 +288,34 @@ void CMapHeader::loadPlayerInfo( int &pom, const ui8 * bufor, int &i ) players[pom].generateHero = false; } - players[pom].posOfMainTown.x = bufor[i++]; - players[pom].posOfMainTown.y = bufor[i++]; - players[pom].posOfMainTown.z = bufor[i++]; + players[pom].posOfMainTown.x = buffer[i++]; + players[pom].posOfMainTown.y = buffer[i++]; + players[pom].posOfMainTown.z = buffer[i++]; } - players[pom].p8= bufor[i++]; - players[pom].p9= bufor[i++]; + players[pom].p8= buffer[i++]; + players[pom].p9= buffer[i++]; if(players[pom].p9!=0xff) { - players[pom].mainHeroPortrait = bufor[i++]; - players[pom].mainHeroName = readString(bufor,i); + players[pom].mainHeroPortrait = buffer[i++]; + players[pom].mainHeroName = readString(buffer,i); } - if(version != RoE) + if(version != EMapFormat::ROE) { - players[pom].powerPlacehodlers = bufor[i++];//unknown byte - int heroCount = bufor[i++]; + players[pom].powerPlacehodlers = buffer[i++];//unknown byte + int heroCount = buffer[i++]; i+=3; for (int pp=0;pp2) + if (buffer[i+4]>2) victoryCondition.pos = int3(-1,-1,-1); else { - victoryCondition.pos.x = bufor[i+2]; - victoryCondition.pos.y = bufor[i+3]; - victoryCondition.pos.z = bufor[i+4]; + victoryCondition.pos.x = buffer[i+2]; + victoryCondition.pos.y = buffer[i+3]; + victoryCondition.pos.z = buffer[i+4]; } nr = 3; break; @@ -345,9 +381,9 @@ void CMapHeader::loadViCLossConditions( const ui8 * bufor, int &i) case EVictoryConditionType::CAPTURECITY: case EVictoryConditionType::BEATMONSTER: { - victoryCondition.pos.x = bufor[i+2]; - victoryCondition.pos.y = bufor[i+3]; - victoryCondition.pos.z = bufor[i+4]; + victoryCondition.pos.x = buffer[i+2]; + victoryCondition.pos.y = buffer[i+3]; + victoryCondition.pos.z = buffer[i+4]; nr = 3; break; } @@ -359,34 +395,34 @@ void CMapHeader::loadViCLossConditions( const ui8 * bufor, int &i) } case EVictoryConditionType::TRANSPORTITEM: { - victoryCondition.ID = bufor[i+2]; - victoryCondition.pos.x = bufor[i+3]; - victoryCondition.pos.y = bufor[i+4]; - victoryCondition.pos.z = bufor[i+5]; + victoryCondition.ID = buffer[i+2]; + victoryCondition.pos.x = buffer[i+3]; + victoryCondition.pos.y = buffer[i+4]; + victoryCondition.pos.z = buffer[i+5]; nr = 4; break; } default: assert(0); } - victoryCondition.allowNormalVictory = bufor[i++]; - victoryCondition.appliesToAI = bufor[i++]; + victoryCondition.allowNormalVictory = buffer[i++]; + victoryCondition.appliesToAI = buffer[i++]; i+=nr; } - lossCondition.typeOfLossCon = (ELossConditionType::ELossConditionType)bufor[i++]; + lossCondition.typeOfLossCon = (ELossConditionType::ELossConditionType)buffer[i++]; switch (lossCondition.typeOfLossCon) //read loss conditions { case ELossConditionType::LOSSCASTLE: case ELossConditionType::LOSSHERO: { - lossCondition.pos.x=bufor[i++]; - lossCondition.pos.y=bufor[i++]; - lossCondition.pos.z=bufor[i++]; + lossCondition.pos.x=buffer[i++]; + lossCondition.pos.y=buffer[i++]; + lossCondition.pos.z=buffer[i++]; break; } case ELossConditionType::TIMEEXPIRES: { - lossCondition.timeLimit = read_le_u16(bufor + i); + lossCondition.timeLimit = read_le_u16(buffer + i); i+=2; break; } @@ -398,19 +434,19 @@ CMapHeader::~CMapHeader() } -void Mapa::initFromBytes(const ui8 * bufor, size_t size) +void CMap::initFromBytes(const ui8 * buffer, size_t size) { // Compute checksum boost::crc_32_type result; - result.process_bytes(bufor, size); + result.process_bytes(buffer, size); checksum = result.checksum(); tlog0 << "\tOur map checksum: "<defInfo) @@ -447,7 +483,7 @@ void Mapa::initFromBytes(const ui8 * bufor, size_t size) tlog0 << "\tMap initialization done!" << std::endl; } -void Mapa::removeBlockVisTiles(CGObjectInstance * obj, bool total) +void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total) { for(int fx=0; fx<8; ++fx) { @@ -473,7 +509,7 @@ void Mapa::removeBlockVisTiles(CGObjectInstance * obj, bool total) } } } -void Mapa::addBlockVisTiles(CGObjectInstance * obj) +void CMap::addBlockVisTiles(CGObjectInstance * obj) { for(int fx=0; fx<8; ++fx) { @@ -500,9 +536,9 @@ void Mapa::addBlockVisTiles(CGObjectInstance * obj) } } -TInputStreamPtr Mapa::getMapStream(std::string URI) +TInputStreamPtr CMap::getMapStream(std::string name) { - TInputStreamPtr file = CResourceHandler::get()->load(ResourceID(URI, EResType::MAP)); + TInputStreamPtr file = CResourceHandler::get()->load(ResourceID(name, EResType::MAP)); CBinaryReader reader(*file.get()); @@ -513,19 +549,19 @@ TInputStreamPtr Mapa::getMapStream(std::string URI) { case 0x00088B1F: // gzip header magic number, reversed for LE return TInputStreamPtr(new CCompressedStream(std::move(file), true)); - case CMapHeader::WoG : - case CMapHeader::AB : - case CMapHeader::RoE : - case CMapHeader::SoD : + case EMapFormat::WOG : + case EMapFormat::AB : + case EMapFormat::ROE : + case EMapFormat::SOD : return file; default : - tlog0 << "Error: Failed to open map " << URI << ": unknown format\n"; + tlog0 << "Error: Failed to open map " << name << ": unknown format\n"; return TInputStreamPtr(); } } -Mapa::Mapa(std::string filename) - :grailPos(-1, -1, -1), grailRadious(0) +CMap::CMap(std::string filename) + : grailPos(-1, -1, -1), grailRadious(0) { tlog0<<"Opening map file: "<serial < 0) //def not present in the main vector in defobjinfo - // delete defy[i]; + //for(int i=0; i < customDefs.size(); i++) + // if(customDefs[i]->serial < 0) //def not present in the main vector in defobjinfo + // delete customDefs[i]; if(terrain) { - for (int ii=0;ii >::iterator i = events.begin(); i != events.end(); i++) + { i->dellNull(); + } } -CGHeroInstance * Mapa::getHero(int ID, int mode) +CGHeroInstance * CMap::getHero(int heroID) { - if (mode != 0) -#ifndef __GNUC__ - throw new std::exception("gs->getHero: This mode is not supported!"); -#else - throw new std::exception(); -#endif - for(ui32 i=0; isubID == ID) + if(heroes[i]->subID == heroID) return heroes[i]; - return NULL; + return nullptr; } -int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj ) +int CMap::loadSeerHut(const ui8 * buffer, int i, CGObjectInstance * & seerHut) { CGSeerHut *hut = new CGSeerHut(); - nobj = hut; + seerHut = hut; - if(version>RoE) + if(version > EMapFormat::ROE) { - loadQuest(hut,bufor,i); + loadQuest(hut,buffer,i); } else //RoE { - int artID = bufor[i]; ++i; + int artID = buffer[i]; ++i; if (artID != 255) //not none quest { hut->quest->m5arts.push_back (artID); @@ -608,79 +639,79 @@ int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj ) if (hut->quest->missionType) { - ui8 rewardType = bufor[i]; ++i; + ui8 rewardType = buffer[i]; ++i; hut->rewardType = rewardType; switch(rewardType) { case 1: { - hut->rVal = read_le_u32(bufor + i); i+=4; + hut->rVal = read_le_u32(buffer + i); i+=4; break; } case 2: { - hut->rVal = read_le_u32(bufor + i); i+=4; + hut->rVal = read_le_u32(buffer + i); i+=4; break; } case 3: { - hut->rVal = bufor[i]; ++i; + hut->rVal = buffer[i]; ++i; break; } case 4: { - hut->rVal = bufor[i]; ++i; + hut->rVal = buffer[i]; ++i; break; } case 5: { - hut->rID = bufor[i]; ++i; + hut->rID = buffer[i]; ++i; /* Only the first 3 bytes are used. Skip the 4th. */ - hut->rVal = read_le_u32(bufor + i) & 0x00ffffff; + hut->rVal = read_le_u32(buffer + i) & 0x00ffffff; i+=4; break; } case 6: { - hut->rID = bufor[i]; ++i; - hut->rVal = bufor[i]; ++i; + hut->rID = buffer[i]; ++i; + hut->rVal = buffer[i]; ++i; break; } case 7: { - hut->rID = bufor[i]; ++i; - hut->rVal = bufor[i]; ++i; + hut->rID = buffer[i]; ++i; + hut->rVal = buffer[i]; ++i; break; } case 8: { - if (version == RoE) + if (version == EMapFormat::ROE) { - hut->rID = bufor[i]; i++; + hut->rID = buffer[i]; i++; } else { - hut->rID = read_le_u16(bufor + i); i+=2; + hut->rID = read_le_u16(buffer + i); i+=2; } break; } case 9: { - hut->rID = bufor[i]; ++i; + hut->rID = buffer[i]; ++i; break; } case 10: { - if(version>RoE) + if(version > EMapFormat::ROE) { - hut->rID = read_le_u16(bufor + i); i+=2; - hut->rVal = read_le_u16(bufor + i); i+=2; + hut->rID = read_le_u16(buffer + i); i+=2; + hut->rVal = read_le_u16(buffer + i); i+=2; } else { - hut->rID = bufor[i]; ++i; - hut->rVal = read_le_u16(bufor + i); i+=2; + hut->rID = buffer[i]; ++i; + hut->rVal = read_le_u16(buffer + i); i+=2; } break; } @@ -694,30 +725,28 @@ int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj ) return i; } -void Mapa::loadTown( CGObjectInstance * &nobj, const ui8 * bufor, int &i, int subid) +void CMap::loadTown(CGObjectInstance * & town, const ui8 * buffer, int &i, int castleID) { CGTownInstance * nt = new CGTownInstance(); - //(*(static_cast(nt))) = *nobj; - //delete nobj; - nobj = nt; + town = nt; nt->identifier = 0; - if(version>RoE) + if(version > EMapFormat::ROE) { - nt->identifier = read_le_u32(bufor + i); i+=4; + nt->identifier = read_le_u32(buffer + i); i+=4; } - nt->tempOwner = bufor[i]; ++i; - if(readChar(bufor,i)) //has name - nt->name = readString(bufor,i); - if(readChar(bufor,i))//true if garrison isn't empty - readCreatureSet(nt, bufor, i, 7, version > RoE); - nt->formation = bufor[i]; ++i; - if(readChar(bufor,i)) //custom buildings info + nt->tempOwner = buffer[i]; ++i; + if(readChar(buffer,i)) //has name + nt->name = readString(buffer,i); + if(readChar(buffer,i))//true if garrison isn't empty + readCreatureSet(nt, buffer, i, 7, version > EMapFormat::ROE); + nt->formation = buffer[i]; ++i; + if(readChar(buffer,i)) //custom buildings info { //built buildings for(int byte=0;byte<6;byte++) { for(int bit=0;bit<8;bit++) - if(bufor[i] & (1<builtBuildings.insert(byte*8+bit); i++; } @@ -725,26 +754,26 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const ui8 * bufor, int &i, int su for(int byte=6;byte<12;byte++) { for(int bit=0;bit<8;bit++) - if(bufor[i] & (1<forbiddenBuildings.insert((byte-6)*8+bit); i++; } - nt->builtBuildings = convertBuildings(nt->builtBuildings,subid); - nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings,subid); + nt->builtBuildings = convertBuildings(nt->builtBuildings,castleID); + nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings,castleID); } else //standard buildings { - if(readChar(bufor,i)) //has fort + if(readChar(buffer,i)) //has fort nt->builtBuildings.insert(EBuilding::FORT); nt->builtBuildings.insert(-50); //means that set of standard building should be included } int ist = i; - if(version>RoE) + if(version > EMapFormat::ROE) { for(; itown = nt; - nce->name = readString(bufor,i); - nce->message = readString(bufor,i); + nce->name = readString(buffer,i); + nce->message = readString(buffer,i); for(int x=0; x < 7; x++) { - nce->resources[x] = read_le_u32(bufor + i); + nce->resources[x] = read_le_u32(buffer + i); i+=4; } - nce->players = bufor[i]; ++i; - if(version > AB) + nce->players = buffer[i]; ++i; + if(version > EMapFormat::AB) { - nce->humanAffected = bufor[i]; ++i; + nce->humanAffected = buffer[i]; ++i; } else nce->humanAffected = true; - nce->computerAffected = bufor[i]; ++i; - nce->firstOccurence = read_le_u16(bufor + i); i+=2; - nce->nextOccurence = bufor[i]; ++i; + nce->computerAffected = buffer[i]; ++i; + nce->firstOccurence = read_le_u16(buffer + i); i+=2; + nce->nextOccurence = buffer[i]; ++i; i+=17; @@ -804,24 +833,24 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const ui8 * bufor, int &i, int su for(int byte=0;byte<6;byte++) { for(int bit=0;bit<8;bit++) - if(bufor[i] & (1<buildings.insert(byte*8+bit); i++; } - nce->buildings = convertBuildings(nce->buildings,subid, false); + nce->buildings = convertBuildings(nce->buildings,castleID, false); nce->creatures.resize(7); for(int vv=0; vv<7; ++vv) { - nce->creatures[vv] = read_le_u16(bufor + i);i+=2; + nce->creatures[vv] = read_le_u16(buffer + i);i+=2; } i+=4; nt->events.push_back(nce); }//castle events have been read - if(version > AB) + if(version > EMapFormat::AB) { - nt->alignment = bufor[i]; ++i; + nt->alignment = buffer[i]; ++i; } else nt->alignment = 0xff; @@ -832,19 +861,19 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const ui8 * bufor, int &i, int su nt->garrisonHero = NULL; } -CGObjectInstance * Mapa::loadHero(const ui8 * bufor, int &i, int idToBeGiven) +CGObjectInstance * CMap::loadHero(const ui8 * buffer, int &i, int idToBeGiven) { CGHeroInstance * nhi = new CGHeroInstance(); int identifier = 0; - if(version > RoE) + if(version > EMapFormat::ROE) { - identifier = read_le_u32(bufor + i); i+=4; + identifier = read_le_u32(buffer + i); i+=4; questIdentifierToId[identifier] = idToBeGiven; } - ui8 owner = bufor[i++]; - nhi->subID = bufor[i++]; + ui8 owner = buffer[i++]; + nhi->subID = buffer[i++]; for(ui32 j=0; jname = readString(bufor,i); - if(version>AB) + if(readChar(buffer,i))//true if hero has nonstandard name + nhi->name = readString(buffer,i); + if(version > EMapFormat::AB) { - if(readChar(bufor,i))//true if hero's experience is greater than 0 - { nhi->exp = read_le_u32(bufor + i); i+=4; } + if(readChar(buffer,i))//true if hero's experience is greater than 0 + { nhi->exp = read_le_u32(buffer + i); i+=4; } else nhi->exp = 0xffffffff; } else { - nhi->exp = read_le_u32(bufor + i); i+=4; + nhi->exp = read_le_u32(buffer + i); i+=4; if(!nhi->exp) //0 means "not set" in <=AB maps nhi->exp = 0xffffffff; } - bool portrait=bufor[i]; ++i; + bool portrait=buffer[i]; ++i; if (portrait) - nhi->portrait = bufor[i++]; - if(readChar(bufor,i))//true if hero has specified abilities + nhi->portrait = buffer[i++]; + if(readChar(buffer,i))//true if hero has specified abilities { - int howMany = read_le_u32(bufor + i); i+=4; + int howMany = read_le_u32(buffer + i); i+=4; nhi->secSkills.resize(howMany); for(int yy=0; yysecSkills[yy].first = bufor[i++]; - nhi->secSkills[yy].second = bufor[i++]; + nhi->secSkills[yy].first = buffer[i++]; + nhi->secSkills[yy].second = buffer[i++]; } } - if(readChar(bufor,i))//true if hero has nonstandard garrison - readCreatureSet(nhi, bufor, i, 7, version > RoE); + if(readChar(buffer,i))//true if hero has nonstandard garrison + readCreatureSet(nhi, buffer, i, 7, version > EMapFormat::ROE); - nhi->formation =bufor[i]; ++i; //formation - loadArtifactsOfHero(bufor, i, nhi); - nhi->patrol.patrolRadious = bufor[i]; ++i; + nhi->formation =buffer[i]; ++i; //formation + loadArtifactsOfHero(buffer, i, nhi); + nhi->patrol.patrolRadious = buffer[i]; ++i; if(nhi->patrol.patrolRadious == 0xff) nhi->patrol.patrolling = false; else nhi->patrol.patrolling = true; - if(version>RoE) + if(version > EMapFormat::ROE) { - if(readChar(bufor,i))//true if hero has nonstandard (mapmaker defined) biography - nhi->biography = readString(bufor,i); - nhi->sex = bufor[i]; ++i; + if(readChar(buffer,i))//true if hero has nonstandard (mapmaker defined) biography + nhi->biography = readString(buffer,i); + nhi->sex = buffer[i]; ++i; if (nhi->sex != 0xFF)//remove trash nhi->sex &=1; @@ -921,9 +950,9 @@ CGObjectInstance * Mapa::loadHero(const ui8 * bufor, int &i, int idToBeGiven) else nhi->sex = 0xFF; //spells - if(version>AB) + if(version > EMapFormat::AB) { - bool areSpells = bufor[i]; ++i; + bool areSpells = buffer[i]; ++i; if(areSpells) //TODO: sprawdzi //seems to be ok - tow { @@ -931,7 +960,7 @@ CGObjectInstance * Mapa::loadHero(const ui8 * bufor, int &i, int idToBeGiven) int ist = i; for(; ispells.insert(0xffffffff); //placeholder "preset spells" @@ -954,12 +983,12 @@ CGObjectInstance * Mapa::loadHero(const ui8 * bufor, int &i, int idToBeGiven) } } //spells loaded - if(version>AB) + if(version > EMapFormat::AB) { - if(readChar(bufor,i))//customPrimSkills + if(readChar(buffer,i))//customPrimSkills { for(int xx=0; xxpushPrimSkill(xx, bufor[i++]); + nhi->pushPrimSkill(xx, buffer[i++]); } } i+=16; @@ -967,40 +996,40 @@ CGObjectInstance * Mapa::loadHero(const ui8 * bufor, int &i, int idToBeGiven) return nhi; } -void Mapa::readRumors( const ui8 * bufor, int &i) +void CMap::readRumors( const ui8 * buffer, int &i) { - int rumNr = read_le_u32(bufor + i);i+=4; + int rumNr = read_le_u32(buffer + i);i+=4; for (int it=0;it=SoD) + if(version >= EMapFormat::SOD) { - disp = bufor[i++]; + disp = buffer[i++]; disposedHeroes.resize(disp); for(int g=0; garth->artifacts) { @@ -1036,7 +1065,7 @@ void Mapa::readHeader( const ui8 * bufor, int &i) allowedArtifact[artifact->id] = false; } } - if (version == RoE) + if (version == EMapFormat::ROE) allowedArtifact[128] = false; //Armageddon's Blade } @@ -1048,13 +1077,13 @@ void Mapa::readHeader( const ui8 * bufor, int &i) for(ui32 x=0;x=SoD) + if(version >= EMapFormat::SOD) { //reading allowed spells (9 bytes) ist=i; //starting i for loop for(; iID = Obj::HERO; cgh->subID = z; - if(readChar(bufor,i))//true if hore's experience is greater than 0 - { cgh->exp = read_le_u32(bufor + i); i+=4; } + if(readChar(buffer,i))//true if hore's experience is greater than 0 + { cgh->exp = read_le_u32(buffer + i); i+=4; } else cgh->exp = 0; - if(readChar(bufor,i))//true if hero has specified abilities + if(readChar(buffer,i))//true if hero has specified abilities { - int howMany = read_le_u32(bufor + i); i+=4; + int howMany = read_le_u32(buffer + i); i+=4; cgh->secSkills.resize(howMany); for(int yy=0; yysecSkills[yy].first = bufor[i]; ++i; - cgh->secSkills[yy].second = bufor[i]; ++i; + cgh->secSkills[yy].first = buffer[i]; ++i; + cgh->secSkills[yy].second = buffer[i]; ++i; } } - loadArtifactsOfHero(bufor, i, cgh); + loadArtifactsOfHero(buffer, i, cgh); - if(readChar(bufor,i))//customBio - cgh->biography = readString(bufor,i); - cgh->sex = bufor[i++]; // 0xFF is default, 00 male, 01 female - if(readChar(bufor,i))//are spells + if(readChar(buffer,i))//customBio + cgh->biography = readString(buffer,i); + cgh->sex = buffer[i++]; // 0xFF is default, 00 male, 01 female + if(readChar(buffer,i))//are spells { int ist = i; for(; ipushPrimSkill(xx, bufor[i++]); + cgh->pushPrimSkill(xx, buffer[i++]); } predefinedHeroes.push_back(cgh); } break; } - case RoE: + case EMapFormat::ROE: i+=0; break; } } -void Mapa::readTerrain( const ui8 * bufor, int &i) +void CMap::readTerrain( const ui8 * buffer, int &i) { terrain = new TerrainTile**[width]; // allocate memory for (int ii=0;ii(bufor[i++]); - terrain[z][c][0].terview = bufor[i++]; - terrain[z][c][0].nuine = static_cast(bufor[i++]); - terrain[z][c][0].rivDir = bufor[i++]; - terrain[z][c][0].malle = static_cast(bufor[i++]); - terrain[z][c][0].roadDir = bufor[i++]; - terrain[z][c][0].siodmyTajemniczyBajt = bufor[i++]; - terrain[z][c][0].blocked = (terrain[z][c][0].tertype == TerrainTile::rock ? 1 : 0); //underground tiles are always blocked + terrain[z][c][0].tertype = static_cast(buffer[i++]); + terrain[z][c][0].terview = buffer[i++]; + terrain[z][c][0].riverType = static_cast(buffer[i++]); + terrain[z][c][0].riverDir = buffer[i++]; + terrain[z][c][0].roadType = static_cast(buffer[i++]); + terrain[z][c][0].roadDir = buffer[i++]; + terrain[z][c][0].extTileFlags = buffer[i++]; + terrain[z][c][0].blocked = (terrain[z][c][0].tertype == ETerrainType::ROCK ? 1 : 0); //underground tiles are always blocked terrain[z][c][0].visitable = 0; } } @@ -1175,34 +1205,34 @@ void Mapa::readTerrain( const ui8 * bufor, int &i) { for (int z=0; z(bufor[i++]); - terrain[z][c][1].terview = bufor[i++]; - terrain[z][c][1].nuine = static_cast(bufor[i++]); - terrain[z][c][1].rivDir = bufor[i++]; - terrain[z][c][1].malle = static_cast(bufor[i++]); - terrain[z][c][1].roadDir = bufor[i++]; - terrain[z][c][1].siodmyTajemniczyBajt = bufor[i++]; - terrain[z][c][1].blocked = (terrain[z][c][1].tertype == TerrainTile::rock ? 1 : 0); //underground tiles are always blocked + terrain[z][c][1].tertype = static_cast(buffer[i++]); + terrain[z][c][1].terview = buffer[i++]; + terrain[z][c][1].riverType = static_cast(buffer[i++]); + terrain[z][c][1].riverDir = buffer[i++]; + terrain[z][c][1].roadType = static_cast(buffer[i++]); + terrain[z][c][1].roadDir = buffer[i++]; + terrain[z][c][1].extTileFlags = buffer[i++]; + terrain[z][c][1].blocked = (terrain[z][c][1].tertype == ETerrainType::ROCK ? 1 : 0); //underground tiles are always blocked terrain[z][c][1].visitable = 0; } } } } -void Mapa::readDefInfo( const ui8 * bufor, int &i) +void CMap::readDefInfo( const ui8 * buffer, int &i) { - int defAmount = read_le_u32(bufor + i); i+=4; - defy.reserve(defAmount+8); + int defAmount = read_le_u32(buffer + i); i+=4; + customDefs.reserve(defAmount+8); for (int idd = 0 ; iddname.reserve(nameLength); for (int cd=0;cdname += bufor[i++]; + vinya->name += buffer[i++]; } std::transform(vinya->name.begin(),vinya->name.end(),vinya->name.begin(),(int(*)(int))toupper); @@ -1210,14 +1240,14 @@ void Mapa::readDefInfo( const ui8 * bufor, int &i) ui8 bytes[12]; for (int v=0; v<12; v++) // read info { - bytes[v] = bufor[i++]; + bytes[v] = buffer[i++]; } - vinya->terrainAllowed = read_le_u16(bufor + i);i+=2; - vinya->terrainMenu = read_le_u16(bufor + i);i+=2; - vinya->id = read_le_u32(bufor + i);i+=4; - vinya->subid = read_le_u32(bufor + i);i+=4; - vinya->type = bufor[i++]; - vinya->printPriority = bufor[i++]; + vinya->terrainAllowed = read_le_u16(buffer + i);i+=2; + vinya->terrainMenu = read_le_u16(buffer + i);i+=2; + vinya->id = read_le_u32(buffer + i);i+=4; + vinya->subid = read_le_u32(buffer + i);i+=4; + vinya->type = buffer[i++]; + vinya->printPriority = buffer[i++]; for (int zi=0; zi<6; zi++) { vinya->blockMap[zi] = reverse(bytes[zi]); @@ -1254,13 +1284,13 @@ void Mapa::readDefInfo( const ui8 * bufor, int &i) //calculating coverageMap vinya->fetchInfoFromMSK(); - defy.push_back(vinya); // add this def to the vector + customDefs.push_back(vinya); // add this def to the vector } //add holes - they always can appear for (int i = 0; i < 8 ; i++) { - defy.push_back(VLC->dobjinfo->gobjs[124][i]); + customDefs.push_back(VLC->dobjinfo->gobjs[124][i]); } } @@ -1273,22 +1303,22 @@ public: } }; -void Mapa::readObjects( const ui8 * bufor, int &i) +void CMap::readObjects(const ui8 * buffer, int &i) { - int howManyObjs = read_le_u32(bufor + i); i+=4; + int howManyObjs = read_le_u32(buffer + i); i+=4; for(int ww=0; wwid) @@ -1298,77 +1328,77 @@ void Mapa::readObjects( const ui8 * bufor, int &i) CGEvent *evnt = new CGEvent(); nobj = evnt; - bool guardMess = bufor[i]; ++i; + bool guardMess = buffer[i]; ++i; if(guardMess) { - int messLong = read_le_u32(bufor + i); i+=4; + int messLong = read_le_u32(buffer + i); i+=4; if(messLong>0) { for(int yy=0; yymessage +=bufor[i+yy]; + evnt->message +=buffer[i+yy]; } i+=messLong; } - if(bufor[i++]) + if(buffer[i++]) { - readCreatureSet(evnt, bufor, i, 7, version > RoE); + readCreatureSet(evnt, buffer, i, 7, version > EMapFormat::ROE); } i+=4; } - evnt->gainedExp = read_le_u32(bufor + i); i+=4; - evnt->manaDiff = read_le_u32(bufor + i); i+=4; - evnt->moraleDiff = (char)bufor[i]; ++i; - evnt->luckDiff = (char)bufor[i]; ++i; + evnt->gainedExp = read_le_u32(buffer + i); i+=4; + evnt->manaDiff = read_le_u32(buffer + i); i+=4; + evnt->moraleDiff = (char)buffer[i]; ++i; + evnt->luckDiff = (char)buffer[i]; ++i; evnt->resources.resize(GameConstants::RESOURCE_QUANTITY); for(int x=0; x<7; x++) { - evnt->resources[x] = read_le_u32(bufor + i); + evnt->resources[x] = read_le_u32(buffer + i); i+=4; } evnt->primskills.resize(GameConstants::PRIMARY_SKILLS); for(int x=0; x<4; x++) { - evnt->primskills[x] = bufor[i]; + evnt->primskills[x] = buffer[i]; i++; } int gabn; //number of gained abilities - gabn = bufor[i]; ++i; + gabn = buffer[i]; ++i; for(int oo = 0; ooabilities.push_back(bufor[i]); ++i; - evnt->abilityLevels.push_back(bufor[i]); ++i; + evnt->abilities.push_back(buffer[i]); ++i; + evnt->abilityLevels.push_back(buffer[i]); ++i; } - int gart = bufor[i]; ++i; //number of gained artifacts + int gart = buffer[i]; ++i; //number of gained artifacts for(int oo = 0; ooartifacts.push_back(bufor[i]); i++; + evnt->artifacts.push_back(buffer[i]); i++; } else { - evnt->artifacts.push_back(read_le_u16(bufor + i)); i+=2; + evnt->artifacts.push_back(read_le_u16(buffer + i)); i+=2; } } - int gspel = bufor[i]; ++i; //number of gained spells + int gspel = buffer[i]; ++i; //number of gained spells for(int oo = 0; oospells.push_back(bufor[i]); ++i; + evnt->spells.push_back(buffer[i]); ++i; } - int gcre = bufor[i]; ++i; //number of gained creatures - readCreatureSet(&evnt->creatures, bufor,i,gcre,(version>RoE)); + int gcre = buffer[i]; ++i; //number of gained creatures + readCreatureSet(&evnt->creatures, buffer,i,gcre,(version > EMapFormat::ROE)); i+=8; - evnt->availableFor = bufor[i]; ++i; - evnt->computerActivate = bufor[i]; ++i; - evnt->removeAfterVisit = bufor[i]; ++i; + evnt->availableFor = buffer[i]; ++i; + evnt->computerActivate = buffer[i]; ++i; + evnt->removeAfterVisit = buffer[i]; ++i; evnt->humanActivate = true; i+=4; @@ -1376,7 +1406,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i) } case 34: case 70: case 62: //34 - hero; 70 - random hero; 62 - prison { - nobj = loadHero(bufor, i, idToBeGiven); + nobj = loadHero(buffer, i, idToBeGiven); break; } case 4: //Arena @@ -1425,40 +1455,40 @@ void Mapa::readObjects( const ui8 * bufor, int &i) CGCreature *cre = new CGCreature(); nobj = cre; - if(version>RoE) + if(version > EMapFormat::ROE) { - cre->identifier = read_le_u32(bufor + i); i+=4; + cre->identifier = read_le_u32(buffer + i); i+=4; questIdentifierToId[cre->identifier] = idToBeGiven; //monsters[cre->identifier] = cre; } CStackInstance *hlp = new CStackInstance(); - hlp->count = read_le_u16(bufor + i); i+=2; + hlp->count = read_le_u16(buffer + i); i+=2; //type will be set during initialization cre->putStack(0, hlp); - cre->character = bufor[i]; ++i; - bool isMesTre = bufor[i]; ++i; //true if there is message or treasury + cre->character = buffer[i]; ++i; + bool isMesTre = buffer[i]; ++i; //true if there is message or treasury if(isMesTre) { - cre->message = readString(bufor,i); + cre->message = readString(buffer,i); cre->resources.resize(GameConstants::RESOURCE_QUANTITY); for(int j=0; j<7; j++) { - cre->resources[j] = read_le_u32(bufor + i); i+=4; + cre->resources[j] = read_le_u32(buffer + i); i+=4; } int artID; - if (version == RoE) + if (version == EMapFormat::ROE) { - artID = bufor[i]; i++; + artID = buffer[i]; i++; } else { - artID = read_le_u16(bufor + i); i+=2; + artID = read_le_u16(buffer + i); i+=2; } - if(version==RoE) + if(version == EMapFormat::ROE) { if(artID!=0xff) cre->gainedArtifact = artID; @@ -1473,8 +1503,8 @@ void Mapa::readObjects( const ui8 * bufor, int &i) cre->gainedArtifact = -1; } } - cre->neverFlees = bufor[i]; ++i; - cre->notGrowingTeam = bufor[i]; ++i; + cre->neverFlees = buffer[i]; ++i; + cre->notGrowingTeam = buffer[i]; ++i; i+=2;; break; } @@ -1482,13 +1512,13 @@ void Mapa::readObjects( const ui8 * bufor, int &i) { CGSignBottle *sb = new CGSignBottle(); nobj = sb; - sb->message = readString(bufor,i); + sb->message = readString(buffer,i); i+=4; break; } case 83: //seer's hut { - i = loadSeerHut(bufor, i, nobj); + i = loadSeerHut(buffer, i, nobj); addQuest (nobj); break; } @@ -1496,12 +1526,12 @@ void Mapa::readObjects( const ui8 * bufor, int &i) { CGWitchHut *wh = new CGWitchHut(); nobj = wh; - if(version>RoE) //in reo we cannot specify it - all are allowed (I hope) + if(version > EMapFormat::ROE) //in reo we cannot specify it - all are allowed (I hope) { int ist=i; //starting i for loop for(; ibonusType = bufor[i++]; - sch->bonusID = bufor[i++]; + sch->bonusType = buffer[i++]; + sch->bonusID = buffer[i++]; i+=6; break; } @@ -1534,12 +1564,12 @@ void Mapa::readObjects( const ui8 * bufor, int &i) { CGGarrison *gar = new CGGarrison(); nobj = gar; - nobj->setOwner(bufor[i++]); + nobj->setOwner(buffer[i++]); i+=3; - readCreatureSet(gar, bufor, i, 7, version > RoE); - if(version > RoE) + readCreatureSet(gar, buffer, i, 7, version > EMapFormat::ROE); + if(version > EMapFormat::ROE) { - gar->removableUnits = bufor[i]; ++i; + gar->removableUnits = buffer[i]; ++i; } else gar->removableUnits = true; @@ -1555,21 +1585,21 @@ void Mapa::readObjects( const ui8 * bufor, int &i) CGArtifact *art = new CGArtifact(); nobj = art; - bool areSettings = bufor[i++]; + bool areSettings = buffer[i++]; if(areSettings) { - art->message = readString(bufor,i); - bool areGuards = bufor[i++]; + art->message = readString(buffer,i); + bool areGuards = buffer[i++]; if(areGuards) { - readCreatureSet(art, bufor, i, 7, version > RoE); + readCreatureSet(art, buffer, i, 7, version > EMapFormat::ROE); } i+=4; } if(defInfo->id==93) { - spellID = read_le_u32(bufor + i); i+=4; + spellID = read_le_u32(buffer + i); i+=4; artID = 1; } else if(defInfo->id == 5) //specific artifact @@ -1585,17 +1615,17 @@ void Mapa::readObjects( const ui8 * bufor, int &i) CGResource *res = new CGResource(); nobj = res; - bool isMessGuard = bufor[i]; ++i; + bool isMessGuard = buffer[i]; ++i; if(isMessGuard) { - res->message = readString(bufor,i); - if(bufor[i++]) + res->message = readString(buffer,i); + if(buffer[i++]) { - readCreatureSet(res, bufor, i, 7, version > RoE); + readCreatureSet(res, buffer, i, 7, version > EMapFormat::ROE); } i+=4; } - res->amount = read_le_u32(bufor + i); i+=4; + res->amount = read_le_u32(buffer + i); i+=4; if (defInfo->subid == 6) // Gold is multiplied by 100. res->amount *= 100; i+=4; @@ -1604,21 +1634,21 @@ void Mapa::readObjects( const ui8 * bufor, int &i) } case 77: case 98: //random town; town { - loadTown(nobj, bufor, i, defInfo->subid); + loadTown(nobj, buffer, i, defInfo->subid); break; } case 53: case 220://mine (?) { nobj = new CGMine(); - nobj->setOwner(bufor[i++]); + nobj->setOwner(buffer[i++]); i+=3; break; } case 17: case 18: case 19: case 20: //dwellings { nobj = new CGDwelling(); - nobj->setOwner(bufor[i++]); + nobj->setOwner(buffer[i++]); i+=3; break; } @@ -1632,76 +1662,76 @@ void Mapa::readObjects( const ui8 * bufor, int &i) { CGShrine * shr = new CGShrine(); nobj = shr; - shr->spell = bufor[i]; i+=4; + shr->spell = buffer[i]; i+=4; break; } case 6: //pandora's box { CGPandoraBox *box = new CGPandoraBox(); nobj = box; - bool messg = bufor[i]; ++i; + bool messg = buffer[i]; ++i; if(messg) { - box->message = readString(bufor,i); - if(bufor[i++]) + box->message = readString(buffer,i); + if(buffer[i++]) { - readCreatureSet(box, bufor, i, 7, version > RoE); + readCreatureSet(box, buffer, i, 7, version > EMapFormat::ROE); } i+=4; } - box->gainedExp = read_le_u32(bufor + i); i+=4; - box->manaDiff = read_le_u32(bufor + i); i+=4; - box->moraleDiff = (si8)bufor[i]; ++i; - box->luckDiff = (si8)bufor[i]; ++i; + box->gainedExp = read_le_u32(buffer + i); i+=4; + box->manaDiff = read_le_u32(buffer + i); i+=4; + box->moraleDiff = (si8)buffer[i]; ++i; + box->luckDiff = (si8)buffer[i]; ++i; box->resources.resize(GameConstants::RESOURCE_QUANTITY); for(int x=0; x<7; x++) { - box->resources[x] = read_le_u32(bufor + i); + box->resources[x] = read_le_u32(buffer + i); i+=4; } box->primskills.resize(GameConstants::PRIMARY_SKILLS); for(int x=0; x<4; x++) { - box->primskills[x] = bufor[i]; + box->primskills[x] = buffer[i]; i++; } int gabn; //number of gained abilities - gabn = bufor[i]; ++i; + gabn = buffer[i]; ++i; for(int oo = 0; ooabilities.push_back(bufor[i]); ++i; - box->abilityLevels.push_back(bufor[i]); ++i; + box->abilities.push_back(buffer[i]); ++i; + box->abilityLevels.push_back(buffer[i]); ++i; } - int gart = bufor[i]; ++i; //number of gained artifacts + int gart = buffer[i]; ++i; //number of gained artifacts for(int oo = 0; oo RoE) + if(version > EMapFormat::ROE) { - box->artifacts.push_back(read_le_u16(bufor + i)); i+=2; + box->artifacts.push_back(read_le_u16(buffer + i)); i+=2; } else { - box->artifacts.push_back(bufor[i]); i+=1; + box->artifacts.push_back(buffer[i]); i+=1; } } - int gspel = bufor[i]; ++i; //number of gained spells + int gspel = buffer[i]; ++i; //number of gained spells for(int oo = 0; oospells.push_back(bufor[i]); ++i; + box->spells.push_back(buffer[i]); ++i; } - int gcre = bufor[i]; ++i; //number of gained creatures - readCreatureSet(&box->creatures, bufor,i,gcre,(version>RoE)); + int gcre = buffer[i]; ++i; //number of gained creatures + readCreatureSet(&box->creatures, buffer,i,gcre,(version > EMapFormat::ROE)); i+=8; break; } case 36: //grail { grailPos = pos; - grailRadious = read_le_u32(bufor + i); i+=4; + grailRadious = read_le_u32(buffer + i); i+=4; continue; } //dwellings @@ -1718,16 +1748,16 @@ void Mapa::readObjects( const ui8 * bufor, int &i) break; case 218: spec = new CCreGenLeveledInfo; } - spec->player = read_le_u32(bufor + i); i+=4; + spec->player = read_le_u32(buffer + i); i+=4; //216 and 217 if (auto castleSpec = dynamic_cast(spec)) { - castleSpec->identifier = read_le_u32(bufor + i); i+=4; + castleSpec->identifier = read_le_u32(buffer + i); i+=4; if(!castleSpec->identifier) { castleSpec->asCastle = false; - castleSpec->castles[0] = bufor[i]; ++i; - castleSpec->castles[1] = bufor[i]; ++i; + castleSpec->castles[0] = buffer[i]; ++i; + castleSpec->castles[1] = buffer[i]; ++i; } else { @@ -1738,8 +1768,8 @@ void Mapa::readObjects( const ui8 * bufor, int &i) //216 and 218 if (auto lvlSpec = dynamic_cast(spec)) { - lvlSpec->minLevel = std::max(bufor[i], ui8(1)); ++i; - lvlSpec->maxLevel = std::min(bufor[i], ui8(7)); ++i; + lvlSpec->minLevel = std::max(buffer[i], ui8(1)); ++i; + lvlSpec->maxLevel = std::min(buffer[i], ui8(7)); ++i; } nobj->setOwner(spec->player); static_cast(nobj)->info = spec; @@ -1749,7 +1779,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i) { CGQuestGuard *guard = new CGQuestGuard(); addQuest (guard); - loadQuest(guard, bufor, i); + loadQuest(guard, buffer, i); nobj = guard; break; } @@ -1802,7 +1832,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i) case 87: //Shipyard { nobj = new CGShipyard(); - nobj->setOwner(read_le_u32(bufor + i)); i+=4; + nobj->setOwner(read_le_u32(buffer + i)); i+=4; break; } case 214: //hero placeholder @@ -1810,14 +1840,14 @@ void Mapa::readObjects( const ui8 * bufor, int &i) CGHeroPlaceholder *hp = new CGHeroPlaceholder();; nobj = hp; - int a = bufor[i++]; //unknown byte, seems to be always 0 (if not - scream!) + int a = buffer[i++]; //unknown byte, seems to be always 0 (if not - scream!) tlog2 << "Unhandled Hero Placeholder detected: "<subID = htid; if(htid == 0xff) - hp->power = bufor[i++]; + hp->power = buffer[i++]; else hp->power = 0; @@ -1878,7 +1908,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i) case 42: //Lighthouse { nobj = new CGLighthouse(); - nobj->tempOwner = read_le_u32(bufor + i); i+=4; + nobj->tempOwner = read_le_u32(buffer + i); i+=4; break; } case 2: //Altar of Sacrifice @@ -1925,57 +1955,57 @@ void Mapa::readObjects( const ui8 * bufor, int &i) std::sort(heroes.begin(), heroes.end(), _HERO_SORTER()); } -void Mapa::readEvents( const ui8 * bufor, int &i ) +void CMap::readEvents( const ui8 * buffer, int &i ) { - int numberOfEvents = read_le_u32(bufor + i); i+=4; + int numberOfEvents = read_le_u32(buffer + i); i+=4; for(int yyoo=0; yyooname = std::string(); ne->message = std::string(); - int nameLen = read_le_u32(bufor + i); i+=4; + int nameLen = read_le_u32(buffer + i); i+=4; for(int qq=0; qqname += bufor[i]; ++i; + ne->name += buffer[i]; ++i; } - int messLen = read_le_u32(bufor + i); i+=4; + int messLen = read_le_u32(buffer + i); i+=4; for(int qq=0; qqmessage +=bufor[i]; ++i; + ne->message +=buffer[i]; ++i; } for(int k=0; k < 7; k++) { - ne->resources[k] = read_le_u32(bufor + i); i+=4; + ne->resources[k] = read_le_u32(buffer + i); i+=4; } - ne->players = bufor[i]; ++i; - if(version>AB) + ne->players = buffer[i]; ++i; + if(version > EMapFormat::AB) { - ne->humanAffected = bufor[i]; ++i; + ne->humanAffected = buffer[i]; ++i; } else ne->humanAffected = true; - ne->computerAffected = bufor[i]; ++i; - ne->firstOccurence = read_le_u16(bufor + i); i+=2; - ne->nextOccurence = bufor[i]; ++i; + ne->computerAffected = buffer[i]; ++i; + ne->firstOccurence = read_le_u16(buffer + i); i+=2; + ne->nextOccurence = buffer[i]; ++i; char unknown[17]; - memcpy(unknown, bufor+i, 17); + memcpy(unknown, buffer+i, 17); i+=17; events.push_back(ne); } } -bool Mapa::isInTheMap(const int3 &pos) const +bool CMap::isInTheMap(const int3 &pos) const { if(pos.x<0 || pos.y<0 || pos.z<0 || pos.x >= width || pos.y >= height || pos.z > twoLevel) return false; else return true; } -void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) +void CMap::loadQuest(IQuestObject * guard, const ui8 * buffer, int & i) { - guard->quest->missionType = bufor[i]; ++i; + guard->quest->missionType = buffer[i]; ++i; //int len1, len2, len3; switch(guard->quest->missionType) { @@ -1986,7 +2016,7 @@ void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) guard->quest->m2stats.resize(4); for(int x=0; x<4; x++) { - guard->quest->m2stats[x] = bufor[i++]; + guard->quest->m2stats[x] = buffer[i++]; } } break; @@ -1994,15 +2024,15 @@ void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) case 3: case 4: { - guard->quest->m13489val = read_le_u32(bufor + i); i+=4; + guard->quest->m13489val = read_le_u32(buffer + i); i+=4; break; } case 5: { - int artNumber = bufor[i]; ++i; + int artNumber = buffer[i]; ++i; for(int yy=0; yyquest->m5arts.push_back(artid); allowedArtifact[artid] = false; //these are unavailable for random generation } @@ -2010,12 +2040,12 @@ void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) } case 6: { - int typeNumber = bufor[i]; ++i; + int typeNumber = buffer[i]; ++i; guard->quest->m6creatures.resize(typeNumber); for(int hh=0; hhquest->m6creatures[hh].type = VLC->creh->creatures[read_le_u16(bufor + i)]; i+=2; - guard->quest->m6creatures[hh].count = read_le_u16(bufor + i); i+=2; + guard->quest->m6creatures[hh].type = VLC->creh->creatures[read_le_u16(buffer + i)]; i+=2; + guard->quest->m6creatures[hh].count = read_le_u16(buffer + i); i+=2; } break; } @@ -2024,7 +2054,7 @@ void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) guard->quest->m7resources.resize(7); for(int x=0; x<7; x++) { - guard->quest->m7resources[x] = read_le_u32(bufor + i); + guard->quest->m7resources[x] = read_le_u32(buffer + i); i+=4; } break; @@ -2032,13 +2062,13 @@ void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) case 8: case 9: { - guard->quest->m13489val = bufor[i]; ++i; + guard->quest->m13489val = buffer[i]; ++i; break; } } - int limit = read_le_u32(bufor + i); i+=4; + int limit = read_le_u32(buffer + i); i+=4; if(limit == ((int)0xffffffff)) { guard->quest->lastDay = -1; @@ -2047,32 +2077,32 @@ void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) { guard->quest->lastDay = limit; } - guard->quest->firstVisitText = readString(bufor,i); - guard->quest->nextVisitText = readString(bufor,i); - guard->quest->completedText = readString(bufor,i); + guard->quest->firstVisitText = readString(buffer,i); + guard->quest->nextVisitText = readString(buffer,i); + guard->quest->completedText = readString(buffer,i); guard->quest->isCustomFirst = guard->quest->firstVisitText.size() > 0; guard->quest->isCustomNext = guard->quest->nextVisitText.size() > 0; guard->quest->isCustomComplete = guard->quest->completedText.size() > 0; } -TerrainTile & Mapa::getTile( const int3 & tile ) +TerrainTile & CMap::getTile( const int3 & tile ) { return terrain[tile.x][tile.y][tile.z]; } -const TerrainTile & Mapa::getTile( const int3 & tile ) const +const TerrainTile & CMap::getTile( const int3 & tile ) const { return terrain[tile.x][tile.y][tile.z]; } -bool Mapa::isWaterTile(const int3 &pos) const +bool CMap::isWaterTile(const int3 &pos) const { - return isInTheMap(pos) && getTile(pos).tertype == TerrainTile::water; + return isInTheMap(pos) && getTile(pos).tertype == ETerrainType::WATER; } -const CGObjectInstance *Mapa::getObjectiveObjectFrom(int3 pos, bool lookForHero) +const CGObjectInstance *CMap::getObjectiveObjectFrom(int3 pos, bool lookForHero) { - const std::vector &objs = getTile(pos).visitableObjects; + const std::vector & objs = getTile(pos).visitableObjects; assert(objs.size()); if(objs.size() > 1 && lookForHero && objs.front()->ID != Obj::HERO) { @@ -2083,7 +2113,7 @@ const CGObjectInstance *Mapa::getObjectiveObjectFrom(int3 pos, bool lookForHero) return objs.front(); } -void Mapa::checkForObjectives() +void CMap::checkForObjectives() { if(isInTheMap(victoryCondition.pos)) victoryCondition.obj = getObjectiveObjectFrom(victoryCondition.pos, victoryCondition.condition == EVictoryConditionType::BEATHERO); @@ -2092,31 +2122,31 @@ void Mapa::checkForObjectives() lossCondition.obj = getObjectiveObjectFrom(lossCondition.pos, lossCondition.typeOfLossCon == ELossConditionType::LOSSHERO); } -void Mapa::addNewArtifactInstance( CArtifactInstance *art ) +void CMap::addNewArtifactInstance( CArtifactInstance *art ) { art->id = artInstances.size(); artInstances.push_back(art); } -void Mapa::addQuest (CGObjectInstance *obj) +void CMap::addQuest (CGObjectInstance * quest) { - auto q = dynamic_cast(obj); + auto q = dynamic_cast(quest); q->quest->qid = quests.size(); quests.push_back (q->quest); } -bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const ui8 * bufor, int &i) +bool CMap::loadArtifactToSlot(CGHeroInstance * hero, int slot, const ui8 * buffer, int & i) { - const int artmask = version == RoE ? 0xff : 0xffff; + const int artmask = version == EMapFormat::ROE ? 0xff : 0xffff; int aid; - if (version == RoE) + if (version == EMapFormat::ROE) { - aid = bufor[i]; i++; + aid = buffer[i]; i++; } else { - aid = read_le_u16(bufor + i); i+=2; + aid = read_le_u16(buffer + i); i+=2; } bool isArt = aid != artmask; @@ -2134,50 +2164,50 @@ bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const ui8 * bufor, in slot = ArtifactPosition::SPELLBOOK; } - h->putArtifact(slot, createArt(aid)); + hero->putArtifact(slot, createArt(aid)); } return isArt; } -void Mapa::loadArtifactsOfHero(const ui8 * bufor, int & i, CGHeroInstance * nhi) +void CMap::loadArtifactsOfHero(const ui8 * buffer, int & i, CGHeroInstance * hero) { - bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts) + bool artSet = buffer[i]; ++i; //true if artifact set is not default (hero has some artifacts) if(artSet) { for(int pom=0;pom<16;pom++) - loadArtifactToSlot(nhi, pom, bufor, i); + loadArtifactToSlot(hero, pom, buffer, i); //misc5 art //17 - if(version >= SoD) + if(version >= EMapFormat::SOD) { - if(!loadArtifactToSlot(nhi, ArtifactPosition::MACH4, bufor, i)) - nhi->putArtifact(ArtifactPosition::MACH4, createArt(GameConstants::ID_CATAPULT)); //catapult by default + if(!loadArtifactToSlot(hero, ArtifactPosition::MACH4, buffer, i)) + hero->putArtifact(ArtifactPosition::MACH4, createArt(GameConstants::ID_CATAPULT)); //catapult by default } - loadArtifactToSlot(nhi, ArtifactPosition::SPELLBOOK, bufor, i); + loadArtifactToSlot(hero, ArtifactPosition::SPELLBOOK, buffer, i); //19 //???what is that? gap in file or what? - it's probably fifth slot.. - if(version > RoE) - loadArtifactToSlot(nhi, ArtifactPosition::MISC5, bufor, i); + if(version > EMapFormat::ROE) + loadArtifactToSlot(hero, ArtifactPosition::MISC5, buffer, i); else i+=1; //bag artifacts //20 - int amount = read_le_u16(bufor + i); i+=2; //number of artifacts in hero's bag + int amount = read_le_u16(buffer + i); i+=2; //number of artifacts in hero's bag for(int ss = 0; ss < amount; ++ss) - loadArtifactToSlot(nhi, GameConstants::BACKPACK_START + nhi->artifactsInBackpack.size(), bufor, i); + loadArtifactToSlot(hero, GameConstants::BACKPACK_START + hero->artifactsInBackpack.size(), buffer, i); } //artifacts } -CArtifactInstance * Mapa::createArt(int aid, int spellID /*= -1*/) +CArtifactInstance * CMap::createArt(int aid, int spellID /*= -1*/) { CArtifactInstance *a = NULL; if(aid >= 0) { - if(spellID < 0) + if(spellID < 0) a = CArtifactInstance::createNewArtifactInstance(aid); else - a = CArtifactInstance::createScroll(VLC->spellh->spells[spellID]); + a = CArtifactInstance::createScroll(VLC->spellh->spells[spellID]); } else a = new CArtifactInstance(); @@ -2194,7 +2224,7 @@ CArtifactInstance * Mapa::createArt(int aid, int spellID /*= -1*/) return a; } -void Mapa::eraseArtifactInstance(CArtifactInstance *art) +void CMap::eraseArtifactInstance(CArtifactInstance *art) { assert(artInstances[art->id] == art); artInstances[art->id].dellNull(); @@ -2207,22 +2237,22 @@ LossCondition::LossCondition() pos = int3(-1,-1,-1); } -CVictoryCondition::CVictoryCondition() +VictoryCondition::VictoryCondition() { pos = int3(-1,-1,-1); obj = NULL; ID = allowNormalVictory = appliesToAI = count = 0; } -bool TerrainTile::entrableTerrain(const TerrainTile *from /*= NULL*/) const +bool TerrainTile::entrableTerrain(const TerrainTile * from /*= NULL*/) const { - return entrableTerrain(from ? from->tertype != water : true, from ? from->tertype == water : true); + return entrableTerrain(from ? from->tertype != ETerrainType::WATER : true, from ? from->tertype == ETerrainType::WATER : true); } bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const { - return tertype != rock - && ((allowSea && tertype == water) || (allowLand && tertype != water)); + return tertype != ETerrainType::ROCK + && ((allowSea && tertype == ETerrainType::WATER) || (allowLand && tertype != ETerrainType::WATER)); } bool TerrainTile::isClear(const TerrainTile *from /*= NULL*/) const @@ -2237,15 +2267,15 @@ int TerrainTile::topVisitableID() const bool TerrainTile::isCoastal() const { - return siodmyTajemniczyBajt & 64; + return extTileFlags & 64; } bool TerrainTile::hasFavourableWinds() const { - return siodmyTajemniczyBajt & 128; + return extTileFlags & 128; } bool TerrainTile::isWater() const { - return tertype == water; + return tertype == ETerrainType::WATER; } diff --git a/lib/map.h b/lib/map.h index ae4f075ff..af7c381db 100644 --- a/lib/map.h +++ b/lib/map.h @@ -35,104 +35,244 @@ class IQuestObject; class CInputStream; typedef std::unique_ptr TInputStreamPtr; -/// Struct which describes a single terrain tile +namespace ETerrainType +{ + enum ETerrainType + { + BORDER = -1, DIRT, SAND, GRASS, SNOW, SWAMP, + ROUGH, SUBTERRANEAN, LAVA, WATER, ROCK + }; +} + +namespace ERiverType +{ + enum ERiverType + { + NO_RIVER = 0, CLEAR_RIVER, ICY_RIVER, MUDDY_RIVER, LAVA_RIVER + }; +} + +namespace ERoadType +{ + enum ERoadType + { + DIRT_ROAD = 1, GRAVEL_ROAD, COBBLESTONE_ROAD + }; +} + +/** + * The terrain tile describes the terrain type and the visual representation of the terrain. + * Furthermore the struct defines whether the tile is visitable or/and blocked and which objects reside in it. + */ struct DLL_LINKAGE TerrainTile { - enum EterrainType {border=-1, dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock}; - enum Eriver {noRiver=0, clearRiver, icyRiver, muddyRiver, lavaRiver}; - enum Eroad {dirtRoad=1, grazvelRoad, cobblestoneRoad}; + /** the type of terrain */ + ETerrainType::ETerrainType tertype; - EterrainType tertype; // type of terrain - ui8 terview; // look of terrain - Eriver nuine; // type of Eriver (0 if there is no river) - ui8 rivDir; // direction of Eriver - Eroad malle; // type of Eroad (0 if there is no river) - ui8 roadDir; // direction of Eroad - ui8 siodmyTajemniczyBajt; //first two bits - how to rotate terrain graphic (next two - river graphic, next two - road); 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favourable Winds effect + /** the visual representation of the terrain */ + ui8 terview; - bool visitable; //false = not visitable; true = visitable - bool blocked; //false = free; true = blocked; + /** the type of the river. 0 if there is no river */ + ERiverType::ERiverType riverType; - std::vector visitableObjects; //pointers to objects hero can visit while being on this tile - std::vector blockingObjects; //pointers to objects that are blocking this tile + /** the direction of the river */ + ui8 riverDir; - template void serialize(Handler &h, const int version) - { - h & tertype & terview & nuine & rivDir & malle &roadDir & siodmyTajemniczyBajt & blocked; + /** the type of the road. 0 if there is no river */ + ERoadType::ERoadType roadType; - if(!h.saving) - { - visitable = false; - //these flags (and obj vectors) will be restored in map serialization - } - } + /** the direction of the road */ + ui8 roadDir; - bool entrableTerrain(const TerrainTile *from = NULL) const; //checks if terrain is not a rock. If from is water/land, same type is also required. - bool entrableTerrain(bool allowLand, bool allowSea) const; //checks if terrain is not a rock. If from is water/land, same type is also required. - bool isClear(const TerrainTile *from = NULL) const; //checks for blocking objs and terraint type (water / land) - int topVisitableID() const; //returns ID of the top visitable ovject or -1 if there is none + /** + * first two bits - how to rotate terrain graphic (next two - river graphic, next two - road); + * 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favourable Winds effect + */ + ui8 extTileFlags; + /** true if it is visitable, false if not */ + bool visitable; + + /** true if it is blocked, false if not */ + bool blocked; + + /** pointers to objects which the hero can visit while being on this tile */ + std::vector visitableObjects; + + /** pointers to objects that are blocking this tile */ + std::vector blockingObjects; + + /** + * Gets true if the terrain is not a rock. If from is water/land, same type is also required. + * + * @param from + * @return + */ + bool entrableTerrain(const TerrainTile * from = NULL) const; + + /** + * Gets true if the terrain is not a rock. If from is water/land, same type is also required. + * + * @param allowLand + * @param allowSea + * @return + */ + bool entrableTerrain(bool allowLand, bool allowSea) const; + + /** + * Checks for blocking objects and terraint type (water / land). + * + * @param from + * @return + */ + bool isClear(const TerrainTile * from = NULL) const; + + /** + * Gets the ID of the top visitable object or -1 if there is none. + * + * @return the ID of the top visitable object or -1 if there is none + */ + int topVisitableID() const; + + /** + * Gets true if the terrain type is water. + * + * @return true if the terrain type is water + */ bool isWater() const; + /** + * Gets true if the terrain tile is coastal. + * + * @return true if the terrain tile is coastal + */ bool isCoastal() const; + + /** + * Gets true if the terrain tile has favourable winds. + * + * @return true if the terrain tile has favourable winds + */ bool hasFavourableWinds() const; + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) + { + h & tertype & terview & riverType & riverDir & roadType &roadDir & extTileFlags & blocked; + + if(!h.saving) + { + visitable = false; + //these flags (and obj vectors) will be restored in map serialization + } + } }; -/// name of starting hero +/** + * The hero name struct consists of the hero id and name. + */ struct DLL_LINKAGE SheroName { + /** the id of the hero */ int heroID; + + /** the name of the hero */ std::string heroName; - template void serialize(Handler &h, const int version) + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { h & heroID & heroName; } }; -/// Player information regarding map. Which factions are allowed, AI tactic setting, main hero name, -/// position of main town,... +/** + * The player info constains data about which factions are allowed, AI tactical settings, + * main hero name, where to generate the hero, whether faction is random,... + */ struct DLL_LINKAGE PlayerInfo { - si32 p7, p8, p9; - ui8 powerPlacehodlers; //q-ty of hero placeholders containing hero type, WARNING: powerPlacehodlers sometimes gives false 0 (eg. even if there is one placeholder), maybe different meaning??? + /** unknown, unused */ + si32 p7; + + /** TODO ? */ + si32 p8; + + /** TODO ? */ + si32 p9; + + /** TODO unused, q-ty of hero placeholders containing hero type, WARNING: powerPlacehodlers sometimes gives false 0 (eg. even if there is one placeholder), maybe different meaning??? */ + ui8 powerPlacehodlers; + + /** player can be played by a human */ ui8 canHumanPlay; + + /** player can be played by the computer */ ui8 canComputerPlay; - ui32 AITactic; //(00 - random, 01 - warrior, 02 - builder, 03 - explorer) - std::set allowedFactions; //set with factions player can play with - ui8 isFactionRandom; - ui32 mainHeroPortrait; //it's ID of hero with chosen portrait; 255 if standard + + /** defines the tactical setting of the AI: 0 - random, 1 - warrior, 2 - builder, 3 - explorer */ + ui32 AITactic; + + /** IDs of allowed factions */ + std::set allowedFactions; + + /** unused. is the faction random */ + ui8 isFactionRandom; + + /** specifies the ID of hero with chosen portrait; 255 if standard */ + ui32 mainHeroPortrait; + + /** the name of the main hero */ std::string mainHeroName; + + /** list of available heroes */ std::vector heroesNames; + + /** has the player a main town */ ui8 hasMainTown; + + /** generates the hero at the main town */ ui8 generateHeroAtMainTown; + + /** the position of the main town */ int3 posOfMainTown; + + /** the team id to which the player belongs to */ ui8 team; + + /** unused. generates a hero */ ui8 generateHero; - PlayerInfo(): p7(0), p8(0), p9(0), canHumanPlay(0), canComputerPlay(0), - AITactic(0), isFactionRandom(0), - mainHeroPortrait(0), hasMainTown(0), generateHeroAtMainTown(0), - team(255), generateHero(0) {}; + /** + * Default constructor. + */ + PlayerInfo(); - si8 defaultCastle() const - { - assert(!allowedFactions.empty()); // impossible? + /** + * Gets the default faction id or -1 for a random faction. + * + * @return the default faction id or -1 for a random faction + */ + si8 defaultCastle() const; - if (allowedFactions.size() == 1) - return *allowedFactions.begin(); //only one faction s available - pick it - return -1; // set to random - } - si8 defaultHero() const - { - if ((generateHeroAtMainTown && hasMainTown) //we will generate hero in front of main town - || p8) //random hero - return -1; - else - return -2; - } + /** + * Gets -1 for random hero. + * + * @return -1 for random hero + */ + si8 defaultHero() const; - template void serialize(Handler &h, const int version) + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & AITactic & allowedFactions & isFactionRandom & mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown & @@ -140,283 +280,682 @@ struct DLL_LINKAGE PlayerInfo } }; -/// Small struct which holds information about the loss condition +/** + * The loss condition describes the condition to lose the game. (e.g. lose all own heroes/castles) + */ struct DLL_LINKAGE LossCondition { + /** specifies the condition type */ ELossConditionType::ELossConditionType typeOfLossCon; + /** the position of an object which mustn't be lost */ int3 pos; - si32 timeLimit; // in days; -1 if not used - const CGObjectInstance *obj; //set during map parsing: hero/town (depending on typeOfLossCon); NULL if not used + /** time limit in days, -1 if not used */ + si32 timeLimit; + /** set during map parsing: hero/town (depending on typeOfLossCon); nullptr if not used */ + const CGObjectInstance * obj; - template void serialize(Handler &h, const int version) + /** + * Default constructor. + */ + LossCondition(); + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { h & typeOfLossCon & pos & timeLimit & obj; } - - LossCondition(); }; -/// Small struct which holds information about the victory condition -struct DLL_LINKAGE CVictoryCondition +/** + * The victory condition describes the condition to win the game. (e.g. defeat all enemy heroes/castles, + * receive a specific artifact, ...) + */ +struct DLL_LINKAGE VictoryCondition { - EVictoryConditionType::EVictoryConditionType condition; //ID of condition - ui8 allowNormalVictory, appliesToAI; + /** specifies the condition type */ + EVictoryConditionType::EVictoryConditionType condition; - int3 pos; //pos of city to upgrade (3); pos of town to build grail, {-1,-1,-1} if not relevant (4); hero pos (5); town pos(6); monster pos (7); destination pos(8) - si32 ID; //artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8) - si32 count; //needed count for creatures (1) / resource (2); upgraded town hall level (3); + /** true if a normal victory is allowed (defeat all enemy towns, heroes) */ + ui8 allowNormalVictory; - const CGObjectInstance *obj; //object of specific monster / city / hero instance (NULL if not used); set during map parsing + /** true if this victory condition also applies to the AI */ + ui8 appliesToAI; - CVictoryCondition(); + /** pos of city to upgrade (3); pos of town to build grail, {-1,-1,-1} if not relevant (4); hero pos (5); town pos(6); monster pos (7); destination pos(8) */ + int3 pos; - template void serialize(Handler &h, const int version) + /** artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8) */ + si32 ID; + + /** needed count for creatures (1) / resource (2); upgraded town hall level (3); */ + si32 count; + + /** object of specific monster / city / hero instance (NULL if not used); set during map parsing */ + const CGObjectInstance * obj; + + /** + * Default constructor. + */ + VictoryCondition(); + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { h & condition & allowNormalVictory & appliesToAI & pos & ID & count & obj; } }; -/// Struct which holds a name and the rumor text +/** + * The rumor struct consists of a rumor name and text. + */ struct DLL_LINKAGE Rumor { - std::string name, text; + /** the name of the rumor */ + std::string name; - template void serialize(Handler &h, const int version) + /** the content of the rumor */ + std::string text; + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { h & name & text; } }; -/// Struct which describes who can hire this hero +/** + * The disposed hero struct describes which hero can be hired from which player. + */ struct DLL_LINKAGE DisposedHero { + /** the id of the hero */ ui32 ID; - ui16 portrait; //0xFF - default - std::string name; - ui8 players; //who can hire this hero (bitfield) - template void serialize(Handler &h, const int version) + /** the portrait id of the hero, 0xFF is default */ + ui16 portrait; + + /** the name of the hero */ + std::string name; + + /** who can hire this hero (bitfield) */ + ui8 players; + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { h & ID & portrait & name & players; } }; /// Class which manages map events. + +/** + * The map event is an event which gives or takes resources for a specific + * amount of players and can appear regularly or once a time. + */ class DLL_LINKAGE CMapEvent { public: - std::string name, message; - TResources resources; //gained / taken resources - ui8 players; //affected players - ui8 humanAffected; - ui8 computerAffected; - ui32 firstOccurence; - ui32 nextOccurence; //after nextOccurance day event will occur; if it it 0, event occures only one time; + /** the name of the event */ + std::string name; - template void serialize(Handler &h, const int version) + /** the message to display */ + std::string message; + + /** gained or taken resources */ + TResources resources; + + /** affected players */ + ui8 players; + + /** affected humans */ + ui8 humanAffected; + + /** affacted computer players */ + ui8 computerAffected; + + /** the day counted continously where the event happens */ + ui32 firstOccurence; + + /** specifies after how many days the event will occur the next time; 0 if event occurs only one time */ + ui32 nextOccurence; + + bool operator<(const CMapEvent &b) const + { + return firstOccurence < b.firstOccurence; + } + bool operator<=(const CMapEvent &b) const + { + return firstOccurence <= b.firstOccurence; + } + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { h & name & message & resources & players & humanAffected & computerAffected & firstOccurence & nextOccurence; } - bool operator<(const CMapEvent &b) const - { - return firstOccurence < b.firstOccurence; - } - bool operator<=(const CMapEvent &b) const - { - return firstOccurence <= b.firstOccurence; - } }; -/// Sub-class derived by CMapEvent; This event can build specific buildings or add -/// additional creatures in a town. +/** + * The castle event builds/adds buildings/creatures for a specific town. + */ class DLL_LINKAGE CCastleEvent: public CMapEvent { public: - std::set buildings;//build specific buildings - std::vector creatures;//additional creatures in i-th level dwelling - CGTownInstance * town;//owner of this event + /** build specific buildings */ + std::set buildings; - template void serialize(Handler &h, const int version) + /** additional creatures in i-th level dwelling */ + std::vector creatures; + + /** owner of this event */ + CGTownInstance * town; + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int version) { - h & static_cast(*this); + h & static_cast(*this); h & buildings & creatures; } }; -/// Holds information about loss/victory condition, map format, version, players, height, width,... +namespace EMapFormat +{ + enum EMapFormat + { + INVALID, WOG=0x33, AB=0x15, ROE=0x0e, SOD=0x1c + }; +} + +/** + * The map header holds information about loss/victory condition, + * map format, version, players, height, width,... + */ class DLL_LINKAGE CMapHeader { public: - enum Eformat {invalid, WoG=0x33, AB=0x15, RoE=0x0e, SoD=0x1c}; - Eformat version; // version of map Eformat - ui8 areAnyPLayers; // if there are any playable players on map - si32 height, width, twoLevel; //sizes - std::string name; //name of map - std::string description; //and description - ui8 difficulty; // 0 easy - 4 impossible - ui8 levelLimit; + /** + * Default constructor. + */ + CMapHeader(); + + /** + * Constructor. + * + * @param map a pointer to an buffer which contains bytes describing a map header + */ + CMapHeader(const ui8 * map); + + /** + * Destructor. + */ + virtual ~CMapHeader(); + + /** + * Initializes the map header from memory. + * + * @param buffer a pointer to an buffer which contains bytes describing a map header + * @param i the index where to start reading from + */ + void initFromMemory(const ui8 * buffer, int & i); + + /** + * Loads victory/loss conditions. + * + * @param buffer a pointer to an buffer which contains bytes describing a map header + * @param i the index where to start reading from + */ + void loadViCLossConditions(const ui8 * buffer, int & i); + + /** + * Loads information about players. + * + * @param pom + * @param buffer a pointer to an buffer which contains bytes describing a map header + * @param i the index where to start reading from + */ + void loadPlayerInfo(int & pom, const ui8 * buffer, int & i); + + /** the version of the map */ + EMapFormat::EMapFormat version; + + /** if there are any playable players on the map */ + ui8 areAnyPLayers; + + /** the height of the map */ + si32 height; + + /** the width of the map */ + si32 width; + + /** specifies if the map has two levels */ + si32 twoLevel; + + /** the name of the map */ + std::string name; + + /** the description of the map */ + std::string description; + + /** specifies the difficulty of the map ranging from 0 easy to 4 impossible */ + ui8 difficulty; + + /** specifies the maximum level to reach for a hero */ + ui8 levelLimit; + + /** the loss condition */ LossCondition lossCondition; - CVictoryCondition victoryCondition; //victory conditions - std::vector players; // info about players - size 8 + + /** the victory condition */ + VictoryCondition victoryCondition; + + /** list of player information */ + std::vector players; + + /** number of teams */ ui8 howManyTeams; - std::vector allowedHeroes; //allowedHeroes[hero_ID] - if the hero is allowed - std::vector placeholdedHeroes; //ID of types of heroes in placeholders - void initFromMemory(const ui8 *bufor, int &i); - void loadViCLossConditions( const ui8 * bufor, int &i); - void loadPlayerInfo( int &pom, const ui8 * bufor, int &i); - CMapHeader(const ui8 *map); //an argument is a reference to string described a map (unpacked) - CMapHeader(); - virtual ~CMapHeader(); + /** list of allowed heroes, index is hero id */ + std::vector allowedHeroes; - template void serialize(Handler &h, const int Version) + /** list of placeholded heroes, index is id of heroes types */ + std::vector placeholdedHeroes; + + /** + * Serialize method. + */ + template + void serialize(Handler & h, const int Version) { h & version & name & description & width & height & twoLevel & difficulty & levelLimit & areAnyPLayers; - h & players & lossCondition & victoryCondition & howManyTeams; + h & players & lossCondition & victoryCondition & howManyTeams & allowedHeroes; } }; -/// Extends the base class and adds further map information like rumors, disposed heroes, -/// allowed spells, artifacts, abilities and such things. -struct DLL_LINKAGE Mapa : public CMapHeader +/** + * The map contains the map header, the tiles of the terrain, objects, + * heroes, towns, rumors... + */ +class DLL_LINKAGE CMap : public CMapHeader { +public: + /** the checksum of the map */ ui32 checksum; + + /** a 3-dimensional array of terrain tiles, access is as follows: x, y, level */ TerrainTile*** terrain; + + /** list of rumors */ std::vector rumors; + + /** list of disposed heroes */ std::vector disposedHeroes; + + /** list of predefined heroes */ std::vector > predefinedHeroes; - std::vector > defy; // list of .def files with definitions from .h3m (may be custom) - std::vector allowedSpell; //allowedSpell[spell_ID] - if the spell is allowed - std::vector allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact is allowed - std::vector allowedAbilities; //allowedAbilities[ability_ID] - if the ability is allowed + + /** list of .def files with definitions from .h3m (may be custom) */ + std::vector > customDefs; + + /** list of allowed spells, index is the spell id */ + std::vector allowedSpell; + + /** list of allowed artifacts, index is the artifact id */ + std::vector allowedArtifact; + + /** list of allowed abilities, index is the ability id */ + std::vector allowedAbilities; + + /** list of map events */ std::list > events; + /** specifies the position of the grail */ int3 grailPos; + + /** specifies the radius of the grail */ int grailRadious; + /** list of objects */ std::vector< ConstTransitivePtr > objects; - std::vector< ConstTransitivePtr > heroes; - std::vector< ConstTransitivePtr > towns; - std::vector< ConstTransitivePtr > artInstances; //stores all artifacts - std::vector< ConstTransitivePtr > quests; //FIXME: allow to serialize quests not related to objects - //std::vector< ConstTransitivePtr > commanders; - //bmap > monsters; - //bmap > heroesToBeat; + /** list of heroes */ + std::vector< ConstTransitivePtr > heroes; + + /** list of towns */ + std::vector< ConstTransitivePtr > towns; + + /** list of artifacts */ + std::vector< ConstTransitivePtr > artInstances; + + /** list of quests */ + std::vector< ConstTransitivePtr > quests; + + /** associative list to identify which hero/creature id belongs to which object id(index for objects) */ bmap questIdentifierToId; - void initFromBytes( const ui8 * bufor, size_t size); //creates map from decompressed .h3m data + /** + * Creates map from decompressed .h3m data. + * + * @param buffer a pointer to an buffer which contains bytes describing a map + * @param size the length of the buffer + */ + void initFromBytes(const ui8 * buffer, size_t size); - void readEvents( const ui8 * bufor, int &i); - void readObjects( const ui8 * bufor, int &i); - void loadQuest( IQuestObject * guard, const ui8 * bufor, int & i); - void readDefInfo( const ui8 * bufor, int &i); - void readTerrain( const ui8 * bufor, int &i); - void readPredefinedHeroes( const ui8 * bufor, int &i); - void readHeader( const ui8 * bufor, int &i); - void readRumors( const ui8 * bufor, int &i); - CGObjectInstance *loadHero(const ui8 * bufor, int &i, int idToBeGiven); - void loadArtifactsOfHero(const ui8 * bufor, int & i, CGHeroInstance * nhi); - bool loadArtifactToSlot(CGHeroInstance *h, int slot, const ui8 * bufor, int &i); - void loadTown( CGObjectInstance * &nobj, const ui8 * bufor, int &i, int subid); - int loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj); + /** + * Reads events from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + */ + void readEvents(const ui8 * buffer, int & i); - CArtifactInstance *createArt(int aid, int spellID = -1); - void addNewArtifactInstance(CArtifactInstance *art); - void addQuest (CGObjectInstance *obj); - void eraseArtifactInstance(CArtifactInstance *art); + /** + * Reads objects from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing objects + * @param i the index where to start reading from + */ + void readObjects(const ui8 * buffer, int & i); + /** + * Loads quest information and stores that to a quest guard object. + * + * @param guard the quest guard object where the quest info should be applied to + * @param buffer a pointer to an buffer which contains bytes describing objects + * @param i the index where to start reading from + */ + void loadQuest(IQuestObject * guard, const ui8 * buffer, int & i); - const CGObjectInstance *getObjectiveObjectFrom(int3 pos, bool lookForHero); + /** + * Reads def information from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing def information + * @param i the index where to start reading from + */ + void readDefInfo(const ui8 * buffer, int & i); + + /** + * Reads terrain data from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing terrain data + * @param i the index where to start reading from + */ + void readTerrain(const ui8 * buffer, int & i); + + /** + * Reads predefined heroes from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + */ + void readPredefinedHeroes(const ui8 * buffer, int & i); + + /** + * Reads events from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + */ + void readHeader(const ui8 * buffer, int & i); + + /** + * Reads events from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + */ + void readRumors(const ui8 * buffer, int & i); + + /** + * Loads a hero from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + * @param idToBeGiven the object id which should be set for the hero + * @return a object instance + */ + CGObjectInstance * loadHero(const ui8 * buffer, int & i, int idToBeGiven); + + /** + * Loads artifacts of a hero from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + * @param hero the hero which should hold those artifacts + */ + void loadArtifactsOfHero(const ui8 * buffer, int & i, CGHeroInstance * hero); + + /** + * Loads an artifact from a buffer to the given slot of the specified hero. + * + * @param hero the hero which should hold that artifact + * @param slot the artifact slot where to place that artifact + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + * @return true if it loaded an artifact + */ + bool loadArtifactToSlot(CGHeroInstance * hero, int slot, const ui8 * buffer, int & i); + + /** + * Loads a town from a buffer. + * + * @param town a pointer to a town object which gets filled by data + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + * @param castleID the id of the castle type + */ + void loadTown(CGObjectInstance * & town, const ui8 * buffer, int & i, int castleID); + + /** + * Loads a seer hut from a buffer. + * + * @param buffer a pointer to an buffer which contains bytes describing events + * @param i the index where to start reading from + * @param seerHut the seer hut object which gets filled by data + * @return index of the reading position of the buffer + */ + int loadSeerHut(const ui8 * buffer, int i, CGObjectInstance * & seerHut); + + /** + * Creates an artifact instance. + * + * @param aid the id of the artifact + * @param spellID optional. the id of a spell if a spell scroll object should be created + * @return the created artifact instance + */ + CArtifactInstance * createArt(int aid, int spellID = -1); + + /** + * Adds the specified artifact instance to the list of artifacts of this map. + * + * @param art the artifact which should be added to the list of artifacts + */ + void addNewArtifactInstance(CArtifactInstance * art); + + /** + * Adds a quest to the list of quests of this map. + * + * @param quest the quest object which should be added to the list of quests + */ + void addQuest(CGObjectInstance * quest); + + /** + * Erases an artifact instance. + * + * @param art the artifact to erase + */ + void eraseArtifactInstance(CArtifactInstance * art); + + /** + * Gets the topmost object or the lowermost object depending on the flag + * lookForHero from the specified position. + * + * @param pos the position of the tile + * @param lookForHero true if you want to get the lowermost object, false if + * you want to get the topmost object + * @return the object at the given position and level + */ + const CGObjectInstance * getObjectiveObjectFrom(int3 pos, bool lookForHero); + + /** + * Sets the victory/loss condition objectives. + */ void checkForObjectives(); + + /** + * Adds an visitable/blocking object to a terrain tile. + * + * @param obj the visitable/blocking object to add to a tile + */ void addBlockVisTiles(CGObjectInstance * obj); - void removeBlockVisTiles(CGObjectInstance * obj, bool total=false); - Mapa(std::string filename); //creates map structure from .h3m file - Mapa(); - ~Mapa(); - TerrainTile &getTile(const int3 & tile); - const TerrainTile &getTile(const int3 & tile) const; - CGHeroInstance * getHero(int ID, int mode=0); - bool isInTheMap(const int3 &pos) const; - bool isWaterTile(const int3 &pos) const; //out-of-pos safe - static TInputStreamPtr getMapStream(std::string URI); + /** + * Removes an visitable/blocking object from a terrain tile. + * + * @param obj the visitable/blocking object to remove from a tile + * @param total + */ + void removeBlockVisTiles(CGObjectInstance * obj, bool total = false); - template void serialize(Handler &h, const int formatVersion) + /** + * Constructor. Creates a map from file. + * + * @param filename the name of the h3m map file + */ + CMap(std::string filename); + + /** + * Default constructor. + */ + CMap(); + + /** + * Destructor. + */ + ~CMap(); + + /** + * Gets the terrain tile of the specified position. + * + * @param tile the position of the tile + * @return the terrain tile of the specified position + */ + TerrainTile & getTile(const int3 & tile); + + /** + * Gets the terrain tile as a const of the specified position. + * + * @param tile the position of the tile + * @return the terrain tile as a const of the specified position + */ + const TerrainTile & getTile(const int3 & tile) const; + + /** + * Gets the hero with the given id. + * @param heroID the hero id + * @return the hero with the given id + */ + CGHeroInstance * getHero(int heroID); + + /** + * Validates if the position is in the bounds of the map. + * + * @param pos the position to test + * @return true if the position is in the bounds of the map + */ + bool isInTheMap(const int3 & pos) const; + + /** + * Validates if the tile at the given position is a water terrain type. + * + * @param pos the position to test + * @return true if the tile at the given position is a water terrain type + */ + bool isWaterTile(const int3 & pos) const; + + /** + * Gets a input stream from the given map name. + * + * @param name the name of the map + * @return a unique ptr to the input stream + */ + static TInputStreamPtr getMapStream(std::string name); + + /** + * Serialize method. + */ + template + void serialize(Handler &h, const int formatVersion) { h & static_cast(*this); - h & rumors & allowedSpell & allowedAbilities & allowedArtifact & allowedHeroes & events & grailPos; - h & artInstances & quests; //hopefully serialization is now automagical? - h & questIdentifierToId; + h & rumors & allowedSpell & allowedAbilities & allowedArtifact & events & grailPos; + h & artInstances & quests; + h & questIdentifierToId; //TODO: viccondetails if(h.saving) { - //saving terrain - for (int i = 0; i < width ; i++) - for (int j = 0; j < height ; j++) - for (int k = 0; k <= twoLevel ; k++) + // Save terrain + for(int i = 0; i < width ; ++i) + { + for(int j = 0; j < height ; ++j) + { + for(int k = 0; k <= twoLevel; ++k) + { h & terrain[i][j][k]; + } + } + } } else { - //loading terrain - terrain = new TerrainTile**[width]; // allocate memory - for (int ii=0;ii defs; -// -// if(h.saving) //create vector with all defs used on map -// { -// for(ui32 i=0; idefInfo->serial = -1; //set serial to serial -1 - indicates that def is not present in defs vector -// -// for(ui32 i=0; idefInfo; -// if(cur->serial < 0) -// { -// cur->serial = defs.size(); -// defs.push_back(cur); -// } -// } -// } -// -// h & ((h.saving) ? defs : defy); - -// //objects -// if(h.saving) -// { -// ui32 hlp = objects.size(); -// h & hlp; -// } -// else -// { -// ui32 hlp; -// h & hlp; -// objects.resize(hlp); -// } - - //static members + // static members h & CGTeleport::objs; h & CGTeleport::gates; h & CGKeys::playerKeyMap; @@ -424,25 +963,9 @@ struct DLL_LINKAGE Mapa : public CMapHeader h & CGObelisk::obeliskCount & CGObelisk::visited; h & CGTownInstance::merchantArtifacts; -// for(ui32 i=0; idefInfo->serial) : shlp); //read / write pos of definfo in defs vector -// if(!h.saving) -// obj->defInfo = defy[shlp]; -// } -// } - if(!h.saving) { - - for(ui32 i=0; i(+objects[i])); break; } - addBlockVisTiles(objects[i]); //recreate blockvis map - } - for(ui32 i=0; ipos; vistile.x++; - for(ui32 j=0; jpos; + vistile.x++; + for(ui32 j = 0; j < towns.size(); ++j) { - if(vistile == towns[j]->pos) //hero stands on the town entrance + // hero stands on the town entrance + if(vistile == towns[j]->pos) { if(heroes[i]->inTownGarrison) { @@ -480,21 +1009,22 @@ struct DLL_LINKAGE Mapa : public CMapHeader } vistile.x -= 2; //manifest pos - const TerrainTile &t = getTile(vistile); - if(t.tertype != TerrainTile::water) continue; + const TerrainTile & t = getTile(vistile); + if(t.tertype != ETerrainType::WATER) continue; + //hero stands on the water - he must be in the boat - for(ui32 j = 0; j < t.visitableObjects.size(); j++) + for(ui32 j = 0; j < t.visitableObjects.size(); ++j) { if(t.visitableObjects[j]->ID == Obj::BOAT) { - CGBoat *b = static_cast(t.visitableObjects[j]); + CGBoat * b = static_cast(t.visitableObjects[j]); heroes[i]->boat = b; b->hero = heroes[i]; removeBlockVisTiles(b); break; } } - } //heroes loop - } //!saving + } + } } }; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index fb1e34c81..70589f2ae 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1229,7 +1229,7 @@ void CGameHandler::newTurn() NewTurn::Hero hth; hth.id = h->id; - hth.move = h->maxMovePoints(gs->map->getTile(h->getPosition(false)).tertype != TerrainTile::water); + hth.move = h->maxMovePoints(gs->map->getTile(h->getPosition(false)).tertype != ETerrainType::WATER); if(h->visitedTown && h->visitedTown->hasBuilt(EBuilding::MAGES_GUILD_1)) //if hero starts turn in town with mage guild hth.mana = std::max(h->mana, h->manaLimit()); //restore all mana @@ -1671,11 +1671,11 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255* //it's a rock or blocked and not visitable tile //OR hero is on land and dest is water and (there is not present only one object - boat) - if(((t.tertype == TerrainTile::rock || (t.blocked && !t.visitable && !h->hasBonusOfType(Bonus::FLYING_MOVEMENT) )) + if(((t.tertype == ETerrainType::ROCK || (t.blocked && !t.visitable && !h->hasBonusOfType(Bonus::FLYING_MOVEMENT) )) && complain("Cannot move hero, destination tile is blocked!")) - || ((!h->boat && !h->canWalkOnSea() && t.tertype == TerrainTile::water && (t.visitableObjects.size() < 1 || (t.visitableObjects.back()->ID != 8 && t.visitableObjects.back()->ID != Obj::HERO))) //hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276) + || ((!h->boat && !h->canWalkOnSea() && t.tertype == ETerrainType::WATER && (t.visitableObjects.size() < 1 || (t.visitableObjects.back()->ID != 8 && t.visitableObjects.back()->ID != Obj::HERO))) //hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276) && complain("Cannot move hero, destination tile is on water!")) - || ((h->boat && t.tertype != TerrainTile::water && t.blocked) + || ((h->boat && t.tertype != ETerrainType::WATER && t.blocked) && complain("Cannot disembark hero, tile is blocked!")) || ((h->movement < cost && dst != h->pos && !instant) && complain("Hero doesn't have any movement points left!")) @@ -1697,7 +1697,7 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255* return true; } //hero leaves the boat - else if(h->boat && t.tertype != TerrainTile::water && !t.blocked) + else if(h->boat && t.tertype != ETerrainType::WATER && !t.blocked) { //TODO? code similarity with the block above tmh.result = TryMoveHero::DISEMBARK;