18 #include "precompiled.h"
52 #include <boost/algorithm/string/predicate.hpp>
56 : xml_reader(0), m_PatchesPerSide(0), m_MapGen(0)
223 const double end_time =
timer_Time() + 200e-3;
282 STileDesc* tileptr = &
m_Tiles[0];
312 if (cmpPlayer && cmpPlayer->HasStartingCamera())
351 #define EL(x) int el_##x = xmb_file.GetElementID(#x)
352 #define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
363 int child_name = child.GetNodeName();
364 if (child_name == el_scriptsettings)
376 scriptInterface.
Eval(
"({})", data);
456 #define EL(x) el_##x = xmb_file.GetElementID(#x)
457 #define AT(x) at_##x = xmb_file.GetAttributeID(#x)
467 AT(group);
AT(group2);
492 CStr uid = ent.GetAttributes().GetNamedItem(
at_uid);
512 #define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
520 CStr texture =
"grass1_spring";
526 if (attr.Name == at_patches)
527 patches = attr.Value.ToInt();
528 else if (attr.Name == at_texture)
529 texture = attr.Value;
530 else if (attr.Name == at_priority)
531 priority = attr.Value.ToInt();
532 else if (attr.Name == at_height)
533 height = (
u16)attr.Value.ToInt();
547 for (
ssize_t i = 0; i <
SQR(verticesPerSide); ++i)
548 heightmap[i] = height;
551 for (
ssize_t pz = 0; pz < patches; ++pz)
553 for (
ssize_t px = 0; px < patches; ++px)
571 #define EL(x) int el_##x = xmb_file.GetElementID(#x)
572 #define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
579 EL(terrainambientcolour);
580 EL(unitsambientcolour);
591 EL(reflectiontintstrength);
607 int element_name = element.GetNodeName();
611 if (element_name == el_lightingmodel)
615 else if (element_name == el_skyset)
620 else if (element_name == el_suncolour)
627 else if (element_name == el_sunelevation)
631 else if (element_name == el_sunrotation)
635 else if (element_name == el_terrainambientcolour)
642 else if (element_name == el_unitsambientcolour)
649 else if (element_name == el_fog)
653 int element_name = fog.GetNodeName();
654 if (element_name == el_fogcolour)
662 else if (element_name == el_fogfactor)
666 else if (element_name == el_fogthickness)
672 else if (element_name == el_postproc)
676 int element_name = postproc.GetNodeName();
677 if (element_name == el_brightness)
681 else if (element_name == el_contrast)
685 else if (element_name == el_saturation)
689 else if (element_name == el_bloom)
693 else if (element_name == el_posteffect)
700 else if (element_name == el_water)
704 ENSURE(waterbody.GetNodeName() == el_waterbody);
707 int element_name = waterelement.GetNodeName();
708 if (element_name == el_height)
721 if (element_name == el_type)
725 #define READ_COLOUR(el, out) \
726 else if (element_name == el) \
728 XMBAttributeList attrs = waterelement.GetAttributes(); \
730 attrs.GetNamedItem(at_r).ToFloat(), \
731 attrs.GetNamedItem(at_g).ToFloat(), \
732 attrs.GetNamedItem(at_b).ToFloat(), \
736 #define READ_FLOAT(el, out) \
737 else if (element_name == el) \
739 out = waterelement.GetText().ToFloat(); \
769 #define EL(x) int el_##x = xmb_file.GetElementID(#x)
770 #define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
784 int element_name = element.GetNodeName();
787 if (element_name == el_declination)
791 else if (element_name == el_rotation)
817 #define EL(x) int el_##x = xmb_file.GetElementID(#x)
818 #define AT(x) int at_##x = xmb_file.GetAttributeID(#x)
839 std::map<CStrW, CCinemaPath> pathList;
842 int elementName = element.GetNodeName();
844 if ( elementName == el_path )
848 float timescale = attrs.
GetNamedItem(at_timescale).ToFloat();
855 elementName = pathChild.GetNodeName();
856 attrs = pathChild.GetAttributes();
859 if ( elementName == el_distortion )
868 else if ( elementName == el_node )
873 elementName = nodeChild.GetNodeName();
874 attrs = nodeChild.GetAttributes();
884 else if ( elementName == el_rotation )
891 else if ( elementName == el_time )
892 data.
Distance = nodeChild.GetText().ToFloat();
894 debug_warn(L
"Invalid cinematic element for node child");
900 debug_warn(L
"Invalid cinematic element for path child");
914 for ( std::vector<SplineData>::const_reverse_iterator it = nodes.rbegin();
915 it != nodes.rend(); ++it )
917 spline.
AddNode(it->Position, it->Rotation, it->Distance);
921 pathList[name] = path;
924 ENSURE(
"Invalid cinema child");
954 int EntityUid = uid.ToInt();
968 int element_name = setting.GetNodeName();
973 TemplateName = setting.GetText().FromUTF8();
978 PlayerID = setting.GetText().ToInt();
1011 if (!seedStr.empty())
1013 Seed = seedStr.ToLong();
1025 LOGERROR(L
"Failed to load entity template '%ls'", TemplateName.c_str());
1032 cmpPosition->
JumpTo(Position.
X, Position.
Z);
1078 const double end_time =
timer_Time() + 200e-3;
1086 if (name ==
"Terrain")
1090 else if (name ==
"Environment")
1094 else if (name ==
"Camera")
1098 else if (name ==
"ScriptSettings")
1102 else if (name ==
"Entities")
1111 else if (name ==
"Paths")
1115 else if (name ==
"Triggers")
1119 else if (name ==
"Script")
1126 debug_printf(L
"Invalid XML element in map file: %hs\n", name.c_str());
1234 else if (progress == 0)
1241 if (data.undefined())
1267 TIMER(L
"ParseTerrain");
1271 #define GET_TERRAIN_PROPERTY(val, prop, out)\
1272 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\
1273 { LOGERROR(L"CMapReader::ParseTerrain() failed to get '%hs' property", #prop);\
1274 throw PSERROR_Game_World_MapLoadFailed("Error parsing terrain data.\nCheck application log for details"); }
1285 std::vector<std::string> textureNames;
1305 std::vector<u16> tileIndex;
1306 std::vector<u16> tilePriority;
1310 ENSURE(
SQR(size) == tileIndex.size() &&
SQR(size) == tilePriority.size());
1313 for (
size_t x = 0; x < size; ++x)
1317 for (
size_t y = 0; y < size; ++y)
1323 tile.m_Tex1Index = tileIndex[y*size + x];
1324 tile.m_Tex2Index = 0xFFFF;
1325 tile.m_Priority = tilePriority[y*size + x];
1334 #undef GET_TERRAIN_PROPERTY
1341 TIMER(L
"ParseEntities");
1344 std::vector<Entity> entities;
1347 LOGWARNING(L
"CMapReader::ParseEntities() failed to get 'entities' property");
1352 size_t entity_idx = 0;
1353 size_t num_entities = entities.size();
1357 while (entity_idx < num_entities)
1360 currEnt = entities[entity_idx];
1406 #define GET_ENVIRONMENT_PROPERTY(val, prop, out)\
1407 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\
1408 LOGWARNING(L"CMapReader::ParseEnvironment() failed to get '%hs' property", #prop);
1415 LOGWARNING(L
"CMapReader::ParseEnvironment(): Environment settings not found");
1423 std::wstring skySet;
1435 CColor terrainAmbientColor;
1439 CColor unitsAmbientColor;
1474 #undef GET_ENVIRONMENT_PROPERTY
1486 #define GET_CAMERA_PROPERTY(val, prop, out)\
1487 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\
1488 LOGWARNING(L"CMapReader::ParseCamera() failed to get '%hs' property", #prop);
void Translate(float x, float y, float z)
int GetProgress()
Get status of the map generator thread.
CScriptValRooted GetMapSettings(ScriptInterface &scriptInterface)
Returns a value of the form:
void CalculateSunDirection()
const CSimContext & GetSimContext() const
CPostprocManager * pPostproc
void ReadTriggers(XMBElement parent)
void UnpackRaw(void *rawData, size_t rawDataSize)
unpack given number of bytes from the input into the given array.
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
std::vector< CTerrainTextureEntry * > m_TerrainTextures
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Load from an XML file (with invisible XMB caching).
#define XERO_ITER_ATTR(parent_element, attribute)
void SDL_Delay(Uint32 ms)
const PSRETURN PSRETURN_OK
#define READ_FLOAT(el, out)
XMBElement GetFirstNamedItem(const int ElementName) const
virtual void SetControlGroup2(entity_id_t group2)=0
int GetElementID(const char *Name) const
std::vector< u16 > m_Heightmap
RGBColor m_TerrainAmbientColor
XMBAttributeList GetAttributes() const
XMBElementList GetChildNodes() const
#define GET_ENVIRONMENT_PROPERTY(val, prop, out)
void ResetState(bool skipScriptedComponents=false, bool skipAI=false)
Initialise (or re-initialise) the complete simulation state.
CScriptValRooted m_MapData
ssize_t GetVerticesPerSide() const
#define XERO_ITER_EL(parent_element, child_element)
virtual void ResolveFoundationCollisions()=0
Detects collisions between foundation-blocking entities and tries to fix them by setting control grou...
void SetAllPaths(const std::map< CStrW, CCinemaPath > &tracks)
std::string StringifyJSON(jsval obj, bool indent=true)
Stringify to a JSON string, UTF-8 encoded.
virtual void SetOwner(player_id_t playerID)=0
Contains pointers to various 'global' objects that are needed by the simulation code, to allow easy access without using real (evil) global variables.
CScriptValRooted ParseJSON(const std::string &string_utf8)
Parse a UTF-8-encoded JSON string.
Random map generator interface.
const entity_id_t SYSTEM_ENTITY
Entity ID for singleton 'system' components.
Public API for simulation system.
void SetMapSettings(const std::string &settings)
Set the initial map settings (as a UTF-8-encoded JSON string), which will be used to set up the simul...
float m_Elevation
Height of sun above the horizon, in radians.
RGBColor m_UnitsAmbientColor
void ReadTerrain(XMBElement parent)
void ReadEnvironment(XMBElement parent)
#define LDR_CHECK_TIMEOUT(completed_jobs, total_jobs)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
void RotateY(float angle)
const std::vector< SplineData > & GetAllNodes() const
virtual void SetYRotation(entity_angle_t y)=0
Rotate immediately to the given angle around the upwards axis.
CTerrainTextureEntry * Tex
float m_Rotation
Direction of sun on the compass, in radians.
virtual entity_id_t GetPlayerByID(int32_t id)=0
float ToFloat() const
Convert to float. May be lossy - float can't represent all values.
virtual void SetWaterLevel(entity_pos_t h)=0
Set the height of the water level, as a constant value across the whole map.
void Read(const VfsPath &filename, const char magic[4])
open and read in given file, check magic bits against those given; throw variety of exceptions if ope...
CStr ReadScriptSettings()
std::wstring templateName
ScriptInterface & GetScriptInterface() const
#define SAFE_DELETE(p)
delete memory ensuing from new and set the pointer to zero (thus making double-frees safe / a no-op) ...
CScriptValRooted m_ScriptSettings
bool undefined() const
Returns whether the value is uninitialised or is JSVAL_VOID.
size_t UnpackSize()
use UnpackRaw to retrieve 32-bits; returns their value as size_t after converting from little endian ...
bool Eval(const char *code)
void UnpackString(CStr8 &result)
unpack a string from the raw data stream.
static CFixed FromString(const CStr8 &s)
void LoadMap(const VfsPath &pathname, const CScriptValRooted &settings, CTerrain *, WaterManager *, SkyManager *, CLightEnv *, CGameView *, CCinemaManager *, CTriggerManager *, CPostprocManager *pPostproc, CSimulation2 *, const CSimContext *, int playerID, bool skipEntities)
#define READ_COLOUR(el, out)
static bool IsInitialised()
CStr8 GetNamedItem(const int AttributeName) const
bool Initialize(ssize_t patchesPerSide, const u16 *ptr)
std::string GetElementString(const int ID) const
A simplified syntax for accessing entity components.
std::vector< STileDesc > m_Tiles
const PSRETURN PSRETURN_File_ReadFailed
#define TIMER(description)
Measures the time taken to execute code up until end of the current scope; displays it via debug_prin...
bool GetProperty(jsval obj, const char *name, T &out)
Get the named property on the given object.
void LoadRandomMap(const CStrW &scriptFile, const CScriptValRooted &settings, CTerrain *, WaterManager *, SkyManager *, CLightEnv *, CGameView *, CCinemaManager *, CTriggerManager *, CPostprocManager *pPostproc_, CSimulation2 *, int playerID)
void LoadMapSettings()
Loads the map settings script (called after map is loaded)
void AddNode(const CVector3D &pos, const CVector3D &rotation, float timePeriod)
void UpdateFrustum(const CBoundingBoxAligned &scissor=CBoundingBoxAligned(CVector3D(-1.0f,-1.0f,-1.0f), CVector3D(1.0f, 1.0f, 1.0f)))
PSRETURN LoadMap(const VfsPath &pathname)
Try to load a map file.
#define GET_TERRAIN_PROPERTY(val, prop, out)
void Init(const VfsPath &xml_filename)
void ReadCamera(XMBElement parent)
XMBElement GetRoot() const
Path ChangeExtension(Path extension) const
float m_ReflectionTintStrength
void GenerateMap(const VfsPath &scriptFile, const std::string &settings)
Start the map generator thread.
virtual CFixedVector3D GetPosition()=0
Returns the current x,y,z position (no interpolation).
CPatch * GetPatch(ssize_t i, ssize_t j) const
CTriggerManager * pTrigMan
CXMLReader(const VfsPath &xml_filename, CMapReader &mapReader)
virtual void JumpTo(entity_pos_t x, entity_pos_t z)=0
Move immediately to the given location, with no interpolation.
bool VfsFileExists(const VfsPath &pathname)
virtual void ReloadTerrain()=0
Call when the underlying CTerrain has been modified behind our backs.
entity_id_t AddEntity(const std::wstring &templateName)
Construct a new entity and add it to the world.
void SetXRotation(float angle)
CMiniPatch m_MiniPatches[PATCH_SIZE][PATCH_SIZE]
shared_ptr< ScriptInterface::StructuredClone > GetResults()
Get random map data, according to this format: http://trac.wildfiregames.com/wiki/Random_Map_Generato...
entity_id_t m_StartingCameraTarget
static CFixed FromFloat(float n)
jsval get() const
Returns the current value (or JSVAL_VOID if uninitialised).
const CSimContext * pSimContext
Abstraction around a SpiderMonkey JSContext.
CSimulation2 * pSimulation2
#define debug_warn(expr)
display the error dialog with the given text.
#define GET_CAMERA_PROPERTY(val, prop, out)
void SetSkySet(const CStrW &name)
GetSkySet(): Set the sky set name, potentially loading the textures.
void RegMemFun(T *this_, int(T::*func)(void), const wchar_t *description, int estimated_duration_ms)
bool SetProperty(jsval obj, const char *name, const T &value, bool constant=false, bool enumerate=true)
Set the named property on the given object.
void ReadCinema(XMBElement parent)
u16 * GetHeightMap() const
int ReadEntities(XMBElement parent, double end_time)
Class CLightEnv: description of a lighting environment - contains all the necessary parameters for re...
XMBElement Item(const int id)
jsval ReadStructuredClone(const shared_ptr< StructuredClone > &ptr)
const entity_id_t INVALID_ENTITY
Invalid entity ID.
void SetStartupScript(const std::string &script)
Set a startup script, which will get executed before the first turn.
virtual void SetControlGroup(entity_id_t group)=0
Change the control group that the entity belongs to.
u32 entity_id_t
Entity ID type.
CVector3D GetFocus() const
JSContext * GetContext() const
void ResetCameraTarget(const CVector3D &target)
virtual void SetActorSeed(u32 seed)=0
Set actor seed for random variations and reload model.
void SetPostEffect(CStrW name)
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
void LoadPlayerSettings(bool newPlayers)
Loads the player settings script (called before map is loaded)
Class WaterManager: Maintain water settings and textures.
Class SkyManager: Maintain sky settings and textures, and render the sky.