1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00
vcmi/lib/CTownHandler.h
Ivan Savenko f306d7bb70 some changes towards editing H3 objects via mods. Should be stable, report if not.
- removed duplicated json loading code in handlers
- simpler and mod-friendly handling of combined artifacts
- reorganized CCreature to avoid huge number of fields in one structure
2013-03-02 16:55:51 +00:00

247 lines
7.8 KiB
C++

#pragma once
#include "ConstTransitivePtr.h"
#include "ResourceSet.h"
#include "int3.h"
#include "GameConstants.h"
/*
* 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
*
*/
class CLegacyConfigParser;
class JsonNode;
/// a typical building encountered in every castle ;]
/// this is structure available to both client and server
/// contains all mechanics-related data about town structures
class DLL_LINKAGE CBuilding
{
std::string name;
std::string description;
public:
TFaction tid; //town ID
BuildingID bid; //structure ID
TResources resources;
std::set<BuildingID> requirements; /// set of required buildings, includes upgradeOf;
BuildingID upgrade; /// indicates that building "upgrade" can be improved by this, -1 = empty
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
} mode;
const std::string &Name() const;
const std::string &Description() const;
//return base of upgrade(s) or this
BuildingID getBase() const;
// returns how many times build has to be upgraded to become build
si32 getDistance(BuildingID build) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tid & bid & resources & name & description & requirements & upgrade & mode;
}
friend class CTownHandler;
};
/// This is structure used only by client
/// Consists of all gui-related data about town structures
/// Should be moved from lib to client
struct DLL_LINKAGE CStructure
{
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"
bool hiddenUpgrade; // used only if "building" is upgrade, if true - structure on town screen will behave exactly like parent (mouse clicks, hover texts, etc)
int3 pos;
std::string defName, borderName, areaName;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & pos & defName & borderName & areaName & building & buildable;
}
};
class DLL_LINKAGE CTown
{
public:
TFaction typeID;//same as CFaction::factionID
std::vector<std::string> names; //names of the town instances
/// level -> list of creatures on this tier
// TODO: replace with pointers to CCreature
std::vector<std::vector<CreatureID> > creatures;
bmap<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 favour 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;
si32 moatDamage;
// Client-only data. Should be moved away from lib
struct ClientInfo
{
struct Point
{
si32 x;
si32 y;
template <typename Handler> void serialize(Handler &h, const int version)
{ h & x & y; }
};
//icons [fort is present?][build limit reached?] -> index of icon in def files
int icons[2][2];
std::string musicTheme;
std::string townBackground;
std::string guildWindow;
std::string buildingsIcons;
std::string hallBackground;
/// vector[row][column] = list of buildings in this slot
std::vector< std::vector< std::vector<BuildingID> > > hallSlots;
/// 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;
std::string advMapVillage;
std::string advMapCastle;
std::string advMapCapitol;
std::string siegePrefix;
std::vector<Point> siegePositions;
CreatureID siegeShooter; // shooter creature ID
si32 siegeShooterCropHeight; //trim height for shooters in turrets
template <typename Handler> void serialize(Handler &h, const int version)
{
h & icons & musicTheme & townBackground & guildWindow & buildingsIcons & hallBackground & hallSlots & structures;
h & advMapVillage & advMapCastle & advMapCapitol;
h & siegePrefix & siegePositions & siegeShooter & siegeShooterCropHeight;
}
} clientInfo;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & names & typeID & creatures & dwellings & dwellingNames & buildings & hordeLvl & mageLevel
& primaryRes & warMachine & clientInfo & moatDamage;
}
};
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;
}
};
class CFaction
{
public:
std::string name; //town name, by default - from TownName.txt
TFaction factionID;
ETerrainType nativeTerrain;
EAlignment::EAlignment alignment;
CreatureID commander;
std::string creatureBg120;
std::string creatureBg130;
std::vector<SPuzzleInfo> puzzleMap;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & name & factionID & nativeTerrain & creatureBg120 & creatureBg130 & puzzleMap;
}
};
class DLL_LINKAGE CTownHandler
{
/// loads CBuilding's into town
void loadBuilding(CTown &town, const JsonNode & source);
void loadBuildings(CTown &town, const JsonNode & source);
/// loads CStructure's into town
void loadStructure(CTown &town, const JsonNode & source);
void loadStructures(CTown &town, const JsonNode & source);
/// loads town hall vector (hallSlots)
void loadTownHall(CTown &town, const JsonNode & source);
void loadSiegeScreen(CTown &town, const JsonNode & source);
void loadClientData(CTown &town, const JsonNode & source);
void loadTown(CTown &town, const JsonNode & source);
void loadPuzzle(CFaction & faction, const JsonNode & source);
/// load all available data from h3 txt(s) into json structure using format similar to vcmi configs
/// returns 2d array [townID] [buildID] of buildings
void loadLegacyData(JsonNode & dest);
public:
std::map<TFaction, CTown> towns;
std::map<TFaction, CFaction> factions;
CTownHandler(); //c-tor, set pointer in VLC to this
/// main loading function for mods, accepts merged JSON source and add all entries from it into game
/// all entries in JSON should be checked for validness before using this function
void load(std::string townID, const JsonNode & source);
/// "entry point" for loading of OH3 town.
/// reads legacy txt's from H3 + vcmi json, merges them
/// and loads resulting structure to game using loadTowns method
void load();
/**
* Gets a list of default allowed factions. OH3 factions are in the range of 0 to 8.
*
* TODO Proposal for town modding: Replace faction id with a unique machine readable town name
* and create a JSON config file or merge it with other configs which describes which
* towns can be used for random map generation / map editor(default map settings).
*
* @return a list of allowed factions, the index which is unique is the faction id
*/
std::set<TFaction> getDefaultAllowedFactions() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & towns & factions;
}
};