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 @@ -73,6 +73,7 @@ let points = this.template.VisibleGarrisonPoints; for (let point in points) this.visibleGarrisonPoints.push({ + "name": point, "offset": { "x": +points[point].X, "y": +points[point].Y, @@ -106,6 +107,20 @@ }; /** + * Get the visible garrison point an entity occupies. + * + * @param {number} entity - The entity ID of the entity to check. + * + * @return {String} - The name of the visibly garrison point this entity occupies. + */ +GarrisonHolder.prototype.GetVisibleGarrisonPoint = function(entity) +{ + if (!this.visibleGarrisonPoints.length) + return ""; + return this.visibleGarrisonPoints.find(vgp => vgp.entity == entity).name || ""; +}; + +/** * @return {Array} unit classes which can be garrisoned inside this * particular entity. Obtained from the entity's template. */ @@ -691,11 +706,23 @@ }; /** + * Sets the intitGarrison to the specified entities. Used by the mapreader. + * + * @param {number} entity - An entity ID to garrison on init. + */ +GarrisonHolder.prototype.AddInitGarrisonEntity = function(entity) +{ + if (!this.initGarrison) + this.initGarrison = []; + this.initGarrison.push(entity); +}; + +/** * Initialise the garrisoned units. */ GarrisonHolder.prototype.OnGlobalInitGame = function(msg) { - if (!this.initGarrison) + if (!this.initGarrison || !this.initGarrison.length) return; for (let ent of this.initGarrison) 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: 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,11 +417,13 @@ 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; int at_angle; int at_uid; + int at_gid; int at_seed; XMBElementList nodes; // children of root @@ -465,6 +468,7 @@ EL(template); EL(player); EL(position); + EL(garrison); EL(orientation); EL(obstruction); EL(actor); @@ -472,6 +476,7 @@ AT(group); AT(group2); AT(angle); AT(uid); + AT(gid); AT(seed); #undef AT #undef EL @@ -946,6 +951,7 @@ CStrW TemplateName; int PlayerID = 0; + std::set Garrison; CFixedVector3D Position; CFixedVector3D Orientation; long Seed = -1; @@ -994,6 +1000,19 @@ ControlGroup = attrs.GetNamedItem(at_group).ToInt(); ControlGroup2 = attrs.GetNamedItem(at_group2).ToInt(); } + // + else if (element_name == el_garrison) + { + XMBElementList garrison = setting.GetChildNodes(); + size_t garrison_entity = 0; + while (garrison_entity < garrison.size()) + { + XMBElement garr_ent = garrison[garrison_entity++]; + XMBAttributeList attrs = garr_ent.GetAttributes(); + Garrison.insert(attrs.GetNamedItem(at_gid).ToInt()); + // ToDo: We can store turret position as well. + } + } // else if (element_name == el_actor) { @@ -1029,6 +1048,13 @@ if (cmpOwnership) cmpOwnership->SetOwner(PlayerID); + CmpPtr cmpGarrisonHolder(sim, ent); + if (cmpGarrisonHolder) + { + cmpGarrisonHolder->SetInitEntities(Garrison); + 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) + { + std::set garrison = cmpGarrisonHolder->GetEntities(); + XMLWriter_Element garrisonTag(xmlMapFile, "Garrison"); + for (std::set::iterator garr_ent_id = garrison.begin(); garr_ent_id != garrison.end(); ++garr_ent_id) + { + XMLWriter_Element garrisonedEntityTag(xmlMapFile, "GarrisonedEntity"); + garrisonedEntityTag.Attribute("gid", static_cast(*garr_ent_id)); + garrisonedEntityTag.Setting("Location", cmpGarrisonHolder->GetVisibleGarrisonPoint(*garr_ent_id)); + } + } + 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" + +class ICmpGarrisonHolder : public IComponent +{ +public: + virtual std::set GetEntities() const = 0; + + virtual void SetInitEntities(std::set entities) = 0; + + virtual std::string GetVisibleGarrisonPoint(entity_id_t entity) = 0; + + DECLARE_INTERFACE_TYPE(GarrisonHolder) +}; + +#endif // INCLUDED_ICMPGARRISONHOLDER Index: source/simulation2/components/ICmpGarrisonHolder.cpp =================================================================== --- /dev/null +++ source/simulation2/components/ICmpGarrisonHolder.cpp @@ -0,0 +1,56 @@ +/* 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::set GetEntities() const + { + std::vector entities = m_Script.Call>("GetEntities"); + std::set result; + for (std::vector::iterator it = entities.begin(); it != entities.end(); ++it) + result.insert(*it); + return result; + } + + virtual void SetInitEntities(std::set entities) + { + for (std::set::iterator it = entities.begin(); it != entities.end(); ++it) + { + m_Script.CallVoid("AddInitGarrisonEntity", *it); + } + } + + virtual std::string GetVisibleGarrisonPoint(entity_id_t entity) + { + return m_Script.Call("GetVisibleGarrisonPoint", entity); + } +}; + +REGISTER_COMPONENT_SCRIPT_WRAPPER(GarrisonHolderScripted)