Index: binaries/data/mods/public/maps/scenario.rnc =================================================================== --- binaries/data/mods/public/maps/scenario.rnc +++ binaries/data/mods/public/maps/scenario.rnc @@ -103,6 +103,11 @@ attribute group { xsd:positiveInteger }, attribute group2 { xsd:positiveInteger }? }? & + element Garrison { + element GarrisonedEntity { + attribute uid { xsd:positiveInteger } & + } & + } & element Actor { attribute seed { xsd:integer } }? Index: binaries/data/mods/public/maps/scenario.rng =================================================================== --- binaries/data/mods/public/maps/scenario.rng +++ binaries/data/mods/public/maps/scenario.rng @@ -257,6 +257,17 @@ + + + + + + + + + + + Index: binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml =================================================================== --- binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml +++ binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml @@ -43,10 +43,6 @@ {}, {} ], - "Garrison": { - "3434": [3435, 3436, 3437, 3438, 3439, 3440, 3441, 3442, 3443, 3444, 3429, 3430, 3431, 3432, 3433], - "3445": [3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458, 3459, 3460] - }, "VictoryConditions": [ "conquest" ] @@ -15599,6 +15595,23 @@ 1 + + + + + + + + + + + + + + + + + @@ -15676,6 +15689,23 @@ 2 + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/simulation/components/GarrisonHolder.js =================================================================== --- binaries/data/mods/public/simulation/components/GarrisonHolder.js +++ binaries/data/mods/public/simulation/components/GarrisonHolder.js @@ -691,6 +691,16 @@ }; /** + * Sets the intitGarrison to the specified entities. Used by the mapreader. + * + * @param {number[]} entities - The entity IDs to garrison on init. + */ +GarrisonHolder.prototype.SetInitGarrison = function(entities) +{ + this.initGarrison = clone(entities); +}; + +/** * Initialise the garrisoned units. */ GarrisonHolder.prototype.OnGlobalInitGame = function(msg) Index: binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js =================================================================== --- binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js +++ binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js @@ -1,5 +1,3 @@ -Engine.RegisterInterface("GarrisonHolder"); - /** * Message of the form { "added": number[], "removed": number[] } * sent from the GarrisonHolder component to the current entity whenever the garrisoned units change. Index: binaries/data/mods/public/simulation/helpers/Setup.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Setup.js +++ binaries/data/mods/public/simulation/helpers/Setup.js @@ -64,16 +64,6 @@ if (settings.LockTeams && settings.LastManStanding) warn("Last man standing is only available in games with unlocked teams!"); - if (settings.Garrison) - for (let holder in settings.Garrison) - { - let cmpGarrisonHolder = Engine.QueryInterface(+holder, IID_GarrisonHolder); - if (!cmpGarrisonHolder) - warn("Map error in Setup.js: entity " + holder + " can not garrison units"); - else - cmpGarrisonHolder.initGarrison = settings.Garrison[holder]; - } - let cmpCeasefireManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CeasefireManager); if (settings.Ceasefire) cmpCeasefireManager.StartCeasefire(settings.Ceasefire * 60 * 1000); Index: source/graphics/MapReader.cpp =================================================================== --- source/graphics/MapReader.cpp +++ source/graphics/MapReader.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -41,6 +41,7 @@ #include "renderer/WaterManager.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpCinemaManager.h" +#include "simulation2/components/ICmpGarrisonHolder.h" #include "simulation2/components/ICmpObstruction.h" #include "simulation2/components/ICmpOwnership.h" #include "simulation2/components/ICmpPlayer.h" @@ -416,6 +417,7 @@ int el_tracks; int el_template, el_player; int el_position, el_orientation, el_obstruction; + int el_garrison; int el_actor; int at_x, at_y, at_z; int at_group, at_group2; @@ -465,6 +467,7 @@ EL(template); EL(player); EL(position); + EL(garrison); EL(orientation); EL(obstruction); EL(actor); @@ -946,6 +949,7 @@ CStrW TemplateName; int PlayerID = 0; + std::vector Garrison; CFixedVector3D Position; CFixedVector3D Orientation; long Seed = -1; @@ -994,6 +998,17 @@ ControlGroup = attrs.GetNamedItem(at_group).ToInt(); ControlGroup2 = attrs.GetNamedItem(at_group2).ToInt(); } + // + else if (element_name == el_garrison) + { + XMBElementList garrison = setting.GetChildNodes(); + Garrison.reserve(garrison.size()); + for (const XMBElement& garr_ent : garrison) + { + XMBAttributeList attrs = garr_ent.GetAttributes(); + Garrison.push_back(attrs.GetNamedItem(at_uid).ToInt()); + } + } // else if (element_name == el_actor) { @@ -1029,6 +1044,16 @@ if (cmpOwnership) cmpOwnership->SetOwner(PlayerID); + if (!Garrison.empty()) + { + CmpPtr cmpGarrisonHolder(sim, ent); + if (cmpGarrisonHolder) + cmpGarrisonHolder->SetInitEntities(Garrison); + else + LOGERROR("CXMLMapReader::ReadEntities() entity '%d' of player '%d' has no GarrisonHolder component and thus cannot garrison units.", ent, PlayerID); + Garrison.clear(); + } + CmpPtr cmpObstruction(sim, ent); if (cmpObstruction) { Index: source/graphics/MapWriter.cpp =================================================================== --- source/graphics/MapWriter.cpp +++ source/graphics/MapWriter.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -39,6 +39,7 @@ #include "renderer/WaterManager.h" #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpCinemaManager.h" +#include "simulation2/components/ICmpGarrisonHolder.h" #include "simulation2/components/ICmpObstruction.h" #include "simulation2/components/ICmpOwnership.h" #include "simulation2/components/ICmpPosition.h" @@ -341,6 +342,19 @@ if (cmpOwnership) entityTag.Setting("Player", static_cast(cmpOwnership->GetOwner())); + CmpPtr cmpGarrisonHolder(sim, ent); + if (cmpGarrisonHolder) + { + XMLWriter_Element garrisonTag(xmlMapFile, "Garrison"); + std::vector garrison = cmpGarrisonHolder->GetEntities(); + for (const entity_id_t garr_ent_id : garrison) + { + XMLWriter_Element garrisonedEntityTag(xmlMapFile, "GarrisonedEntity"); + garrisonedEntityTag.Attribute("uid", static_cast(garr_ent_id)); + // ToDo: We can store turret position as well. + } + } + CmpPtr cmpPosition(sim, ent); if (cmpPosition) { Index: source/simulation2/TypeList.h =================================================================== --- source/simulation2/TypeList.h +++ source/simulation2/TypeList.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -98,6 +98,9 @@ INTERFACE(Footprint) COMPONENT(Footprint) +INTERFACE(GarrisonHolder) +COMPONENT(GarrisonHolderScripted) + INTERFACE(GuiInterface) COMPONENT(GuiInterfaceScripted) Index: source/simulation2/components/ICmpGarrisonHolder.h =================================================================== --- /dev/null +++ source/simulation2/components/ICmpGarrisonHolder.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2020 Wildfire Games. +* This file is part of 0 A.D. +* +* 0 A.D. is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* 0 A.D. is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with 0 A.D. If not, see . +*/ + +#ifndef INCLUDED_ICMPGARRISONHOLDER +#define INCLUDED_ICMPGARRISONHOLDER + +#include "simulation2/system/Interface.h" + +#include + +class ICmpGarrisonHolder : public IComponent +{ +public: + virtual std::vector GetEntities() const = 0; + + virtual void SetInitEntities(const std::vector entities) = 0; + + DECLARE_INTERFACE_TYPE(GarrisonHolder) +}; + +#endif // INCLUDED_ICMPGARRISONHOLDER Index: source/simulation2/components/ICmpGarrisonHolder.cpp =================================================================== --- /dev/null +++ source/simulation2/components/ICmpGarrisonHolder.cpp @@ -0,0 +1,44 @@ +/* Copyright (C) 2020 Wildfire Games. +* This file is part of 0 A.D. +* +* 0 A.D. is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* 0 A.D. is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with 0 A.D. If not, see . +*/ + +#include "precompiled.h" + +#include "ICmpGarrisonHolder.h" + +#include "simulation2/scripting/ScriptComponent.h" +#include "simulation2/system/InterfaceScripted.h" + +BEGIN_INTERFACE_WRAPPER(GarrisonHolder) +END_INTERFACE_WRAPPER(GarrisonHolder) + +class CCmpGarrisonHolderScripted : public ICmpGarrisonHolder +{ +public: + DEFAULT_SCRIPT_WRAPPER(GarrisonHolderScripted) + + virtual std::vector GetEntities() const + { + return m_Script.Call >("GetEntities"); + } + + virtual void SetInitEntities(std::vector entities) + { + m_Script.CallVoid("SetInitGarrison", entities); + } +}; + +REGISTER_COMPONENT_SCRIPT_WRAPPER(GarrisonHolderScripted)