2011-12-14 00:23:17 +03:00
# pragma once
2009-01-30 20:36:00 +02:00
# ifndef _MSC_VER
2010-12-20 23:22:53 +02:00
# include "CObjectHandler.h"
# include "CDefObjInfoHandler.h"
2009-01-30 20:36:00 +02:00
# endif
2009-04-15 17:03:31 +03:00
2010-12-17 20:47:07 +02:00
# include "ConstTransitivePtr.h"
2011-07-05 09:14:07 +03:00
# include "ResourceSet.h"
2011-12-14 00:23:17 +03:00
# include "int3.h"
# include "GameConstants.h"
2010-12-17 20:47:07 +02:00
2009-04-15 17:03:31 +03:00
/*
* map . h , part of VCMI engine
*
* 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
*
*/
2010-12-17 20:47:07 +02:00
class CArtifactInstance ;
2008-12-27 03:01:59 +02:00
class CGDefInfo ;
class CGObjectInstance ;
class CGHeroInstance ;
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 ;
2008-12-27 03:01:59 +02:00
2011-02-22 13:52:36 +02:00
/// Struct which describes a single terrain tile
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE TerrainTile
2008-12-27 03:01:59 +02:00
{
2009-05-07 20:20:41 +03:00
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 } ;
2008-12-27 03:01:59 +02:00
EterrainType tertype ; // type of terrain
2011-12-14 00:23:17 +03:00
ui8 terview ; // look of terrain
2009-12-22 23:53:50 +02:00
Eriver nuine ; // type of Eriver (0 if there is no river)
2011-12-14 00:23:17 +03:00
ui8 rivDir ; // direction of Eriver
2009-12-22 23:53:50 +02:00
Eroad malle ; // type of Eroad (0 if there is no river)
2011-12-14 00:23:17 +03:00
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
2008-12-27 03:01:59 +02:00
bool visitable ; //false = not visitable; true = visitable
bool blocked ; //false = free; true = blocked;
std : : vector < CGObjectInstance * > visitableObjects ; //pointers to objects hero can visit while being on this tile
std : : vector < CGObjectInstance * > blockingObjects ; //pointers to objects that are blocking this tile
template < typename Handler > void serialize ( Handler & h , const int version )
{
2012-03-03 15:42:53 +03:00
h & tertype & terview & nuine & rivDir & malle & roadDir & siodmyTajemniczyBajt & blocked ;
2009-01-06 20:42:20 +02:00
if ( ! h . saving )
{
2012-03-03 15:42:53 +03:00
visitable = false ;
2009-01-06 20:42:20 +02:00
//these flags (and obj vectors) will be restored in map serialization
}
2008-12-27 03:01:59 +02:00
}
2010-03-21 00:17:19 +02:00
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)
2011-09-19 23:50:25 +03:00
int topVisitableID ( ) const ; //returns ID of the top visitable ovject or -1 if there is none
2012-01-03 04:55:26 +03:00
bool isWater ( ) const ;
2011-09-19 23:50:25 +03:00
bool isCoastal ( ) const ;
bool hasFavourableWinds ( ) const ;
2008-12-27 03:01:59 +02:00
} ;
2011-02-22 13:52:36 +02:00
/// name of starting hero
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE SheroName
2008-12-27 03:01:59 +02:00
{
int heroID ;
std : : string heroName ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & heroID & heroName ;
}
} ;
2011-02-22 13:52:36 +02:00
/// Player information regarding map. Which factions are allowed, AI tactic setting, main hero name,
/// position of main town,...
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE PlayerInfo
2008-12-27 03:01:59 +02:00
{
si32 p7 , p8 , p9 ;
2010-02-01 19:07:46 +02:00
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???
2008-12-27 03:01:59 +02:00
ui8 canHumanPlay ;
ui8 canComputerPlay ;
ui32 AITactic ; //(00 - random, 01 - warrior, 02 - builder, 03 - explorer)
ui32 allowedFactions ; //(01 - castle; 02 - rampart; 04 - tower; 08 - inferno; 16 - necropolis; 32 - dungeon; 64 - stronghold; 128 - fortress; 256 - conflux);
ui8 isFactionRandom ;
2011-09-24 04:15:36 +03:00
ui32 mainHeroPortrait ; //it's ID of hero with chosen portrait; 255 if standard
2008-12-27 03:01:59 +02:00
std : : string mainHeroName ;
std : : vector < SheroName > heroesNames ;
ui8 hasMainTown ;
ui8 generateHeroAtMainTown ;
int3 posOfMainTown ;
ui8 team ;
ui8 generateHero ;
2009-05-29 06:53:53 +03:00
PlayerInfo ( ) : p7 ( 0 ) , p8 ( 0 ) , p9 ( 0 ) , canHumanPlay ( 0 ) , canComputerPlay ( 0 ) ,
AITactic ( 0 ) , allowedFactions ( 0 ) , isFactionRandom ( 0 ) ,
mainHeroPortrait ( 0 ) , hasMainTown ( 0 ) , generateHeroAtMainTown ( 0 ) ,
2009-08-22 16:59:15 +03:00
team ( 255 ) , generateHero ( 0 ) { } ;
2009-05-29 06:53:53 +03:00
2010-10-24 14:35:14 +03:00
si8 defaultCastle ( ) const
{
si8 ret = - 2 ;
2011-12-14 00:23:17 +03:00
for ( int j = 0 ; j < GameConstants : : F_NUMBER & & ret ! = - 1 ; j + + ) //we start with none and find matching faction. if more than one, then set to random
2010-10-24 14:35:14 +03:00
{
if ( ( 1 < < j ) & allowedFactions )
{
if ( ret > = 0 ) //we've already assigned a castle and another one is possible -> set random and let player choose
ret = - 1 ; //breaks
if ( ret = = - 2 ) //first available castle - pick
ret = j ;
}
}
return ret ;
}
2011-03-19 16:35:29 +02:00
si8 defaultHero ( ) const
2010-10-24 14:35:14 +03:00
{
2011-03-19 16:35:29 +02:00
if ( ( generateHeroAtMainTown & & hasMainTown ) //we will generate hero in front of main town
2010-10-24 14:35:14 +03:00
| | p8 ) //random hero
return - 1 ;
else
return - 2 ;
}
2008-12-27 03:01:59 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & AITactic & allowedFactions & isFactionRandom &
mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
posOfMainTown & team & generateHero ;
}
} ;
2011-02-22 13:52:36 +02:00
/// Small struct which holds information about the loss condition
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE LossCondition
2008-12-27 03:01:59 +02:00
{
2011-12-14 00:23:17 +03:00
ELossConditionType : : ELossConditionType typeOfLossCon ;
2010-01-29 22:52:45 +02:00
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
2008-12-27 03:01:59 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2010-01-29 22:52:45 +02:00
h & typeOfLossCon & pos & timeLimit & obj ;
2008-12-27 03:01:59 +02:00
}
2010-01-29 22:52:45 +02:00
LossCondition ( ) ;
2008-12-27 03:01:59 +02:00
} ;
2011-02-22 13:52:36 +02:00
/// Small struct which holds information about the victory condition
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE CVictoryCondition
2008-12-27 03:01:59 +02:00
{
2011-12-14 00:23:17 +03:00
EVictoryConditionType : : EVictoryConditionType condition ; //ID of condition
2009-01-06 20:42:20 +02:00
ui8 allowNormalVictory , appliesToAI ;
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)
2010-01-30 14:46:15 +02:00
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);
2009-01-06 20:42:20 +02:00
2010-01-29 22:52:45 +02:00
const CGObjectInstance * obj ; //object of specific monster / city / hero instance (NULL if not used); set during map parsing
CVictoryCondition ( ) ;
2009-01-06 20:42:20 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2010-01-29 22:52:45 +02:00
h & condition & allowNormalVictory & appliesToAI & pos & ID & count & obj ;
2009-01-06 20:42:20 +02:00
}
2008-12-27 03:01:59 +02:00
} ;
2009-01-06 20:42:20 +02:00
2011-02-22 13:52:36 +02:00
/// Struct which holds a name and the rumor text
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE Rumor
2008-12-27 03:01:59 +02:00
{
std : : string name , text ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & name & text ;
}
} ;
2011-02-22 13:52:36 +02:00
/// Struct which describes who can hire this hero
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE DisposedHero
2008-12-27 03:01:59 +02:00
{
ui32 ID ;
ui16 portrait ; //0xFF - default
std : : string name ;
ui8 players ; //who can hire this hero (bitfield)
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & ID & portrait & name & players ;
}
} ;
2011-02-22 13:52:36 +02:00
/// Class which manages map events.
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CMapEvent
2008-12-27 03:01:59 +02:00
{
public :
std : : string name , message ;
2011-07-05 09:14:07 +03:00
TResources resources ; //gained / taken resources
2008-12-27 03:01:59 +02:00
ui8 players ; //affected players
ui8 humanAffected ;
ui8 computerAffected ;
ui32 firstOccurence ;
2009-02-06 13:15:39 +02:00
ui32 nextOccurence ; //after nextOccurance day event will occur; if it it 0, event occures only one time;
2010-08-18 17:24:30 +03:00
2008-12-27 03:01:59 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2009-02-06 13:15:39 +02:00
h & name & message & resources
2008-12-27 03:01:59 +02:00
& players & humanAffected & computerAffected & firstOccurence & nextOccurence ;
}
2009-03-09 21:40:43 +02:00
bool operator < ( const CMapEvent & b ) const
{
return firstOccurence < b . firstOccurence ;
}
2011-01-01 22:26:39 +02:00
bool operator < = ( const CMapEvent & b ) const
{
return firstOccurence < = b . firstOccurence ;
}
2008-12-27 03:01:59 +02:00
} ;
2010-08-18 17:24:30 +03:00
2011-02-22 13:52:36 +02:00
/// Sub-class derived by CMapEvent; This event can build specific buildings or add
/// additional creatures in a town.
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CCastleEvent : public CMapEvent
2010-08-18 17:24:30 +03:00
{
public :
std : : set < si32 > buildings ; //build specific buildings
std : : vector < si32 > creatures ; //additional creatures in i-th level dwelling
CGTownInstance * town ; //owner of this event
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & static_cast < CMapEvent & > ( * this ) ;
h & buildings & creatures ;
}
} ;
2011-02-22 13:52:36 +02:00
/// 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 :
2009-08-17 11:50:31 +03:00
enum Eformat { invalid , WoG = 0x33 , AB = 0x15 , RoE = 0x0e , SoD = 0x1c } ;
2008-12-27 03:01:59 +02:00
Eformat version ; // version of map Eformat
2009-01-06 20:42:20 +02:00
ui8 areAnyPLayers ; // if there are any playable players on map
si32 height , width , twoLevel ; //sizes
2008-12-27 03:01:59 +02:00
std : : string name ; //name of map
std : : string description ; //and description
2009-01-06 20:42:20 +02:00
ui8 difficulty ; // 0 easy - 4 impossible
ui8 levelLimit ;
2008-12-27 03:01:59 +02:00
LossCondition lossCondition ;
2009-01-06 20:42:20 +02:00
CVictoryCondition victoryCondition ; //victory conditions
2009-01-11 00:08:18 +02:00
std : : vector < PlayerInfo > players ; // info about players - size 8
2009-01-06 20:42:20 +02:00
ui8 howManyTeams ;
2009-08-17 11:50:31 +03:00
std : : vector < ui8 > allowedHeroes ; //allowedHeroes[hero_ID] - if the hero is allowed
2010-02-01 19:07:46 +02:00
std : : vector < ui16 > placeholdedHeroes ; //ID of types of heroes in placeholders
2011-12-14 00:23:17 +03:00
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)
2009-01-06 20:42:20 +02:00
CMapHeader ( ) ;
2009-08-27 11:04:32 +03:00
virtual ~ CMapHeader ( ) ;
2009-01-11 00:08:18 +02:00
template < typename Handler > void serialize ( Handler & h , const int Version )
{
h & version & name & description & width & height & twoLevel & difficulty & levelLimit & areAnyPLayers ;
2009-08-22 16:59:15 +03:00
h & players & lossCondition & victoryCondition & howManyTeams ;
2009-01-11 00:08:18 +02:00
}
2008-12-27 03:01:59 +02:00
} ;
2009-01-06 20:42:20 +02:00
2011-02-22 13:52:36 +02:00
/// Extends the base class and adds further map information like rumors, disposed heroes,
/// allowed spells, artifacts, abilities and such things.
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE Mapa : public CMapHeader
2008-12-27 03:01:59 +02:00
{
ui32 checksum ;
TerrainTile * * * terrain ;
std : : vector < Rumor > rumors ;
std : : vector < DisposedHero > disposedHeroes ;
2010-12-20 15:04:24 +02:00
std : : vector < ConstTransitivePtr < CGHeroInstance > > predefinedHeroes ;
std : : vector < ConstTransitivePtr < CGDefInfo > > defy ; // list of .def files with definitions from .h3m (may be custom)
2008-12-31 11:33:46 +02:00
std : : vector < ui8 > allowedSpell ; //allowedSpell[spell_ID] - if the spell is allowed
std : : vector < ui8 > allowedArtifact ; //allowedArtifact[artifact_ID] - if the artifact is allowed
std : : vector < ui8 > allowedAbilities ; //allowedAbilities[ability_ID] - if the ability is allowed
2010-12-20 15:04:24 +02:00
std : : list < ConstTransitivePtr < CMapEvent > > events ;
2008-12-27 03:01:59 +02:00
int3 grailPos ;
int grailRadious ;
2010-12-17 20:47:07 +02:00
std : : vector < ConstTransitivePtr < CGObjectInstance > > objects ;
2010-12-20 15:04:24 +02:00
std : : vector < ConstTransitivePtr < CGHeroInstance > > heroes ;
std : : vector < ConstTransitivePtr < CGTownInstance > > towns ;
2010-12-17 20:47:07 +02:00
std : : vector < ConstTransitivePtr < CArtifactInstance > > artInstances ; //stores all artifacts
2011-02-11 14:27:38 +02:00
//bmap<ui16, ConstTransitivePtr<CGCreature> > monsters;
//bmap<ui16, ConstTransitivePtr<CGHeroInstance> > heroesToBeat;
bmap < si32 , si32 > questIdentifierToId ;
2008-12-27 03:01:59 +02:00
2011-12-14 00:23:17 +03:00
void initFromBytes ( const ui8 * bufor , size_t size ) ; //creates map from decompressed .h3m data
void readEvents ( const ui8 * bufor , int & i ) ;
void readObjects ( const ui8 * bufor , int & i ) ;
void loadQuest ( CQuest * 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 ) ;
2008-12-27 03:01:59 +02:00
2011-03-12 23:55:31 +02:00
CArtifactInstance * createArt ( int aid , int spellID = - 1 ) ;
2011-01-28 04:11:58 +02:00
void addNewArtifactInstance ( CArtifactInstance * art ) ;
void eraseArtifactInstance ( CArtifactInstance * art ) ;
2010-12-30 16:41:46 +02:00
2011-05-30 02:49:25 +03:00
const CGObjectInstance * getObjectiveObjectFrom ( int3 pos , bool lookForHero ) ;
2010-01-29 22:52:45 +02:00
void checkForObjectives ( ) ;
2008-12-27 03:01:59 +02:00
void addBlockVisTiles ( CGObjectInstance * obj ) ;
2009-02-14 21:12:40 +02:00
void removeBlockVisTiles ( CGObjectInstance * obj , bool total = false ) ;
2008-12-27 03:01:59 +02:00
Mapa ( std : : string filename ) ; //creates map structure from .h3m file
2009-01-06 20:42:20 +02:00
Mapa ( ) ;
2009-01-11 00:08:18 +02:00
~ Mapa ( ) ;
2010-08-16 16:51:31 +03:00
TerrainTile & getTile ( const int3 & tile ) ;
const TerrainTile & getTile ( const int3 & tile ) const ;
2008-12-27 03:01:59 +02:00
CGHeroInstance * getHero ( int ID , int mode = 0 ) ;
2009-08-22 16:59:15 +03:00
bool isInTheMap ( const int3 & pos ) const ;
bool isWaterTile ( const int3 & pos ) const ; //out-of-pos safe
2010-08-16 16:51:31 +03:00
2009-01-06 20:42:20 +02:00
template < typename Handler > void serialize ( Handler & h , const int formatVersion )
{
2009-01-11 00:08:18 +02:00
h & static_cast < CMapHeader & > ( * this ) ;
h & rumors & allowedSpell & allowedAbilities & allowedArtifact & allowedHeroes & events & grailPos ;
2010-11-20 02:03:31 +02:00
h & artInstances ; //hopefully serialization is now automagical?
2011-02-11 14:27:38 +02:00
h & questIdentifierToId ;
2009-01-06 20:42:20 +02:00
2008-12-27 03:01:59 +02:00
//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 + + )
h & terrain [ i ] [ j ] [ k ] ;
}
else
{
//loading terrain
terrain = new TerrainTile * * [ width ] ; // allocate memory
for ( int ii = 0 ; ii < width ; ii + + )
{
terrain [ ii ] = new TerrainTile * [ height ] ; // allocate memory
for ( int jj = 0 ; jj < height ; jj + + )
terrain [ ii ] [ jj ] = new TerrainTile [ twoLevel + 1 ] ;
}
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 ] ;
}
2010-07-28 13:46:36 +03:00
h & defy & objects ;
// //definfos
// std::vector<CGDefInfo*> defs;
//
// if(h.saving) //create vector with all defs used on map
// {
2011-12-14 00:23:17 +03:00
// for(ui32 i=0; i<objects.size(); i++)
2010-07-28 13:46:36 +03:00
// if(objects[i])
// objects[i]->defInfo->serial = -1; //set serial to serial -1 - indicates that def is not present in defs vector
//
2011-12-14 00:23:17 +03:00
// for(ui32 i=0; i<objects.size(); i++)
2010-07-28 13:46:36 +03:00
// {
// if(!objects[i]) continue;
// CGDefInfo *cur = objects[i]->defInfo;
// 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);
// }
2009-01-06 20:42:20 +02:00
2010-02-10 04:56:00 +02:00
//static members
2009-01-06 20:42:20 +02:00
h & CGTeleport : : objs ;
2009-09-07 05:29:44 +03:00
h & CGTeleport : : gates ;
2009-08-11 10:50:29 +03:00
h & CGKeys : : playerKeyMap ;
h & CGMagi : : eyelist ;
2010-02-10 04:56:00 +02:00
h & CGObelisk : : obeliskCount & CGObelisk : : visited ;
2010-06-26 19:02:10 +03:00
h & CGTownInstance : : merchantArtifacts ;
2009-01-06 20:42:20 +02:00
2011-12-14 00:23:17 +03:00
// for(ui32 i=0; i<objects.size(); i++)
2010-07-28 13:46:36 +03:00
// {
// CGObjectInstance *&obj = objects[i];
// h & obj;
//
// if (obj)
// {
// si32 shlp;
// //definfo
// h & (h.saving ? (shlp=obj->defInfo->serial) : shlp); //read / write pos of definfo in defs vector
// if(!h.saving)
// obj->defInfo = defy[shlp];
// }
// }
2009-01-06 20:42:20 +02:00
if ( ! h . saving )
{
2011-12-14 00:23:17 +03:00
for ( ui32 i = 0 ; i < objects . size ( ) ; i + + )
2009-01-06 20:42:20 +02:00
{
2009-02-02 01:56:45 +02:00
if ( ! objects [ i ] ) continue ;
2011-12-14 00:23:17 +03:00
if ( objects [ i ] - > ID = = GameConstants : : HEROI_TYPE )
2010-12-17 20:47:07 +02:00
heroes . push_back ( static_cast < CGHeroInstance * > ( + objects [ i ] ) ) ;
2011-12-14 00:23:17 +03:00
else if ( objects [ i ] - > ID = = GameConstants : : TOWNI_TYPE )
2010-12-17 20:47:07 +02:00
towns . push_back ( static_cast < CGTownInstance * > ( + objects [ i ] ) ) ;
2009-01-06 20:42:20 +02:00
addBlockVisTiles ( objects [ i ] ) ; //recreate blockvis map
}
2011-12-14 00:23:17 +03:00
for ( ui32 i = 0 ; i < heroes . size ( ) ; i + + ) //if hero is visiting/garrisoned in town set appropriate pointers
2009-01-06 20:42:20 +02:00
{
int3 vistile = heroes [ i ] - > pos ; vistile . x + + ;
2011-12-14 00:23:17 +03:00
for ( ui32 j = 0 ; j < towns . size ( ) ; j + + )
2009-01-06 20:42:20 +02:00
{
if ( vistile = = towns [ j ] - > pos ) //hero stands on the town entrance
{
if ( heroes [ i ] - > inTownGarrison )
2009-08-01 22:25:12 +03:00
{
2009-01-06 20:42:20 +02:00
towns [ j ] - > garrisonHero = heroes [ i ] ;
2009-08-01 22:25:12 +03:00
removeBlockVisTiles ( heroes [ i ] ) ;
}
2009-01-06 20:42:20 +02:00
else
2009-08-01 22:25:12 +03:00
{
2009-01-06 20:42:20 +02:00
towns [ j ] - > visitingHero = heroes [ i ] ;
2009-08-01 22:25:12 +03:00
}
2009-01-06 20:42:20 +02:00
heroes [ i ] - > visitedTown = towns [ j ] ;
2009-08-01 22:25:12 +03:00
break ;
2009-01-06 20:42:20 +02:00
}
}
2009-08-01 13:08:16 +03:00
vistile . x - = 2 ; //manifest pos
const TerrainTile & t = getTile ( vistile ) ;
if ( t . tertype ! = TerrainTile : : water ) continue ;
//hero stands on the water - he must be in the boat
2011-12-14 00:23:17 +03:00
for ( ui32 j = 0 ; j < t . visitableObjects . size ( ) ; j + + )
2009-08-01 13:08:16 +03:00
{
if ( t . visitableObjects [ j ] - > ID = = 8 )
{
CGBoat * b = static_cast < CGBoat * > ( t . visitableObjects [ j ] ) ;
heroes [ i ] - > boat = b ;
b - > hero = heroes [ i ] ;
removeBlockVisTiles ( b ) ;
break ;
}
}
} //heroes loop
} //!saving
2008-12-27 03:01:59 +02:00
}
} ;