Index: source/graphics/MapReader.cpp =================================================================== --- source/graphics/MapReader.cpp +++ source/graphics/MapReader.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -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,8 @@ int at_angle; int at_uid; int at_seed; + int el_variation; + int el_variations; XMBElementList nodes; // children of root @@ -472,6 +475,8 @@ AT(angle); AT(uid); AT(seed); + EL(variations); + EL(variation); #undef AT #undef EL @@ -948,6 +953,7 @@ CFixedVector3D Position; CFixedVector3D Orientation; long Seed = -1; + std::set actorSelections; // Obstruction control groups. entity_id_t ControlGroup = INVALID_ENTITY; @@ -1003,6 +1009,20 @@ Seed = seedStr.ToLong(); ENSURE(Seed >= 0); } + + XMBElementList childActors = setting.GetChildNodes(); + if (childActors.size() > 1) + LOGERROR("Failed to load variations from actor(more than one child) template '%s'", utf8_from_wstring(TemplateName)); + else + { + XMBElement variations = childActors[0]; + ENSURE(variations.GetNodeName() == el_variations); + XERO_ITER_EL(variations, variation) + { + ENSURE(variation.GetNodeName() == el_variation); + actorSelections.insert(variation.GetText()); + } + } } else debug_warn(L"Invalid map XML data"); @@ -1044,7 +1064,13 @@ { 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,24 @@ 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); + + CUnit* unit = cmpVisual->GetUnit(); + if (unit) + { + const std::set& selections = unit->GetActorSelections(); + + if (!selections.empty()) + { + XMLWriter_Element variationsTag(xmlMapFile, "Variations"); + for (const CStr& selection : selections) + variationsTag.Setting("variation", selection); + } } - // TODO: variation/selection strings } } } 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);