Index: source/graphics/MapReader.cpp =================================================================== --- source/graphics/MapReader.cpp +++ source/graphics/MapReader.cpp @@ -28,6 +28,7 @@ #include "graphics/Terrain.h" #include "graphics/TerrainTextureEntry.h" #include "graphics/TerrainTextureManager.h" +#include "graphics/unit.h" #include "lib/timer.h" #include "lib/external_libraries/libsdl.h" #include "maths/MathUtil.h" @@ -421,6 +422,7 @@ int at_angle; int at_uid; int at_seed; + int at_variation; XMBElementList nodes; // children of root @@ -472,6 +474,7 @@ AT(angle); AT(uid); AT(seed); + AT(variation); #undef AT #undef EL @@ -948,6 +951,7 @@ CFixedVector3D Position; CFixedVector3D Orientation; long Seed = -1; + std::set actorSelections; // Obstruction control groups. entity_id_t ControlGroup = INVALID_ENTITY; @@ -1003,6 +1007,16 @@ Seed = seedStr.ToLong(); ENSURE(Seed >= 0); } + + CStr variationStr = attrs.GetNamedItem(at_variation); + if (!variationStr.empty()) + { + std::istringstream f(variationStr); + std::string s; + while (getline(f, s, '|')) { + actorSelections.insert(s); + } + } } else debug_warn(L"Invalid map XML data"); @@ -1044,7 +1058,15 @@ { if (Seed != -1) cmpVisual->SetActorSeed((u32)Seed); - // TODO: variation/selection strings + + if (!actorSelections.empty()) + { + CUnit* unit = cmpVisual->GetUnit(); + if (unit) + { + unit->SetActorSelections(actorSelections); + } + } } if (PlayerID == m_MapReader.m_PlayerID && (boost::algorithm::ends_with(TemplateName, L"civil_centre") || m_MapReader.m_StartingCameraTarget == INVALID_ENTITY)) Index: source/graphics/MapWriter.cpp =================================================================== --- source/graphics/MapWriter.cpp +++ source/graphics/MapWriter.cpp @@ -27,6 +27,7 @@ #include "Terrain.h" #include "TerrainTextureEntry.h" #include "TerrainTextureManager.h" +#include "Unit.h" #include "maths/MathUtil.h" #include "maths/NUSpline.h" @@ -387,12 +388,32 @@ if (cmpVisual) { entity_id_t seed = static_cast(cmpVisual->GetActorSeed()); + + XMLWriter_Element actorTag(xmlMapFile, "Actor"); + if (seed != ent) { - XMLWriter_Element actorTag(xmlMapFile, "Actor"); actorTag.Attribute("seed",seed); } - // TODO: variation/selection strings + + CUnit* unit = cmpVisual->GetUnit(); + if (unit) + { + const std::set& selections = unit->GetActorSelections(); + + if (!selections.empty()) + { + std::string sSelections; + for (const CStr& selection : selections) + { + if (!sSelections.empty()) + sSelections += "|"; + + sSelections += selection; + } + actorTag.Attribute("variation", sSelections); + } + } } } } Index: source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp =================================================================== --- source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp +++ source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp @@ -203,47 +203,50 @@ settings.player = player; } - // TODO: selections - -/* - // Get the unit's possible variants and selected variants - std::vector > groups = unit->GetObject().m_Base->GetVariantGroups(); - const std::set& selections = unit->GetActorSelections(); - - // Iterate over variant groups - std::vector > variantgroups; + std::vector> variantgroups; std::set selections_set; - variantgroups.reserve(groups.size()); - for (size_t i = 0; i < groups.size(); ++i) + + CmpPtr cmpVisualActor(*simulation, view->GetEntityId(msg->id)); + if (cmpVisualActor) { - // Copy variants into output structure + CUnit* unit = cmpVisualActor->GetUnit(); + if (unit) + { + std::vector> groups = unit->GetObject().m_Base->GetVariantGroups(); + const std::set& selections = unit->GetActorSelections(); + variantgroups.reserve(groups.size()); - std::vector group; - group.reserve(groups[i].size()); - int choice = -1; + for (size_t i = 0; i < groups.size(); ++i) + { + // Copy variants into output structure - for (size_t j = 0; j < groups[i].size(); ++j) - { - group.push_back(CStrW(groups[i][j])); + std::vector subgroup; + subgroup.reserve(groups[i].size()); + int choice = -1; - // Find the first string in 'selections' that matches one of this - // group's variants - if (choice == -1) - if (selections.find(groups[i][j]) != selections.end()) - choice = (int)j; - } + for (size_t j = 0; j < groups[i].size(); ++j) + { + subgroup.push_back(wstring_from_utf8(groups[i][j])); - // Assuming one of the variants was selected (which it really ought - // to be), remember that one's name - if (choice != -1) - selections_set.insert(CStrW(groups[i][choice])); + // Find the first string in 'selections' that matches one of this + // group's variants + if (choice == -1) + if (selections.find(groups[i][j]) != selections.end()) + choice = (int)j; + } + + // Assuming one of the variants was selected (which it really ought + // to be), remember that one's name + if (choice != -1) + selections_set.insert(wstring_from_utf8(groups[i][choice])); - variantgroups.push_back(group); + variantgroups.push_back(subgroup); + } + } } - settings.variantgroups = variantgroups; + settings.variantGroups = variantgroups; settings.selections = std::vector (selections_set.begin(), selections_set.end()); // convert set->vector -*/ msg->settings = settings; } @@ -325,8 +328,13 @@ m_PlayerOld = player; } - // TODO: selections -// m_SelectionsOld = unit->GetActorSelections(); + CmpPtr cmpVisualActor(*simulation, view->GetEntityId(msg->id)); + if (cmpVisualActor) + { + CUnit* unit = cmpVisualActor->GetUnit(); + if (unit) + m_SelectionsOld = unit->GetActorSelections(); + } m_PlayerNew = (player_id_t)settings.player; @@ -350,7 +358,7 @@ } private: - void Set(player_id_t player, const std::set& UNUSED(selections)) + void Set(player_id_t player, const std::set& selections) { AtlasView* view = AtlasView::GetView(msg->view); CSimulation2* simulation = view->GetSimulation2(); @@ -359,8 +367,13 @@ if (cmpOwnership) cmpOwnership->SetOwner(player); - // TODO: selections -// unit->SetActorSelections(selections); + CmpPtr cmpVisualActor(*simulation, view->GetEntityId(msg->id)); + if (cmpVisualActor) + { + CUnit* unit = cmpVisualActor->GetUnit(); + if (unit) + unit->SetActorSelections(selections); + } } }; END_COMMAND(SetObjectSettings); Index: source/tools/atlas/GameInterface/Messages.h =================================================================== --- source/tools/atlas/GameInterface/Messages.h +++ source/tools/atlas/GameInterface/Messages.h @@ -342,12 +342,12 @@ struct sObjectSettings { Shareable player; - Shareable > selections; + Shareable> selections; // Some settings are immutable and therefore are ignored (and should be left // empty) when passed from the editor to the game: - Shareable > > variantGroups; + Shareable>> variantGroups; }; SHAREABLE_STRUCT(sObjectSettings); #endif