2010-12-17 20:47:07 +02:00
2009-04-15 17:03:31 +03:00
/*
2012-11-03 16:30:47 +03:00
* CMap . h , part of VCMI engine
2009-04-15 17:03:31 +03:00
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
2012-11-03 16:30:47 +03:00
# pragma once
# ifndef _MSC_VER
# include "../CObjectHandler.h"
# include "../CDefObjInfoHandler.h"
# endif
# include "../ConstTransitivePtr.h"
# include "../ResourceSet.h"
# include "../int3.h"
# include "../GameConstants.h"
2010-12-17 20:47:07 +02:00
class CArtifactInstance ;
2008-12-27 03:01:59 +02:00
class CGDefInfo ;
class CGObjectInstance ;
class CGHeroInstance ;
2012-04-22 20:38:36 +03:00
class CCommanderInstance ;
2010-02-02 19:05:03 +02:00
class CGCreature ;
2008-12-27 03:01:59 +02:00
class CQuest ;
class CGTownInstance ;
2010-11-10 02:06:25 +02:00
class IModableArt ;
2012-09-16 16:34:01 +03:00
class IQuestObject ;
2012-09-26 16:13:39 +03:00
class CInputStream ;
2012-10-26 20:51:05 +03:00
namespace ETerrainType
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
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
} ;
}
2011-09-19 23:50:25 +03:00
2012-10-26 20:51:05 +03:00
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
{
/** the type of terrain */
ETerrainType : : ETerrainType tertype ;
/** the visual representation of the terrain */
ui8 terview ;
/** the type of the river. 0 if there is no river */
ERiverType : : ERiverType riverType ;
/** the direction of the river */
ui8 riverDir ;
/** the type of the road. 0 if there is no river */
ERoadType : : ERoadType roadType ;
/** the direction of the road */
ui8 roadDir ;
/**
* first two bits - how to rotate terrain graphic ( next two - river graphic , next two - road ) ;
* 7 th bit - whether tile is coastal ( allows disembarking if land or block movement if water ) ; 8 th 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 < CGObjectInstance * > visitableObjects ;
/** pointers to objects that are blocking this tile */
std : : vector < CGObjectInstance * > 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
*/
2012-11-03 16:30:47 +03:00
bool isWater ( ) const ;
2012-01-03 04:55:26 +03:00
2012-10-26 20:51:05 +03:00
/**
* Gets true if the terrain tile is coastal .
*
* @ return true if the terrain tile is coastal
*/
2012-11-03 16:30:47 +03:00
bool isCoastal ( ) const ;
2012-10-26 20:51:05 +03:00
/**
* Gets true if the terrain tile has favourable winds .
*
* @ return true if the terrain tile has favourable winds
*/
2012-11-03 16:30:47 +03:00
bool hasFavourableWinds ( ) const ;
2012-10-26 20:51:05 +03:00
/**
* Serialize method .
*/
template < typename Handler >
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
}
}
2008-12-27 03:01:59 +02:00
} ;
2011-02-22 13:52:36 +02:00
2012-10-26 20:51:05 +03:00
/**
* The hero name struct consists of the hero id and name .
*/
2012-11-03 16:30:47 +03:00
struct DLL_LINKAGE SheroName
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
/** the id of the hero */
2012-11-03 16:30:47 +03:00
int heroID ;
2012-10-26 20:51:05 +03:00
/** the name of the hero */
2012-11-03 16:30:47 +03:00
std : : string heroName ;
2008-12-27 03:01:59 +02:00
2012-10-26 20:51:05 +03:00
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
h & heroID & heroName ;
}
2008-12-27 03:01:59 +02:00
} ;
2011-02-22 13:52:36 +02:00
2012-10-26 20:51:05 +03:00
/**
* 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 , . . .
*/
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE PlayerInfo
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
/** 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 */
2012-11-03 16:30:47 +03:00
ui8 canHumanPlay ;
2012-10-26 20:51:05 +03:00
/** player can be played by the computer */
2012-11-03 16:30:47 +03:00
ui8 canComputerPlay ;
2012-10-26 20:51:05 +03:00
/** defines the tactical setting of the AI: 0 - random, 1 - warrior, 2 - builder, 3 - explorer */
ui32 AITactic ;
/** IDs of allowed factions */
std : : set < ui32 > 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 */
2012-11-03 16:30:47 +03:00
std : : string mainHeroName ;
2012-10-26 20:51:05 +03:00
/** list of available heroes */
2012-11-03 16:30:47 +03:00
std : : vector < SheroName > heroesNames ;
2012-10-26 20:51:05 +03:00
/** has the player a main town */
2012-11-03 16:30:47 +03:00
ui8 hasMainTown ;
2012-10-26 20:51:05 +03:00
/** generates the hero at the main town */
2012-11-03 16:30:47 +03:00
ui8 generateHeroAtMainTown ;
2008-12-27 03:01:59 +02:00
2012-10-26 20:51:05 +03:00
/** the position of the main town */
2012-11-03 16:30:47 +03:00
int3 posOfMainTown ;
2009-05-29 06:53:53 +03:00
2012-10-26 20:51:05 +03:00
/** the team id to which the player belongs to */
2012-11-03 16:30:47 +03:00
ui8 team ;
2012-10-06 11:47:13 +03:00
2012-10-26 20:51:05 +03:00
/** unused. generates a hero */
2012-11-03 16:30:47 +03:00
ui8 generateHero ;
2010-10-24 14:35:14 +03:00
2012-10-26 20:51:05 +03:00
/**
* Default constructor .
*/
PlayerInfo ( ) ;
/**
* 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 ;
/**
* Gets - 1 for random hero .
*
* @ return - 1 for random hero
*/
si8 defaultHero ( ) const ;
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & AITactic & allowedFactions & isFactionRandom &
mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
posOfMainTown & team & generateHero ;
}
2008-12-27 03:01:59 +02:00
} ;
2011-02-22 13:52:36 +02:00
2012-10-26 20:51:05 +03:00
/**
* The loss condition describes the condition to lose the game . ( e . g . lose all own heroes / castles )
*/
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE LossCondition
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
/** specifies the condition type */
2012-11-03 16:30:47 +03:00
ELossConditionType : : ELossConditionType typeOfLossCon ;
2010-01-29 22:52:45 +02:00
2012-10-26 20:51:05 +03:00
/** the position of an object which mustn't be lost */
2012-11-03 16:30:47 +03:00
int3 pos ;
2010-01-29 22:52:45 +02:00
2012-10-26 20:51:05 +03:00
/** time limit in days, -1 if not used */
si32 timeLimit ;
2010-01-29 22:52:45 +02:00
2012-10-26 20:51:05 +03:00
/** set during map parsing: hero/town (depending on typeOfLossCon); nullptr if not used */
const CGObjectInstance * obj ;
2008-12-27 03:01:59 +02:00
2012-10-26 20:51:05 +03:00
/**
* Default constructor .
*/
LossCondition ( ) ;
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
h & typeOfLossCon & pos & timeLimit & obj ;
}
2008-12-27 03:01:59 +02:00
} ;
2011-02-22 13:52:36 +02:00
2012-10-26 20:51:05 +03:00
/**
* 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
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
/** specifies the condition type */
EVictoryConditionType : : EVictoryConditionType condition ;
/** true if a normal victory is allowed (defeat all enemy towns, heroes) */
ui8 allowNormalVictory ;
/** true if this victory condition also applies to the AI */
ui8 appliesToAI ;
/** 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 ;
2009-01-06 20:42:20 +02:00
2012-10-26 20:51:05 +03:00
/** artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8) */
si32 ID ;
2009-01-06 20:42:20 +02:00
2012-10-26 20:51:05 +03:00
/** needed count for creatures (1) / resource (2); upgraded town hall level (3); */
si32 count ;
2010-01-29 22:52:45 +02:00
2012-10-26 20:51:05 +03:00
/** object of specific monster / city / hero instance (NULL if not used); set during map parsing */
const CGObjectInstance * obj ;
2009-01-06 20:42:20 +02:00
2012-10-26 20:51:05 +03:00
/**
* Default constructor .
*/
VictoryCondition ( ) ;
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
h & condition & allowNormalVictory & appliesToAI & pos & ID & count & obj ;
}
2008-12-27 03:01:59 +02:00
} ;
2009-01-06 20:42:20 +02:00
2012-10-26 20:51:05 +03:00
/**
* The rumor struct consists of a rumor name and text .
*/
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE Rumor
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
/** the name of the rumor */
std : : string name ;
2008-12-27 03:01:59 +02:00
2012-10-26 20:51:05 +03:00
/** the content of the rumor */
std : : string text ;
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
h & name & text ;
}
2008-12-27 03:01:59 +02:00
} ;
2012-10-26 20:51:05 +03:00
/**
* The disposed hero struct describes which hero can be hired from which player .
*/
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE DisposedHero
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
/** the id of the hero */
2012-11-03 16:30:47 +03:00
ui32 ID ;
2012-10-26 20:51:05 +03:00
/** the portrait id of the hero, 0xFF is default */
ui16 portrait ;
/** the name of the hero */
2012-11-03 16:30:47 +03:00
std : : string name ;
2008-12-27 03:01:59 +02:00
2012-10-26 20:51:05 +03:00
/** who can hire this hero (bitfield) */
ui8 players ;
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
h & ID & portrait & name & players ;
}
2008-12-27 03:01:59 +02:00
} ;
2011-02-22 13:52:36 +02:00
/// Class which manages map events.
2012-10-26 20:51:05 +03:00
/**
* 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 .
*/
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CMapEvent
2008-12-27 03:01:59 +02:00
{
public :
2012-10-26 20:51:05 +03:00
/** the name of the event */
std : : string name ;
/** the message to display */
std : : string message ;
/** gained or taken resources */
TResources resources ;
/** affected players */
ui8 players ;
/** affected humans */
2012-11-03 16:30:47 +03:00
ui8 humanAffected ;
2012-10-26 20:51:05 +03:00
/** affacted computer players */
2012-11-03 16:30:47 +03:00
ui8 computerAffected ;
2012-10-26 20:51:05 +03:00
/** the day counted continously where the event happens */
2012-11-03 16:30:47 +03:00
ui32 firstOccurence ;
2010-08-18 17:24:30 +03:00
2012-10-26 20:51:05 +03:00
/** 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 < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
h & name & message & resources
& players & humanAffected & computerAffected & firstOccurence & nextOccurence ;
}
2008-12-27 03:01:59 +02:00
} ;
2010-08-18 17:24:30 +03:00
2012-10-26 20:51:05 +03:00
/**
* The castle event builds / adds buildings / creatures for a specific town .
*/
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CCastleEvent : public CMapEvent
2010-08-18 17:24:30 +03:00
{
public :
2012-10-26 20:51:05 +03:00
/** build specific buildings */
std : : set < si32 > buildings ;
/** additional creatures in i-th level dwelling */
std : : vector < si32 > creatures ;
2010-08-18 17:24:30 +03:00
2012-10-26 20:51:05 +03:00
/** owner of this event */
CGTownInstance * town ;
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int version )
2012-11-03 16:30:47 +03:00
{
2012-10-26 20:51:05 +03:00
h & static_cast < CMapEvent & > ( * this ) ;
2012-11-03 16:30:47 +03:00
h & buildings & creatures ;
}
2010-08-18 17:24:30 +03:00
} ;
2012-10-26 20:51:05 +03:00
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 , . . .
*/
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CMapHeader
2008-12-27 03:01:59 +02:00
{
public :
2012-10-26 20:51:05 +03:00
/**
* Default constructor .
*/
CMapHeader ( ) ;
/**
2012-11-03 16:30:47 +03:00
* D - tor .
2012-10-26 20:51:05 +03:00
*/
virtual ~ CMapHeader ( ) ;
/** 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 */
2012-11-03 16:30:47 +03:00
LossCondition lossCondition ;
2012-10-26 20:51:05 +03:00
/** the victory condition */
VictoryCondition victoryCondition ;
/** list of player information */
std : : vector < PlayerInfo > players ;
/** number of teams */
2012-11-03 16:30:47 +03:00
ui8 howManyTeams ;
2009-01-11 00:08:18 +02:00
2012-10-26 20:51:05 +03:00
/** list of allowed heroes, index is hero id */
std : : vector < ui8 > allowedHeroes ;
2009-01-11 00:08:18 +02:00
2012-10-26 20:51:05 +03:00
/** list of placeholded heroes, index is id of heroes types */
std : : vector < ui16 > placeholdedHeroes ;
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int Version )
2012-11-03 16:30:47 +03:00
{
h & version & name & description & width & height & twoLevel & difficulty & levelLimit & areAnyPLayers ;
2012-10-26 20:51:05 +03:00
h & players & lossCondition & victoryCondition & howManyTeams & allowedHeroes ;
2012-11-03 16:30:47 +03:00
}
2008-12-27 03:01:59 +02:00
} ;
2009-01-06 20:42:20 +02:00
2012-10-26 20:51:05 +03:00
/**
* The map contains the map header , the tiles of the terrain , objects ,
* heroes , towns , rumors . . .
*/
class DLL_LINKAGE CMap : public CMapHeader
2008-12-27 03:01:59 +02:00
{
2012-10-26 20:51:05 +03:00
public :
/**
2012-11-03 16:30:47 +03:00
* Default constructor .
2012-10-26 20:51:05 +03:00
*/
2012-11-03 16:30:47 +03:00
CMap ( ) ;
2012-10-26 20:51:05 +03:00
/**
2012-11-03 16:30:47 +03:00
* Destructor .
2012-10-26 20:51:05 +03:00
*/
2012-11-03 16:30:47 +03:00
~ CMap ( ) ;
2012-10-26 20:51:05 +03:00
/**
* 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 .
*/
2012-11-03 16:30:47 +03:00
void checkForObjectives ( ) ;
2012-10-26 20:51:05 +03:00
/**
* Adds an visitable / blocking object to a terrain tile .
*
* @ param obj the visitable / blocking object to add to a tile
*/
2012-11-03 16:30:47 +03:00
void addBlockVisTiles ( CGObjectInstance * obj ) ;
2012-10-26 20:51:05 +03:00
/**
* 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 ) ;
/**
* 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 ;
/**
2012-11-03 16:30:47 +03:00
* Adds the specified artifact instance to the list of artifacts of this map .
2012-10-26 20:51:05 +03:00
*
2012-11-03 16:30:47 +03:00
* @ param art the artifact which should be added to the list of artifacts
2012-10-26 20:51:05 +03:00
*/
2012-11-03 16:30:47 +03:00
void addNewArtifactInstance ( CArtifactInstance * art ) ;
/** 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 < Rumor > rumors ;
/** list of disposed heroes */
std : : vector < DisposedHero > disposedHeroes ;
/** list of predefined heroes */
std : : vector < ConstTransitivePtr < CGHeroInstance > > predefinedHeroes ;
/** list of .def files with definitions from .h3m (may be custom) */
std : : vector < ConstTransitivePtr < CGDefInfo > > customDefs ;
/** list of allowed spells, index is the spell id */
std : : vector < ui8 > allowedSpell ;
/** list of allowed artifacts, index is the artifact id */
std : : vector < ui8 > allowedArtifact ;
/** list of allowed abilities, index is the ability id */
std : : vector < ui8 > allowedAbilities ;
/** list of map events */
std : : list < ConstTransitivePtr < CMapEvent > > events ;
/** specifies the position of the grail */
int3 grailPos ;
/** specifies the radius of the grail */
int grailRadious ;
/** list of objects */
std : : vector < ConstTransitivePtr < CGObjectInstance > > objects ;
/** list of heroes */
std : : vector < ConstTransitivePtr < CGHeroInstance > > heroes ;
/** list of towns */
std : : vector < ConstTransitivePtr < CGTownInstance > > towns ;
/** list of artifacts */
std : : vector < ConstTransitivePtr < CArtifactInstance > > artInstances ;
/** list of quests */
std : : vector < ConstTransitivePtr < CQuest > > quests ;
/** associative list to identify which hero/creature id belongs to which object id(index for objects) */
bmap < si32 , si32 > questIdentifierToId ;
2012-10-26 20:51:05 +03:00
/**
* Serialize method .
*/
template < typename Handler >
void serialize ( Handler & h , const int formatVersion )
2012-11-03 16:30:47 +03:00
{
h & static_cast < CMapHeader & > ( * this ) ;
2012-10-26 20:51:05 +03:00
h & rumors & allowedSpell & allowedAbilities & allowedArtifact & events & grailPos ;
h & artInstances & quests ;
h & questIdentifierToId ;
2009-01-06 20:42:20 +02:00
2012-11-03 16:30:47 +03:00
//TODO: viccondetails
if ( h . saving )
{
2012-10-26 20:51:05 +03:00
// Save terrain
for ( int i = 0 ; i < width ; + + i )
{
for ( int j = 0 ; j < height ; + + j )
{
for ( int k = 0 ; k < = twoLevel ; + + k )
{
2012-11-03 16:30:47 +03:00
h & terrain [ i ] [ j ] [ k ] ;
2012-10-26 20:51:05 +03:00
}
}
}
2012-11-03 16:30:47 +03:00
}
else
{
2012-10-26 20:51:05 +03:00
// Load terrain
terrain = new TerrainTile * * [ width ] ;
for ( int ii = 0 ; ii < width ; + + ii )
2012-11-03 16:30:47 +03:00
{
2012-10-26 20:51:05 +03:00
terrain [ ii ] = new TerrainTile * [ height ] ;
for ( int jj = 0 ; jj < height ; + + jj )
{
terrain [ ii ] [ jj ] = new TerrainTile [ twoLevel + 1 ] ;
}
2012-11-03 16:30:47 +03:00
}
2012-10-26 20:51:05 +03:00
for ( int i = 0 ; i < width ; + + i )
{
for ( int j = 0 ; j < height ; + + j )
{
for ( int k = 0 ; k < = twoLevel ; + + k )
{
2012-11-03 16:30:47 +03:00
h & terrain [ i ] [ j ] [ k ] ;
2012-10-26 20:51:05 +03:00
}
}
}
2012-11-03 16:30:47 +03:00
}
2012-10-26 20:51:05 +03:00
h & customDefs & objects ;
// static members
2012-11-03 16:30:47 +03:00
h & CGTeleport : : objs ;
h & CGTeleport : : gates ;
h & CGKeys : : playerKeyMap ;
h & CGMagi : : eyelist ;
h & CGObelisk : : obeliskCount & CGObelisk : : visited ;
h & CGTownInstance : : merchantArtifacts ;
if ( ! h . saving )
{
2012-10-26 20:51:05 +03:00
for ( ui32 i = 0 ; i < objects . size ( ) ; + + i )
2012-11-03 16:30:47 +03:00
{
if ( ! objects [ i ] ) continue ;
switch ( objects [ i ] - > ID )
{
case Obj : : HERO :
heroes . push_back ( static_cast < CGHeroInstance * > ( + objects [ i ] ) ) ;
break ;
case Obj : : TOWN :
towns . push_back ( static_cast < CGTownInstance * > ( + objects [ i ] ) ) ;
break ;
}
2012-10-26 20:51:05 +03:00
// recreate blockvis map
addBlockVisTiles ( objects [ i ] ) ;
}
// if hero is visiting/garrisoned in town set appropriate pointers
for ( ui32 i = 0 ; i < heroes . size ( ) ; + + i )
2012-11-03 16:30:47 +03:00
{
2012-10-26 20:51:05 +03:00
int3 vistile = heroes [ i ] - > pos ;
vistile . x + + ;
for ( ui32 j = 0 ; j < towns . size ( ) ; + + j )
2012-11-03 16:30:47 +03:00
{
2012-10-26 20:51:05 +03:00
// hero stands on the town entrance
if ( vistile = = towns [ j ] - > pos )
2012-11-03 16:30:47 +03:00
{
if ( heroes [ i ] - > inTownGarrison )
{
towns [ j ] - > garrisonHero = heroes [ i ] ;
removeBlockVisTiles ( heroes [ i ] ) ;
}
else
{
towns [ j ] - > visitingHero = heroes [ i ] ;
}
heroes [ i ] - > visitedTown = towns [ j ] ;
break ;
}
}
vistile . x - = 2 ; //manifest pos
2012-10-26 20:51:05 +03:00
const TerrainTile & t = getTile ( vistile ) ;
if ( t . tertype ! = ETerrainType : : WATER ) continue ;
2012-11-03 16:30:47 +03:00
//hero stands on the water - he must be in the boat
2012-10-26 20:51:05 +03:00
for ( ui32 j = 0 ; j < t . visitableObjects . size ( ) ; + + j )
2012-11-03 16:30:47 +03:00
{
if ( t . visitableObjects [ j ] - > ID = = Obj : : BOAT )
{
2012-10-26 20:51:05 +03:00
CGBoat * b = static_cast < CGBoat * > ( t . visitableObjects [ j ] ) ;
2012-11-03 16:30:47 +03:00
heroes [ i ] - > boat = b ;
b - > hero = heroes [ i ] ;
removeBlockVisTiles ( b ) ;
break ;
}
}
2012-10-26 20:51:05 +03:00
}
}
2012-11-03 16:30:47 +03:00
}
2008-12-27 03:01:59 +02:00
} ;