From 8bfb449375ddc3e8ef41fce20ce19578ef9f63d0 Mon Sep 17 00:00:00 2001 From: Angen Date: Sun, 15 Mar 2020 13:54:50 +0000 Subject: [PATCH] Support garrisoned enitites defined in map files. This is adding support to handle garrisoned entities defined in map files by game engine and atlas allowing future extension for atlas ui and solving recreation of entites on init in D1958. Also solving deepfreeze described in D2562. Differential Revision; https://code.wildfiregames.com/D2597 Ticket: #3008 Patch by: Freagarach Comments by: elexis This was SVN commit r23529. --- binaries/data/mods/public/maps/scenario.rnc | 5 +++ binaries/data/mods/public/maps/scenario.rng | 11 +++++ .../public/maps/skirmishes/Sicilia_Nomad.xml | 4 +- .../simulation/components/GarrisonHolder.js | 10 +++++ .../components/interfaces/GarrisonHolder.js | 2 - .../mods/public/simulation/helpers/Setup.js | 10 ----- source/graphics/MapReader.cpp | 27 +++++++++++- source/graphics/MapWriter.cpp | 16 ++++++- source/simulation2/TypeList.h | 5 ++- .../components/ICmpGarrisonHolder.cpp | 44 +++++++++++++++++++ .../components/ICmpGarrisonHolder.h | 35 +++++++++++++++ 11 files changed, 152 insertions(+), 17 deletions(-) create mode 100644 source/simulation2/components/ICmpGarrisonHolder.cpp create mode 100644 source/simulation2/components/ICmpGarrisonHolder.h diff --git a/binaries/data/mods/public/maps/scenario.rnc b/binaries/data/mods/public/maps/scenario.rnc index f4abc6c8f5..dd5f6b9ef4 100644 --- a/binaries/data/mods/public/maps/scenario.rnc +++ b/binaries/data/mods/public/maps/scenario.rnc @@ -103,6 +103,11 @@ Scenario = element Scenario { attribute group { xsd:positiveInteger }, attribute group2 { xsd:positiveInteger }? }? & + element Garrison { + element GarrisonedEntity { + attribute uid { xsd:positiveInteger } & + } & + } & element Actor { attribute seed { xsd:integer } }? diff --git a/binaries/data/mods/public/maps/scenario.rng b/binaries/data/mods/public/maps/scenario.rng index 947f019b14..4d80f3a9be 100644 --- a/binaries/data/mods/public/maps/scenario.rng +++ b/binaries/data/mods/public/maps/scenario.rng @@ -256,6 +256,17 @@ + + + + + + + + + + + diff --git a/binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml b/binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml index 0c3e92a81e..5cc8f25cbf 100644 --- a/binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml +++ b/binaries/data/mods/public/maps/skirmishes/Sicilia_Nomad.xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc402fc30beea8e2aaf1c3ab1c3d94edbb4e6690623d4d2566fbc320f7a9cc47 -size 519678 +oid sha256:b7c9e45798b8cff82e56a25c3860e7764cb2ae702cd81e8913f33cd50382f867 +size 520558 diff --git a/binaries/data/mods/public/simulation/components/GarrisonHolder.js b/binaries/data/mods/public/simulation/components/GarrisonHolder.js index ef587b4586..7586b90569 100644 --- a/binaries/data/mods/public/simulation/components/GarrisonHolder.js +++ b/binaries/data/mods/public/simulation/components/GarrisonHolder.js @@ -690,6 +690,16 @@ GarrisonHolder.prototype.IsEjectable = function(entity) return MatchesClassList(entityClasses, ejectableClasses); }; +/** + * 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. */ diff --git a/binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js b/binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js index b32488a15e..5ef3827feb 100644 --- a/binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js +++ b/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. diff --git a/binaries/data/mods/public/simulation/helpers/Setup.js b/binaries/data/mods/public/simulation/helpers/Setup.js index 530b2900a6..ce5c49cf15 100644 --- a/binaries/data/mods/public/simulation/helpers/Setup.js +++ b/binaries/data/mods/public/simulation/helpers/Setup.js @@ -64,16 +64,6 @@ function LoadMapSettings(settings) 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); diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 98bd89178b..df3abf3ab7 100644 --- a/source/graphics/MapReader.cpp +++ b/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 @@ private: 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 @@ void CXMLReader::Init(const VfsPath& xml_filename) EL(template); EL(player); EL(position); + EL(garrison); EL(orientation); EL(obstruction); EL(actor); @@ -946,6 +949,7 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time) CStrW TemplateName; int PlayerID = 0; + std::vector Garrison; CFixedVector3D Position; CFixedVector3D Orientation; long Seed = -1; @@ -994,6 +998,17 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time) 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 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time) 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) { diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index fe2593b4b1..3eb35e04a8 100644 --- a/source/graphics/MapWriter.cpp +++ b/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 @@ void CMapWriter::WriteXML(const VfsPath& filename, 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) { diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h index eff05ed289..6f157b8314 100644 --- a/source/simulation2/TypeList.h +++ b/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 @@ COMPONENT(FoggingScripted) INTERFACE(Footprint) COMPONENT(Footprint) +INTERFACE(GarrisonHolder) +COMPONENT(GarrisonHolderScripted) + INTERFACE(GuiInterface) COMPONENT(GuiInterfaceScripted) diff --git a/source/simulation2/components/ICmpGarrisonHolder.cpp b/source/simulation2/components/ICmpGarrisonHolder.cpp new file mode 100644 index 0000000000..de3cbc1117 --- /dev/null +++ b/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) diff --git a/source/simulation2/components/ICmpGarrisonHolder.h b/source/simulation2/components/ICmpGarrisonHolder.h new file mode 100644 index 0000000000..b89908f717 --- /dev/null +++ b/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