Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/MapWriter.cpp
Show First 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void CMapWriter::WriteXML(const VfsPath& filename, | void CMapWriter::WriteXML(const VfsPath& filename, | ||||
WaterManager* pWaterMan, SkyManager* pSkyMan, | WaterManager* pWaterMan, SkyManager* pSkyMan, | ||||
CLightEnv* pLightEnv, CCamera* pCamera, | CLightEnv* pLightEnv, CCamera* pCamera, | ||||
CPostprocManager* pPostproc, | CPostprocManager* pPostproc, | ||||
CSimulation2* pSimulation2) | CSimulation2* pSimulation2) | ||||
{ | { | ||||
XML_Start(); | XMLWriter_File xmlMapFile; | ||||
{ | { | ||||
XML_Element("Scenario"); | XMLWriter_Element scenarioTag(xmlMapFile, "Scenario"); | ||||
XML_Attribute("version", (int)FILE_VERSION); | scenarioTag.Attribute("version", static_cast<int>(FILE_VERSION)); | ||||
ENSURE(pSimulation2); | ENSURE(pSimulation2); | ||||
CSimulation2& sim = *pSimulation2; | CSimulation2& sim = *pSimulation2; | ||||
if (!sim.GetStartupScript().empty()) | if (!sim.GetStartupScript().empty()) | ||||
{ | { | ||||
XML_Element("Script"); | XMLWriter_Element scriptTag(xmlMapFile, "Script"); | ||||
XML_CDATA(sim.GetStartupScript().c_str()); | scriptTag.Text(sim.GetStartupScript().c_str(), true); | ||||
} | } | ||||
{ | { | ||||
XML_Element("Environment"); | XMLWriter_Element environmentTag(xmlMapFile, "Environment"); | ||||
environmentTag.Setting("SkySet", pSkyMan->GetSkySet()); | |||||
XML_Setting("SkySet", pSkyMan->GetSkySet()); | |||||
{ | { | ||||
XML_Element("SunColor"); | XMLWriter_Element sunColorTag(xmlMapFile, "SunColor"); | ||||
XML_Attribute("r", pLightEnv->m_SunColor.X); // yes, it's X/Y/Z... | sunColorTag.Attribute("r", pLightEnv->m_SunColor.X); // yes, it's X/Y/Z... | ||||
XML_Attribute("g", pLightEnv->m_SunColor.Y); | sunColorTag.Attribute("g", pLightEnv->m_SunColor.Y); | ||||
XML_Attribute("b", pLightEnv->m_SunColor.Z); | sunColorTag.Attribute("b", pLightEnv->m_SunColor.Z); | ||||
} | } | ||||
{ | { | ||||
XML_Element("SunElevation"); | XMLWriter_Element SunElevationTag(xmlMapFile, "SunElevation"); | ||||
XML_Attribute("angle", pLightEnv->m_Elevation); | SunElevationTag.Attribute("angle", pLightEnv->m_Elevation); | ||||
} | } | ||||
{ | { | ||||
XML_Element("SunRotation"); | XMLWriter_Element sunRotationTag(xmlMapFile, "SunRotation"); | ||||
XML_Attribute("angle", pLightEnv->m_Rotation); | sunRotationTag.Attribute("angle", pLightEnv->m_Rotation); | ||||
} | } | ||||
{ | { | ||||
XML_Element("TerrainAmbientColor"); | XMLWriter_Element terrainAmbientColorTag(xmlMapFile, "TerrainAmbientColor"); | ||||
XML_Attribute("r", pLightEnv->m_TerrainAmbientColor.X); | terrainAmbientColorTag.Attribute("r", pLightEnv->m_TerrainAmbientColor.X); | ||||
XML_Attribute("g", pLightEnv->m_TerrainAmbientColor.Y); | terrainAmbientColorTag.Attribute("g", pLightEnv->m_TerrainAmbientColor.Y); | ||||
XML_Attribute("b", pLightEnv->m_TerrainAmbientColor.Z); | terrainAmbientColorTag.Attribute("b", pLightEnv->m_TerrainAmbientColor.Z); | ||||
} | } | ||||
{ | { | ||||
XML_Element("UnitsAmbientColor"); | XMLWriter_Element unitsAmbientColorTag(xmlMapFile, "UnitsAmbientColor"); | ||||
XML_Attribute("r", pLightEnv->m_UnitsAmbientColor.X); | unitsAmbientColorTag.Attribute("r", pLightEnv->m_UnitsAmbientColor.X); | ||||
XML_Attribute("g", pLightEnv->m_UnitsAmbientColor.Y); | unitsAmbientColorTag.Attribute("g", pLightEnv->m_UnitsAmbientColor.Y); | ||||
XML_Attribute("b", pLightEnv->m_UnitsAmbientColor.Z); | unitsAmbientColorTag.Attribute("b", pLightEnv->m_UnitsAmbientColor.Z); | ||||
} | } | ||||
{ | { | ||||
XML_Element("Fog"); | XMLWriter_Element fogTag(xmlMapFile, "Fog"); | ||||
XML_Setting("FogFactor", pLightEnv->m_FogFactor); | fogTag.Setting("FogFactor", pLightEnv->m_FogFactor); | ||||
XML_Setting("FogThickness", pLightEnv->m_FogMax); | fogTag.Setting("FogThickness", pLightEnv->m_FogMax); | ||||
{ | { | ||||
XML_Element("FogColor"); | XMLWriter_Element fogColorTag(xmlMapFile, "FogColor"); | ||||
XML_Attribute("r", pLightEnv->m_FogColor.X); | fogColorTag.Attribute("r", pLightEnv->m_FogColor.X); | ||||
XML_Attribute("g", pLightEnv->m_FogColor.Y); | fogColorTag.Attribute("g", pLightEnv->m_FogColor.Y); | ||||
XML_Attribute("b", pLightEnv->m_FogColor.Z); | fogColorTag.Attribute("b", pLightEnv->m_FogColor.Z); | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
XML_Element("Water"); | XMLWriter_Element waterTag(xmlMapFile, "Water"); | ||||
{ | { | ||||
XML_Element("WaterBody"); | XMLWriter_Element waterBodyTag(xmlMapFile, "WaterBody"); | ||||
CmpPtr<ICmpWaterManager> cmpWaterManager(sim, SYSTEM_ENTITY); | CmpPtr<ICmpWaterManager> cmpWaterManager(sim, SYSTEM_ENTITY); | ||||
ENSURE(cmpWaterManager); | ENSURE(cmpWaterManager); | ||||
XML_Setting("Type", pWaterMan->m_WaterType); | waterBodyTag.Setting("Type", pWaterMan->m_WaterType); | ||||
{ | { | ||||
XML_Element("Color"); | XMLWriter_Element colorTag(xmlMapFile, "Color"); | ||||
XML_Attribute("r", pWaterMan->m_WaterColor.r); | colorTag.Attribute("r", pWaterMan->m_WaterColor.r); | ||||
XML_Attribute("g", pWaterMan->m_WaterColor.g); | colorTag.Attribute("g", pWaterMan->m_WaterColor.g); | ||||
XML_Attribute("b", pWaterMan->m_WaterColor.b); | colorTag.Attribute("b", pWaterMan->m_WaterColor.b); | ||||
} | } | ||||
{ | { | ||||
XML_Element("Tint"); | XMLWriter_Element tintTag(xmlMapFile, "Tint"); | ||||
XML_Attribute("r", pWaterMan->m_WaterTint.r); | tintTag.Attribute("r", pWaterMan->m_WaterTint.r); | ||||
XML_Attribute("g", pWaterMan->m_WaterTint.g); | tintTag.Attribute("g", pWaterMan->m_WaterTint.g); | ||||
XML_Attribute("b", pWaterMan->m_WaterTint.b); | tintTag.Attribute("b", pWaterMan->m_WaterTint.b); | ||||
} | } | ||||
XML_Setting("Height", cmpWaterManager->GetExactWaterLevel(0, 0)); | waterBodyTag.Setting("Height", cmpWaterManager->GetExactWaterLevel(0, 0)); | ||||
XML_Setting("Waviness", pWaterMan->m_Waviness); | waterBodyTag.Setting("Waviness", pWaterMan->m_Waviness); | ||||
XML_Setting("Murkiness", pWaterMan->m_Murkiness); | waterBodyTag.Setting("Murkiness", pWaterMan->m_Murkiness); | ||||
XML_Setting("WindAngle", pWaterMan->m_WindAngle); | waterBodyTag.Setting("WindAngle", pWaterMan->m_WindAngle); | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
XML_Element("Postproc"); | XMLWriter_Element postProcTag(xmlMapFile, "Postproc"); | ||||
{ | { | ||||
XML_Setting("Brightness", pLightEnv->m_Brightness); | postProcTag.Setting("Brightness", pLightEnv->m_Brightness); | ||||
XML_Setting("Contrast", pLightEnv->m_Contrast); | postProcTag.Setting("Contrast", pLightEnv->m_Contrast); | ||||
XML_Setting("Saturation", pLightEnv->m_Saturation); | postProcTag.Setting("Saturation", pLightEnv->m_Saturation); | ||||
XML_Setting("Bloom", pLightEnv->m_Bloom); | postProcTag.Setting("Bloom", pLightEnv->m_Bloom); | ||||
XML_Setting("PostEffect", pPostproc->GetPostEffect()); | postProcTag.Setting("PostEffect", pPostproc->GetPostEffect()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
XML_Element("Camera"); | XMLWriter_Element cameraTag(xmlMapFile, "Camera"); | ||||
{ | { | ||||
XML_Element("Position"); | XMLWriter_Element positionTag(xmlMapFile, "Position"); | ||||
CVector3D pos = pCamera->m_Orientation.GetTranslation(); | CVector3D pos = pCamera->m_Orientation.GetTranslation(); | ||||
XML_Attribute("x", pos.X); | positionTag.Attribute("x", pos.X); | ||||
XML_Attribute("y", pos.Y); | positionTag.Attribute("y", pos.Y); | ||||
XML_Attribute("z", pos.Z); | positionTag.Attribute("z", pos.Z); | ||||
} | } | ||||
CVector3D in = pCamera->m_Orientation.GetIn(); | CVector3D in = pCamera->m_Orientation.GetIn(); | ||||
// Convert to spherical coordinates | // Convert to spherical coordinates | ||||
float rotation = atan2(in.X, in.Z); | float rotation = atan2(in.X, in.Z); | ||||
float declination = atan2(sqrt(in.X*in.X + in.Z*in.Z), in.Y) - (float)M_PI/2; | float declination = atan2(sqrt(in.X*in.X + in.Z*in.Z), in.Y) - static_cast<float>(M_PI / 2); | ||||
{ | { | ||||
XML_Element("Rotation"); | XMLWriter_Element rotationTag(xmlMapFile, "Rotation"); | ||||
XML_Attribute("angle", rotation); | rotationTag.Attribute("angle", rotation); | ||||
} | } | ||||
{ | { | ||||
XML_Element("Declination"); | XMLWriter_Element declinationTag(xmlMapFile, "Declination"); | ||||
XML_Attribute("angle", declination); | declinationTag.Attribute("angle", declination); | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
std::string settings = sim.GetMapSettingsString(); | std::string settings = sim.GetMapSettingsString(); | ||||
if (!settings.empty()) | if (!settings.empty()) | ||||
{ | { | ||||
XML_Element("ScriptSettings"); | XMLWriter_Element scriptSettingsTag(xmlMapFile, "ScriptSettings"); | ||||
XML_CDATA(("\n" + settings + "\n").c_str()); | scriptSettingsTag.Text(("\n" + settings + "\n").c_str(), true); | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
XML_Element("Entities"); | XMLWriter_Element entitiesTag(xmlMapFile, "Entities"); | ||||
CmpPtr<ICmpTemplateManager> cmpTemplateManager(sim, SYSTEM_ENTITY); | CmpPtr<ICmpTemplateManager> cmpTemplateManager(sim, SYSTEM_ENTITY); | ||||
ENSURE(cmpTemplateManager); | ENSURE(cmpTemplateManager); | ||||
// This will probably need to be changed in the future, but for now we'll | // This will probably need to be changed in the future, but for now we'll | ||||
// just save all entities that have a position | // just save all entities that have a position | ||||
CSimulation2::InterfaceList ents = sim.GetEntitiesWithInterface(IID_Position); | CSimulation2::InterfaceList ents = sim.GetEntitiesWithInterface(IID_Position); | ||||
for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it) | for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it) | ||||
{ | { | ||||
entity_id_t ent = it->first; | entity_id_t ent = it->first; | ||||
// Don't save local entities (placement previews etc) | // Don't save local entities (placement previews etc) | ||||
if (ENTITY_IS_LOCAL(ent)) | if (ENTITY_IS_LOCAL(ent)) | ||||
continue; | continue; | ||||
XML_Element("Entity"); | XMLWriter_Element entityTag(xmlMapFile, "Entity"); | ||||
XML_Attribute("uid", ent); | entityTag.Attribute("uid", ent); | ||||
XML_Setting("Template", cmpTemplateManager->GetCurrentTemplateName(ent)); | entityTag.Setting("Template", cmpTemplateManager->GetCurrentTemplateName(ent)); | ||||
CmpPtr<ICmpOwnership> cmpOwnership(sim, ent); | CmpPtr<ICmpOwnership> cmpOwnership(sim, ent); | ||||
if (cmpOwnership) | if (cmpOwnership) | ||||
XML_Setting("Player", (int)cmpOwnership->GetOwner()); | entityTag.Setting("Player", static_cast<int>(cmpOwnership->GetOwner())); | ||||
CmpPtr<ICmpPosition> cmpPosition(sim, ent); | CmpPtr<ICmpPosition> cmpPosition(sim, ent); | ||||
if (cmpPosition) | if (cmpPosition) | ||||
{ | { | ||||
CFixedVector3D pos; | CFixedVector3D pos; | ||||
if (cmpPosition->IsInWorld()) | if (cmpPosition->IsInWorld()) | ||||
pos = cmpPosition->GetPosition(); | pos = cmpPosition->GetPosition(); | ||||
CFixedVector3D rot = cmpPosition->GetRotation(); | CFixedVector3D rot = cmpPosition->GetRotation(); | ||||
{ | { | ||||
XML_Element("Position"); | XMLWriter_Element positionTag(xmlMapFile, "Position"); | ||||
XML_Attribute("x", pos.X); | positionTag.Attribute("x", pos.X); | ||||
XML_Attribute("z", pos.Z); | positionTag.Attribute("z", pos.Z); | ||||
// TODO: height offset etc | // TODO: height offset etc | ||||
} | } | ||||
{ | { | ||||
XML_Element("Orientation"); | XMLWriter_Element orientationTag(xmlMapFile, "Orientation"); | ||||
XML_Attribute("y", rot.Y); | orientationTag.Attribute("y", rot.Y); | ||||
// TODO: X, Z maybe | // TODO: X, Z maybe | ||||
} | } | ||||
} | } | ||||
CmpPtr<ICmpObstruction> cmpObstruction(sim, ent); | CmpPtr<ICmpObstruction> cmpObstruction(sim, ent); | ||||
if (cmpObstruction) | if (cmpObstruction) | ||||
{ | { | ||||
// TODO: Currently only necessary because Atlas | // TODO: Currently only necessary because Atlas | ||||
// does not set up control groups for its walls. | // does not set up control groups for its walls. | ||||
cmpObstruction->ResolveFoundationCollisions(); | cmpObstruction->ResolveFoundationCollisions(); | ||||
entity_id_t group = cmpObstruction->GetControlGroup(); | entity_id_t group = cmpObstruction->GetControlGroup(); | ||||
entity_id_t group2 = cmpObstruction->GetControlGroup2(); | entity_id_t group2 = cmpObstruction->GetControlGroup2(); | ||||
// Don't waste space writing the default control groups. | // Don't waste space writing the default control groups. | ||||
if (group != ent || group2 != INVALID_ENTITY) | if (group != ent || group2 != INVALID_ENTITY) | ||||
{ | { | ||||
XML_Element("Obstruction"); | XMLWriter_Element obstructionTag(xmlMapFile, "Obstruction"); | ||||
if (group != ent) | if (group != ent) | ||||
XML_Attribute("group", group); | obstructionTag.Attribute("group", group); | ||||
if (group2 != INVALID_ENTITY) | if (group2 != INVALID_ENTITY) | ||||
XML_Attribute("group2", group2); | obstructionTag.Attribute("group2", group2); | ||||
} | } | ||||
} | } | ||||
CmpPtr<ICmpVisual> cmpVisual(sim, ent); | CmpPtr<ICmpVisual> cmpVisual(sim, ent); | ||||
if (cmpVisual) | if (cmpVisual) | ||||
{ | { | ||||
u32 seed = cmpVisual->GetActorSeed(); | entity_id_t seed = static_cast<entity_id_t>(cmpVisual->GetActorSeed()); | ||||
if (seed != (u32)ent) | if (seed != ent) | ||||
{ | { | ||||
XML_Element("Actor"); | XMLWriter_Element actorTag(xmlMapFile, "Actor"); | ||||
XML_Attribute("seed", seed); | actorTag.Attribute("seed",seed); | ||||
} | } | ||||
// TODO: variation/selection strings | // TODO: variation/selection strings | ||||
} | } | ||||
} | } | ||||
} | } | ||||
CmpPtr<ICmpCinemaManager> cmpCinemaManager(sim, SYSTEM_ENTITY); | CmpPtr<ICmpCinemaManager> cmpCinemaManager(sim, SYSTEM_ENTITY); | ||||
if (cmpCinemaManager) | if (cmpCinemaManager) | ||||
{ | { | ||||
const std::map<CStrW, CCinemaPath>& paths = cmpCinemaManager->GetPaths(); | const std::map<CStrW, CCinemaPath>& paths = cmpCinemaManager->GetPaths(); | ||||
std::map<CStrW, CCinemaPath>::const_iterator it = paths.begin(); | std::map<CStrW, CCinemaPath>::const_iterator it = paths.begin(); | ||||
XML_Element("Paths"); | XMLWriter_Element pathsTag(xmlMapFile, "Paths"); | ||||
for ( ; it != paths.end(); ++it ) | for ( ; it != paths.end(); ++it ) | ||||
{ | { | ||||
fixed timescale = it->second.GetTimescale(); | fixed timescale = it->second.GetTimescale(); | ||||
const std::vector<SplineData>& position_nodes = it->second.GetAllNodes(); | const std::vector<SplineData>& position_nodes = it->second.GetAllNodes(); | ||||
const std::vector<SplineData>& target_nodes = it->second.GetTargetSpline().GetAllNodes(); | const std::vector<SplineData>& target_nodes = it->second.GetTargetSpline().GetAllNodes(); | ||||
const CCinemaData* data = it->second.GetData(); | const CCinemaData* data = it->second.GetData(); | ||||
XML_Element("Path"); | XMLWriter_Element pathTag(xmlMapFile, "Path"); | ||||
XML_Attribute("name", data->m_Name); | pathTag.Attribute("name", data->m_Name); | ||||
XML_Attribute("timescale", timescale); | pathTag.Attribute("timescale", timescale); | ||||
XML_Attribute("orientation", data->m_Orientation); | pathTag.Attribute("orientation", data->m_Orientation); | ||||
XML_Attribute("mode", data->m_Mode); | pathTag.Attribute("mode", data->m_Mode); | ||||
XML_Attribute("style", data->m_Style); | pathTag.Attribute("style", data->m_Style); | ||||
struct SEvent | struct SEvent | ||||
{ | { | ||||
fixed time; | fixed time; | ||||
const char* type; | const char* type; | ||||
CFixedVector3D value; | CFixedVector3D value; | ||||
SEvent(fixed time, const char* type, CFixedVector3D value) | SEvent(fixed time, const char* type, CFixedVector3D value) | ||||
: time(time), type(type), value(value) | : time(time), type(type), value(value) | ||||
Show All 22 Lines | if (cmpCinemaManager) | ||||
fixed distance = i > 0 ? target_nodes[i - 1].Distance : fixed::Zero(); | fixed distance = i > 0 ? target_nodes[i - 1].Distance : fixed::Zero(); | ||||
last_target += distance; | last_target += distance; | ||||
events.emplace_back(last_target, "Target", target_nodes[i].Position); | events.emplace_back(last_target, "Target", target_nodes[i].Position); | ||||
} | } | ||||
std::sort(events.begin(), events.end()); | std::sort(events.begin(), events.end()); | ||||
for (size_t i = 0; i < events.size();) | for (size_t i = 0; i < events.size();) | ||||
{ | { | ||||
XML_Element("Node"); | XMLWriter_Element nodeTag(xmlMapFile, "Node"); | ||||
fixed deltatime = i > 0 ? (events[i].time - events[i - 1].time) : fixed::Zero(); | fixed deltatime = i > 0 ? (events[i].time - events[i - 1].time) : fixed::Zero(); | ||||
XML_Attribute("deltatime", deltatime); | nodeTag.Attribute("deltatime", deltatime); | ||||
size_t j = i; | size_t j = i; | ||||
for (; j < events.size() && events[j].time == events[i].time; ++j) | for (; j < events.size() && events[j].time == events[i].time; ++j) | ||||
{ | { | ||||
// Types: Position/Rotation/Target | // Types: Position/Rotation/Target | ||||
XML_Element(events[j].type); | XMLWriter_Element eventTypeTag(xmlMapFile, events[j].type); | ||||
XML_Attribute("x", events[j].value.X); | eventTypeTag.Attribute("x", events[j].value.X); | ||||
XML_Attribute("y", events[j].value.Y); | eventTypeTag.Attribute("y", events[j].value.Y); | ||||
XML_Attribute("z", events[j].value.Z); | eventTypeTag.Attribute("z", events[j].value.Z); | ||||
} | } | ||||
i = j; | i = j; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (!XML_StoreVFS(g_VFS, filename)) | if (!xmlMapFile.StoreVFS(g_VFS, filename)) | ||||
LOGERROR("Failed to write map '%s'", filename.string8()); | LOGERROR("Failed to write map '%s'", filename.string8()); | ||||
} | } |
Wildfire Games · Phabricator