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 @@
skirmish/units/default_ship_trireme
1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -15676,6 +15689,23 @@
skirmish/units/default_ship_trireme
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)