diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp
index ed57c2c..68d052f 100644
a
|
b
|
|
1 | | /* Copyright (C) 2013 Wildfire Games. |
| 1 | /* Copyright (C) 2015 Wildfire Games. |
2 | 2 | * This file is part of 0 A.D. |
3 | 3 | * |
4 | 4 | * 0 A.D. is free software: you can redistribute it and/or modify |
… |
… |
|
19 | 19 | |
20 | 20 | #include "MapReader.h" |
21 | 21 | |
| 22 | #include <boost/algorithm/string/split.hpp> |
| 23 | #include <boost/algorithm/string/classification.hpp> |
22 | 24 | #include "graphics/Camera.h" |
23 | 25 | #include "graphics/CinemaTrack.h" |
24 | 26 | #include "graphics/Entity.h" |
… |
… |
|
28 | 30 | #include "graphics/Terrain.h" |
29 | 31 | #include "graphics/TerrainTextureEntry.h" |
30 | 32 | #include "graphics/TerrainTextureManager.h" |
| 33 | #include "graphics/Unit.h" |
31 | 34 | #include "lib/timer.h" |
32 | 35 | #include "lib/external_libraries/libsdl.h" |
33 | 36 | #include "maths/MathUtil.h" |
… |
… |
CMapReader::CMapReader()
|
60 | 63 | // Maps that don't override the default probably want the old lighting model |
61 | 64 | //m_LightEnv.SetLightingModel("old"); |
62 | 65 | //pPostproc->SetPostEffect(L"default"); |
63 | | |
| 66 | |
64 | 67 | } |
65 | 68 | |
66 | 69 | // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful |
… |
… |
void CMapReader::LoadMap(const VfsPath& pathname, JSRuntime* rt, JS::HandleValu
|
112 | 115 | // delete all existing entities |
113 | 116 | if (pSimulation2) |
114 | 117 | pSimulation2->ResetState(); |
115 | | |
| 118 | |
116 | 119 | // reset post effects |
117 | 120 | if (pPostproc) |
118 | 121 | pPostproc->SetPostEffect(L"default"); |
… |
… |
int CMapReader::ApplyTerrainData()
|
296 | 299 | |
297 | 300 | mp.Tex = m_TerrainTextures[tileptr->m_Tex1Index]; |
298 | 301 | mp.Priority = tileptr->m_Priority; |
299 | | |
| 302 | |
300 | 303 | tileptr++; |
301 | 304 | } |
302 | 305 | } |
… |
… |
int CMapReader::ApplyData()
|
324 | 327 | { |
325 | 328 | // Default to global camera (with constraints) |
326 | 329 | pGameView->ResetCameraTarget(pGameView->GetCamera()->GetFocus()); |
327 | | |
| 330 | |
328 | 331 | // TODO: Starting rotation? |
329 | 332 | CmpPtr<ICmpPlayer> cmpPlayer(*pSimContext, cmpPlayerManager->GetPlayerByID(m_PlayerID)); |
330 | 333 | if (cmpPlayer && cmpPlayer->HasStartingCamera()) |
… |
… |
void CMapSummaryReader::GetMapSettings(ScriptInterface& scriptInterface, JS::Mut
|
388 | 391 | { |
389 | 392 | JSContext* cx = scriptInterface.GetContext(); |
390 | 393 | JSAutoRequest rq(cx); |
391 | | |
| 394 | |
392 | 395 | scriptInterface.Eval("({})", ret); |
393 | 396 | if (m_ScriptSettings.empty()) |
394 | 397 | return; |
… |
… |
private:
|
439 | 442 | int at_angle; |
440 | 443 | int at_uid; |
441 | 444 | int at_seed; |
| 445 | int at_variation; |
442 | 446 | |
443 | 447 | XMBElementList nodes; // children of root |
444 | 448 | |
… |
… |
void CXMLReader::Init(const VfsPath& xml_filename)
|
490 | 494 | AT(angle); |
491 | 495 | AT(uid); |
492 | 496 | AT(seed); |
| 497 | AT(variation); |
493 | 498 | #undef AT |
494 | 499 | #undef EL |
495 | 500 | |
… |
… |
void CXMLReader::ReadEnvironment(XMBElement parent)
|
740 | 745 | // graphics are disabled |
741 | 746 | if (!m_MapReader.pWaterMan) |
742 | 747 | continue; |
743 | | |
| 748 | |
744 | 749 | if (element_name == el_type) |
745 | 750 | { |
746 | 751 | if (waterelement.GetText() == "default") |
… |
… |
void CXMLReader::ReadCinema(XMBElement parent)
|
863 | 868 | |
864 | 869 | #undef EL |
865 | 870 | #undef AT |
866 | | |
| 871 | |
867 | 872 | std::map<CStrW, CCinemaPath> pathList; |
868 | 873 | XERO_ITER_EL(parent, element) |
869 | 874 | { |
870 | 875 | int elementName = element.GetNodeName(); |
871 | | |
| 876 | |
872 | 877 | if ( elementName == el_path ) |
873 | 878 | { |
874 | 879 | XMBAttributeList attrs = element.GetAttributes(); |
… |
… |
void CXMLReader::ReadCinema(XMBElement parent)
|
891 | 896 | pathData.m_Growth = attrs.GetNamedItem(at_growth).ToInt(); |
892 | 897 | pathData.m_Switch = attrs.GetNamedItem(at_switch).ToInt(); |
893 | 898 | } |
894 | | |
| 899 | |
895 | 900 | //Load node data used for spline |
896 | 901 | else if ( elementName == el_node ) |
897 | 902 | { |
… |
… |
void CXMLReader::ReadCinema(XMBElement parent)
|
900 | 905 | { |
901 | 906 | elementName = nodeChild.GetNodeName(); |
902 | 907 | attrs = nodeChild.GetAttributes(); |
903 | | |
| 908 | |
904 | 909 | //Fix?: assumes that time is last element |
905 | 910 | if ( elementName == el_position ) |
906 | 911 | { |
… |
… |
void CXMLReader::ReadCinema(XMBElement parent)
|
920 | 925 | data.Distance = nodeChild.GetText().ToFloat(); |
921 | 926 | else |
922 | 927 | debug_warn(L"Invalid cinematic element for node child"); |
923 | | |
| 928 | |
924 | 929 | backwardSpline.AddNode(data.Position, data.Rotation, data.Distance); |
925 | 930 | } |
926 | 931 | } |
927 | 932 | else |
928 | 933 | debug_warn(L"Invalid cinematic element for path child"); |
929 | | |
930 | | |
| 934 | |
| 935 | |
931 | 936 | } |
932 | 937 | |
933 | 938 | //Construct cinema path with data gathered |
… |
… |
void CXMLReader::ReadCinema(XMBElement parent)
|
938 | 943 | debug_warn(L"Failure loading cinematics"); |
939 | 944 | return; |
940 | 945 | } |
941 | | |
| 946 | |
942 | 947 | for ( std::vector<SplineData>::const_reverse_iterator it = nodes.rbegin(); |
943 | 948 | it != nodes.rend(); ++it ) |
944 | 949 | { |
945 | 950 | spline.AddNode(it->Position, it->Rotation, it->Distance); |
946 | 951 | } |
947 | | |
| 952 | |
948 | 953 | CCinemaPath path(pathData, spline); |
949 | | pathList[name] = path; |
| 954 | pathList[name] = path; |
950 | 955 | } |
951 | 956 | else |
952 | 957 | ENSURE("Invalid cinema child"); |
… |
… |
int CXMLReader::ReadEntities(XMBElement parent, double end_time)
|
986 | 991 | CFixedVector3D Position; |
987 | 992 | CFixedVector3D Orientation; |
988 | 993 | long Seed = -1; |
| 994 | std::set<CStr> actorSelections; |
989 | 995 | |
990 | 996 | // Obstruction control groups. |
991 | 997 | entity_id_t ControlGroup = INVALID_ENTITY; |
… |
… |
int CXMLReader::ReadEntities(XMBElement parent, double end_time)
|
1035 | 1041 | else if (element_name == el_actor) |
1036 | 1042 | { |
1037 | 1043 | XMBAttributeList attrs = setting.GetAttributes(); |
1038 | | CStr seedStr = attrs.GetNamedItem(at_seed); |
1039 | | if (!seedStr.empty()) |
| 1044 | CStr variationStr = attrs.GetNamedItem(at_variation); |
| 1045 | |
| 1046 | if (!variationStr.empty()) |
1040 | 1047 | { |
1041 | | Seed = seedStr.ToLong(); |
1042 | | ENSURE(Seed >= 0); |
| 1048 | boost::algorithm::split(actorSelections, variationStr, boost::is_any_of("|")); |
| 1049 | } |
| 1050 | else |
| 1051 | { |
| 1052 | CStr seedStr = attrs.GetNamedItem(at_seed); |
| 1053 | if (!seedStr.empty()) |
| 1054 | { |
| 1055 | Seed = seedStr.ToLong(); |
| 1056 | ENSURE(Seed >= 0); |
| 1057 | } |
1043 | 1058 | } |
1044 | 1059 | } |
1045 | 1060 | else |
… |
… |
int CXMLReader::ReadEntities(XMBElement parent, double end_time)
|
1080 | 1095 | CmpPtr<ICmpVisual> cmpVisual(sim, ent); |
1081 | 1096 | if (cmpVisual) |
1082 | 1097 | { |
1083 | | if (Seed != -1) |
| 1098 | if (!actorSelections.empty()) |
| 1099 | { |
| 1100 | CUnit* unit = cmpVisual->GetUnit(); |
| 1101 | if (unit) |
| 1102 | unit->SetActorSelections(actorSelections); |
| 1103 | } |
| 1104 | else if (Seed != -1) |
1084 | 1105 | cmpVisual->SetActorSeed((u32)Seed); |
1085 | | // TODO: variation/selection strings |
1086 | 1106 | } |
1087 | 1107 | |
1088 | 1108 | if (PlayerID == m_MapReader.m_PlayerID && (boost::algorithm::ends_with(TemplateName, L"civil_centre") || m_MapReader.m_StartingCameraTarget == INVALID_ENTITY)) |
… |
… |
int CMapReader::GenerateMap()
|
1260 | 1280 | { |
1261 | 1281 | JSContext* cx = pSimulation2->GetScriptInterface().GetContext(); |
1262 | 1282 | JSAutoRequest rq(cx); |
1263 | | |
| 1283 | |
1264 | 1284 | if (!m_MapGen) |
1265 | 1285 | { |
1266 | 1286 | // Initialize map generator |
1267 | 1287 | m_MapGen = new CMapGenerator(); |
1268 | 1288 | |
1269 | 1289 | VfsPath scriptPath; |
1270 | | |
| 1290 | |
1271 | 1291 | if (m_ScriptFile.length()) |
1272 | 1292 | scriptPath = L"maps/random/"+m_ScriptFile; |
1273 | 1293 | |
1274 | 1294 | // Stringify settings to pass across threads |
1275 | 1295 | std::string scriptSettings = pSimulation2->GetScriptInterface().StringifyJSON(&m_ScriptSettings.get()); |
1276 | | |
| 1296 | |
1277 | 1297 | // Try to generate map |
1278 | 1298 | m_MapGen->GenerateMap(scriptPath, scriptSettings); |
1279 | 1299 | } |
… |
… |
int CMapReader::GenerateMap()
|
1293 | 1313 | // Parse data into simulation context |
1294 | 1314 | JS::RootedValue data(cx); |
1295 | 1315 | pSimulation2->GetScriptInterface().ReadStructuredClone(results, &data); |
1296 | | |
| 1316 | |
1297 | 1317 | if (data.isUndefined()) |
1298 | 1318 | { |
1299 | 1319 | // RMS failed - return to main menu |
… |
… |
int CMapReader::GenerateMap()
|
1312 | 1332 | // to allow more CPU for the map generator thread |
1313 | 1333 | SDL_Delay(100); |
1314 | 1334 | } |
1315 | | |
| 1335 | |
1316 | 1336 | // return progress |
1317 | 1337 | return progress; |
1318 | 1338 | }; |
… |
… |
int CMapReader::ParseTerrain()
|
1323 | 1343 | TIMER(L"ParseTerrain"); |
1324 | 1344 | JSContext* cx = pSimulation2->GetScriptInterface().GetContext(); |
1325 | 1345 | JSAutoRequest rq(cx); |
1326 | | |
| 1346 | |
1327 | 1347 | // parse terrain from map data |
1328 | 1348 | // an error here should stop the loading process |
1329 | 1349 | #define GET_TERRAIN_PROPERTY(val, prop, out)\ |
… |
… |
int CMapReader::ParseTerrain()
|
1376 | 1396 | { |
1377 | 1397 | size_t patchY = y / PATCH_SIZE; |
1378 | 1398 | size_t offY = y % PATCH_SIZE; |
1379 | | |
| 1399 | |
1380 | 1400 | STileDesc tile; |
1381 | 1401 | tile.m_Tex1Index = tileIndex[y*size + x]; |
1382 | 1402 | tile.m_Tex2Index = 0xFFFF; |
… |
… |
int CMapReader::ParseEntities()
|
1411 | 1431 | |
1412 | 1432 | size_t entity_idx = 0; |
1413 | 1433 | size_t num_entities = entities.size(); |
1414 | | |
| 1434 | |
1415 | 1435 | Entity currEnt; |
1416 | 1436 | |
1417 | 1437 | while (entity_idx < num_entities) |
… |
… |
int CMapReader::ParseEnvironment()
|
1493 | 1513 | |
1494 | 1514 | GET_ENVIRONMENT_PROPERTY(envObj, SunElevation, m_LightEnv.m_Elevation) |
1495 | 1515 | GET_ENVIRONMENT_PROPERTY(envObj, SunRotation, m_LightEnv.m_Rotation) |
1496 | | |
| 1516 | |
1497 | 1517 | CColor terrainAmbientColor; |
1498 | 1518 | GET_ENVIRONMENT_PROPERTY(envObj, TerrainAmbientColor, terrainAmbientColor) |
1499 | 1519 | m_LightEnv.m_TerrainAmbientColor = RGBColor(terrainAmbientColor.r, terrainAmbientColor.g, terrainAmbientColor.b); |
diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp
index 9d59ac0..fa6281f 100644
a
|
b
|
|
1 | | /* Copyright (C) 2014 Wildfire Games. |
| 1 | /* Copyright (C) 2015 Wildfire Games. |
2 | 2 | * This file is part of 0 A.D. |
3 | 3 | * |
4 | 4 | * 0 A.D. is free software: you can redistribute it and/or modify |
… |
… |
|
27 | 27 | #include "Terrain.h" |
28 | 28 | #include "TerrainTextureEntry.h" |
29 | 29 | #include "TerrainTextureManager.h" |
| 30 | #include "Unit.h" |
30 | 31 | |
| 32 | |
| 33 | #include <boost/algorithm/string/join.hpp> |
31 | 34 | #include "maths/MathUtil.h" |
32 | 35 | #include "maths/NUSpline.h" |
33 | 36 | #include "ps/CLogger.h" |
… |
… |
void CMapWriter::EnumTerrainTextures(CTerrain *pTerrain,
|
103 | 106 | { |
104 | 107 | // the list of all handles in use |
105 | 108 | std::vector<CTerrainTextureEntry*> entries; |
106 | | |
| 109 | |
107 | 110 | // resize tile array to required size |
108 | 111 | tiles.resize(SQR(pTerrain->GetVerticesPerSide()-1)); |
109 | 112 | STileDesc* tileptr=&tiles[0]; |
… |
… |
void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain* pTerrain)
|
160 | 163 | // pack map size |
161 | 164 | const ssize_t mapsize = pTerrain->GetPatchesPerSide(); |
162 | 165 | packer.PackSize(mapsize); |
163 | | |
| 166 | |
164 | 167 | // pack heightmap |
165 | | packer.PackRaw(pTerrain->GetHeightMap(),sizeof(u16)*SQR(pTerrain->GetVerticesPerSide())); |
| 168 | packer.PackRaw(pTerrain->GetHeightMap(),sizeof(u16)*SQR(pTerrain->GetVerticesPerSide())); |
166 | 169 | |
167 | 170 | // the list of textures used by map |
168 | 171 | std::vector<CStr> terrainTextures; |
169 | 172 | // descriptions of each tile |
170 | 173 | std::vector<STileDesc> tiles; |
171 | | |
| 174 | |
172 | 175 | // build lists by scanning through the terrain |
173 | 176 | EnumTerrainTextures(pTerrain, terrainTextures, tiles); |
174 | | |
| 177 | |
175 | 178 | // pack texture names |
176 | 179 | const size_t numTextures = terrainTextures.size(); |
177 | 180 | packer.PackSize(numTextures); |
178 | 181 | for (size_t i=0;i<numTextures;i++) |
179 | 182 | packer.PackString(terrainTextures[i]); |
180 | | |
| 183 | |
181 | 184 | // pack tile data |
182 | 185 | packer.PackRaw(&tiles[0],sizeof(STileDesc)*tiles.size()); |
183 | 186 | } |
… |
… |
void CMapWriter::WriteXML(const VfsPath& filename,
|
270 | 273 | XML_Setting("WindAngle", pWaterMan->m_WindAngle); |
271 | 274 | } |
272 | 275 | } |
273 | | |
| 276 | |
274 | 277 | { |
275 | 278 | XML_Element("Postproc"); |
276 | 279 | { |
… |
… |
void CMapWriter::WriteXML(const VfsPath& filename,
|
386 | 389 | CmpPtr<ICmpVisual> cmpVisual(sim, ent); |
387 | 390 | if (cmpVisual) |
388 | 391 | { |
| 392 | CUnit* unit = cmpVisual->GetUnit(); |
389 | 393 | u32 seed = cmpVisual->GetActorSeed(); |
390 | | if (seed != (u32)ent) |
| 394 | bool variationsAdded = false; |
| 395 | XML_Element("Actor"); |
| 396 | if (unit) |
391 | 397 | { |
392 | | XML_Element("Actor"); |
393 | | XML_Attribute("seed", seed); |
| 398 | const std::set<CStr>& actorSelections = unit->GetActorSelections(); |
| 399 | |
| 400 | if (!actorSelections.empty()) |
| 401 | { |
| 402 | CStr actorSelectionsStr = boost::algorithm::join(unit->GetActorSelections(), "|"); |
| 403 | XML_Attribute("variation", actorSelectionsStr.c_str()); |
| 404 | variationsAdded = true; |
| 405 | } |
394 | 406 | } |
395 | | // TODO: variation/selection strings |
| 407 | if (!variationsAdded && seed != (u32)ent) |
| 408 | XML_Attribute("seed", seed); |
396 | 409 | } |
397 | 410 | } |
398 | 411 | } |
399 | 412 | |
400 | 413 | const std::map<CStrW, CCinemaPath>& paths = pCinema->GetAllPaths(); |
401 | 414 | std::map<CStrW, CCinemaPath>::const_iterator it = paths.begin(); |
402 | | |
| 415 | |
403 | 416 | { |
404 | 417 | XML_Element("Paths"); |
405 | 418 | |
… |
… |
void CMapWriter::WriteXML(const VfsPath& filename,
|
407 | 420 | { |
408 | 421 | CStrW name = it->first; |
409 | 422 | float timescale = it->second.GetTimescale(); |
410 | | |
| 423 | |
411 | 424 | XML_Element("Path"); |
412 | 425 | XML_Attribute("name", name); |
413 | 426 | XML_Attribute("timescale", timescale); |
414 | 427 | |
415 | 428 | const std::vector<SplineData>& nodes = it->second.GetAllNodes(); |
416 | 429 | const CCinemaData* data = it->second.GetData(); |
417 | | |
| 430 | |
418 | 431 | { |
419 | 432 | XML_Element("Distortion"); |
420 | 433 | XML_Attribute("mode", data->m_Mode); |
… |
… |
void CMapWriter::WriteXML(const VfsPath& filename,
|
426 | 439 | for ( ssize_t j=nodes.size()-1; j >= 0; --j ) |
427 | 440 | { |
428 | 441 | XML_Element("Node"); |
429 | | |
| 442 | |
430 | 443 | { |
431 | 444 | XML_Element("Position"); |
432 | 445 | XML_Attribute("x", nodes[j].Position.X); |