2011-12-14 00:23:17 +03:00
# pragma once
2012-09-02 13:33:41 +03:00
# include "ConstTransitivePtr.h"
# include "ResourceSet.h"
2011-12-14 00:23:17 +03:00
# include "int3.h"
2012-09-26 16:13:39 +03:00
# include "GameConstants.h"
2013-04-21 15:49:26 +03:00
# include "IHandlerBase.h"
2013-12-02 14:58:02 +03:00
# include "LogicalExpression.h"
2009-04-16 14:14:13 +03:00
2009-04-15 17:03:31 +03:00
/*
* CTownHandler . 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
*
2009-04-16 14:14:13 +03:00
*/
2012-09-02 13:33:41 +03:00
class CLegacyConfigParser ;
class JsonNode ;
2013-04-21 15:49:26 +03:00
class CTown ;
2013-04-22 16:23:53 +03:00
class CFaction ;
2009-04-16 14:14:13 +03:00
2012-09-02 13:33:41 +03:00
/// a typical building encountered in every castle ;]
/// this is structure available to both client and server
/// contains all mechanics-related data about town structures
2014-04-26 17:23:35 +03:00
2012-09-02 13:33:41 +03:00
class DLL_LINKAGE CBuilding
{
2012-09-05 15:49:23 +03:00
2012-09-02 13:33:41 +03:00
std : : string name ;
std : : string description ;
2009-04-16 14:14:13 +03:00
2012-09-02 13:33:41 +03:00
public :
2013-12-02 14:58:02 +03:00
typedef LogicalExpression < BuildingID > TRequired ;
2013-04-21 15:49:26 +03:00
CTown * town ; // town this building belongs to
2012-09-02 13:33:41 +03:00
TResources resources ;
2014-04-26 17:23:35 +03:00
TResources produce ;
2013-12-02 14:58:02 +03:00
TRequired requirements ;
std : : string identifier ;
2012-09-05 15:49:23 +03:00
2013-12-02 14:58:02 +03:00
BuildingID bid ; //structure ID
2013-02-11 22:11:34 +03:00
BuildingID upgrade ; /// indicates that building "upgrade" can be improved by this, -1 = empty
2012-09-05 15:49:23 +03:00
enum EBuildMode
{
BUILD_NORMAL , // 0 - normal, default
BUILD_AUTO , // 1 - auto - building appears when all requirements are built
BUILD_SPECIAL , // 2 - special - building can not be built normally
BUILD_GRAIL // 3 - grail - building reqires grail to be built
2013-02-11 22:11:34 +03:00
} mode ;
2009-04-16 14:14:13 +03:00
2012-09-02 13:33:41 +03:00
const std : : string & Name ( ) const ;
const std : : string & Description ( ) const ;
2009-04-16 14:14:13 +03:00
2012-09-05 15:49:23 +03:00
//return base of upgrade(s) or this
2013-02-11 22:11:34 +03:00
BuildingID getBase ( ) const ;
2012-09-05 15:49:23 +03:00
// returns how many times build has to be upgraded to become build
2013-02-11 22:11:34 +03:00
si32 getDistance ( BuildingID build ) const ;
2012-09-05 15:49:23 +03:00
2009-04-16 14:14:13 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2014-04-26 17:23:35 +03:00
h & identifier & town & bid & resources & produce & name & description & requirements & upgrade & mode ;
2009-04-16 14:14:13 +03:00
}
2012-09-02 13:33:41 +03:00
friend class CTownHandler ;
2009-04-16 14:14:13 +03:00
} ;
2012-09-02 13:33:41 +03:00
/// This is structure used only by client
/// Consists of all gui-related data about town structures
2012-09-05 15:49:23 +03:00
/// Should be moved from lib to client
2012-09-02 13:33:41 +03:00
struct DLL_LINKAGE CStructure
2009-04-16 14:14:13 +03:00
{
2012-09-05 15:49:23 +03:00
CBuilding * building ; // base building. If null - this structure will be always present on screen
CBuilding * buildable ; // building that will be used to determine built building and visible cost. Usually same as "building"
2009-04-16 14:14:13 +03:00
int3 pos ;
2013-12-02 14:58:02 +03:00
std : : string defName , borderName , areaName , identifier ;
2012-09-02 13:33:41 +03:00
2013-12-02 14:58:02 +03:00
bool hiddenUpgrade ; // used only if "building" is upgrade, if true - structure on town screen will behave exactly like parent (mouse clicks, hover texts, etc)
2012-09-02 13:33:41 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2013-12-02 14:58:02 +03:00
h & pos & defName & borderName & areaName & identifier & building & buildable & hiddenUpgrade ;
2012-09-02 13:33:41 +03:00
}
} ;
2013-04-21 15:49:26 +03:00
struct DLL_LINKAGE SPuzzleInfo
{
ui16 number ; //type of puzzle
si16 x , y ; //position
ui16 whenUncovered ; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered)
std : : string filename ; //file with graphic of this puzzle
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & number & x & y & whenUncovered & filename ;
}
} ;
2013-04-21 20:06:24 +03:00
class DLL_LINKAGE CFaction
2013-04-21 15:49:26 +03:00
{
public :
2013-04-21 17:08:46 +03:00
CFaction ( ) ;
~ CFaction ( ) ;
2013-04-21 15:49:26 +03:00
std : : string name ; //town name, by default - from TownName.txt
2013-12-02 14:58:02 +03:00
std : : string identifier ;
2013-04-21 15:49:26 +03:00
TFaction index ;
ETerrainType nativeTerrain ;
EAlignment : : EAlignment alignment ;
CTown * town ; //NOTE: can be null
std : : string creatureBg120 ;
std : : string creatureBg130 ;
2014-04-24 22:36:10 +03:00
2013-04-21 15:49:26 +03:00
std : : vector < SPuzzleInfo > puzzleMap ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
2013-12-13 21:27:54 +03:00
h & name & identifier & index & nativeTerrain & alignment & town & creatureBg120 & creatureBg130 & puzzleMap ;
2013-04-21 15:49:26 +03:00
}
} ;
2012-09-02 13:33:41 +03:00
class DLL_LINKAGE CTown
{
2012-10-05 16:11:26 +03:00
public :
2013-04-21 17:08:46 +03:00
CTown ( ) ;
~ CTown ( ) ;
2013-04-21 15:49:26 +03:00
CFaction * faction ;
2014-04-24 22:36:10 +03:00
2012-09-02 13:33:41 +03:00
std : : vector < std : : string > names ; //names of the town instances
/// level -> list of creatures on this tier
2013-12-02 14:58:02 +03:00
// TODO: replace with pointers to CCreature
std : : vector < std : : vector < CreatureID > > creatures ;
std : : map < BuildingID , ConstTransitivePtr < CBuilding > > buildings ;
std : : vector < std : : string > dwellings ; //defs for adventure map dwellings for new towns, [0] means tier 1 creatures etc.
std : : vector < std : : string > dwellingNames ;
// should be removed at least from configs in favor of auto-detection
std : : map < int , int > hordeLvl ; //[0] - first horde building creature level; [1] - second horde building (-1 if not present)
ui32 mageLevel ; //max available mage guild level
ui16 primaryRes ;
ArtifactID warMachine ;
2013-02-09 00:17:39 +03:00
si32 moatDamage ;
2013-11-03 15:07:23 +03:00
// default chance for hero of specific class to appear in tavern, if field "tavern" was not set
// resulting chance = sqrt(town.chance * heroClass.chance)
ui32 defaultTavernChance ;
2012-09-02 13:33:41 +03:00
// Client-only data. Should be moved away from lib
struct ClientInfo
{
2012-12-13 16:07:56 +03:00
struct Point
{
si32 x ;
si32 y ;
template < typename Handler > void serialize ( Handler & h , const int version )
{ h & x & y ; }
} ;
2012-10-05 21:03:49 +03:00
2012-09-22 18:10:15 +03:00
//icons [fort is present?][build limit reached?] -> index of icon in def files
int icons [ 2 ] [ 2 ] ;
2013-04-22 22:51:22 +03:00
std : : string iconSmall [ 2 ] [ 2 ] ; /// icon names used during loading
std : : string iconLarge [ 2 ] [ 2 ] ;
2014-04-24 22:36:10 +03:00
std : : string tavernVideo ;
2012-09-05 15:49:23 +03:00
std : : string musicTheme ;
std : : string townBackground ;
2014-04-24 22:36:10 +03:00
std : : string guildBackground ;
2012-09-05 15:49:23 +03:00
std : : string guildWindow ;
std : : string buildingsIcons ;
2012-09-02 13:33:41 +03:00
std : : string hallBackground ;
2012-09-05 15:49:23 +03:00
/// vector[row][column] = list of buildings in this slot
2013-02-11 22:11:34 +03:00
std : : vector < std : : vector < std : : vector < BuildingID > > > hallSlots ;
2012-09-05 15:49:23 +03:00
/// list of town screen structures.
/// NOTE: index in vector is meaningless. Vector used instead of list for a bit faster access
std : : vector < ConstTransitivePtr < CStructure > > structures ;
2012-09-02 13:33:41 +03:00
2012-10-05 21:03:49 +03:00
std : : string siegePrefix ;
std : : vector < Point > siegePositions ;
2013-02-11 02:24:57 +03:00
CreatureID siegeShooter ; // shooter creature ID
2012-10-05 21:03:49 +03:00
2012-09-02 13:33:41 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2014-04-24 22:36:10 +03:00
h & icons & iconSmall & iconLarge & tavernVideo & musicTheme & townBackground & guildBackground & guildWindow & buildingsIcons & hallBackground ;
2014-06-15 19:43:01 +03:00
h & hallSlots & structures ;
2013-08-01 01:24:44 +03:00
h & siegePrefix & siegePositions & siegeShooter ;
2012-09-02 13:33:41 +03:00
}
} clientInfo ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
2013-04-21 15:49:26 +03:00
h & names & faction & creatures & dwellings & dwellingNames & buildings & hordeLvl & mageLevel
2013-11-03 15:07:23 +03:00
& primaryRes & warMachine & clientInfo & moatDamage & defaultTavernChance ;
2013-09-07 19:57:31 +03:00
2013-09-08 16:02:34 +03:00
auto findNull = [ ] ( const std : : pair < BuildingID , ConstTransitivePtr < CBuilding > > & building )
{ return building . second = = nullptr ; } ;
2013-09-07 19:57:31 +03:00
//Fix #1444 corrupted save
2013-09-08 16:02:34 +03:00
while ( auto badElem = vstd : : tryFindIf ( buildings , findNull ) )
2013-09-07 19:57:31 +03:00
{
2013-09-27 18:20:42 +03:00
logGlobal - > errorStream ( ) < < " #1444-like bug encountered in CTown::serialize, fixing buildings list by removing bogus entry " < < badElem - > first < < " from " < < faction - > name ;
2013-09-07 19:57:31 +03:00
buildings . erase ( badElem - > first ) ;
}
2012-09-02 13:33:41 +03:00
}
2009-04-16 14:14:13 +03:00
} ;
2013-04-21 15:49:26 +03:00
class DLL_LINKAGE CTownHandler : public IHandlerBase
2009-04-16 14:14:13 +03:00
{
2013-12-02 14:58:02 +03:00
struct BuildingRequirementsHelper
{
JsonNode json ;
CBuilding * building ;
CFaction * faction ;
} ;
std : : vector < BuildingRequirementsHelper > requirementsToLoad ;
void initializeRequirements ( ) ;
2012-09-02 13:33:41 +03:00
/// loads CBuilding's into town
2013-12-02 14:58:02 +03:00
void loadBuildingRequirements ( CTown & town , CBuilding & building , const JsonNode & source ) ;
void loadBuilding ( CTown & town , const std : : string & stringID , const JsonNode & source ) ;
2012-09-02 13:33:41 +03:00
void loadBuildings ( CTown & town , const JsonNode & source ) ;
/// loads CStructure's into town
2013-12-02 14:58:02 +03:00
void loadStructure ( CTown & town , const std : : string & stringID , const JsonNode & source ) ;
2012-09-02 13:33:41 +03:00
void loadStructures ( CTown & town , const JsonNode & source ) ;
/// loads town hall vector (hallSlots)
void loadTownHall ( CTown & town , const JsonNode & source ) ;
2012-10-05 21:03:49 +03:00
void loadSiegeScreen ( CTown & town , const JsonNode & source ) ;
2012-09-02 13:33:41 +03:00
2012-09-05 15:49:23 +03:00
void loadClientData ( CTown & town , const JsonNode & source ) ;
void loadTown ( CTown & town , const JsonNode & source ) ;
2012-09-02 13:33:41 +03:00
2012-09-21 00:28:18 +03:00
void loadPuzzle ( CFaction & faction , const JsonNode & source ) ;
2015-08-24 10:55:45 +02:00
CFaction * loadFromJson ( const JsonNode & data , const std : : string & identifier ) ;
2012-09-05 15:49:23 +03:00
2009-04-16 14:14:13 +03:00
public :
2013-04-21 15:49:26 +03:00
std : : vector < ConstTransitivePtr < CFaction > > factions ;
2009-04-16 14:14:13 +03:00
2012-09-02 13:33:41 +03:00
CTownHandler ( ) ; //c-tor, set pointer in VLC to this
2013-04-21 19:38:31 +03:00
~ CTownHandler ( ) ;
2012-09-02 13:33:41 +03:00
2013-04-21 15:49:26 +03:00
std : : vector < JsonNode > loadLegacyData ( size_t dataSize ) override ;
void loadObject ( std : : string scope , std : : string name , const JsonNode & data ) override ;
void loadObject ( std : : string scope , std : : string name , const JsonNode & data , size_t index ) override ;
2013-12-02 14:58:02 +03:00
void afterLoadFinalization ( ) override ;
2013-04-21 15:49:26 +03:00
std : : vector < bool > getDefaultAllowed ( ) const override ;
2014-10-30 14:03:53 +02:00
std : : set < TFaction > getAllowedFactions ( bool withTown = true ) const ;
2012-11-20 20:53:45 +03:00
2009-04-16 14:14:13 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2013-04-21 15:49:26 +03:00
h & factions ;
2009-04-16 14:14:13 +03:00
}
} ;