Index: binaries/data/mods/public/maps/scenario.rnc
===================================================================
--- binaries/data/mods/public/maps/scenario.rnc
+++ binaries/data/mods/public/maps/scenario.rnc
@@ -108,6 +108,12 @@
attribute uid { xsd:positiveInteger } &
} &
} &
+ element Turrets {
+ element Turret {
+ attribute turret { text } &
+ 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
@@ -268,6 +268,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/simulation/components/TurretHolder.js
===================================================================
--- binaries/data/mods/public/simulation/components/TurretHolder.js
+++ binaries/data/mods/public/simulation/components/TurretHolder.js
@@ -189,6 +189,36 @@
}
/**
+ * @return {map[String, number]} - The currently occupied turret points with their entities.
+ */
+ GetTurrets()
+ {
+ let turrets = new Map();
+ for (let turretPoint in this.turretPoints)
+ if (turretPoint.entity)
+ turrets.set(turretPoint, turretPoint.entity);
+
+ return turrets;
+ }
+
+ /**
+ * Sets an init turret, present from game start. (E.g. set in Atlas.)
+ * @param {String} turret - The turret point to be used.
+ * @param {number} entity - The entity-ID to be placed.
+ */
+ SetInitEntity(turret, entity)
+ {
+ if (!this.initTurrets)
+ this.initTurrets = new Map();
+
+ if (this.initTurrets.has(turret))
+ error("The turret position " + turret + " of entity " +
+ this.entity + " is already set! Overwriting.");
+
+ this.initTurrets.set(turret, entity);
+ }
+
+ /**
* We process EntityRenamed here because we need to be sure that we receive
* it after it is processed by GarrisonHolder.js.
* ToDo: Make this not needed by fully separating TurretHolder from GarrisonHolder.
@@ -221,6 +251,22 @@
for (let entity of msg.added)
this.OccupyTurret(entity);
}
+
+ /**
+ * Initialise the turreted units.
+ */
+ OnGlobalInitGame(msg)
+ {
+ if (!this.initTurrets)
+ return;
+
+ for (let [turretPoint, entity] of this.initTurrets)
+ if (!this.OccupyTurret(entity, this.turretPoints[turretPoint]))
+ error("Entity " + entity + " could not occupy the turret point " +
+ turretPoint + " of turret holder " + this.entity + ".");
+
+ delete this.initGarrison;
+ }
}
TurretHolder.prototype.Schema =
Index: binaries/data/mods/public/simulation/components/interfaces/TurretHolder.js
===================================================================
--- binaries/data/mods/public/simulation/components/interfaces/TurretHolder.js
+++ binaries/data/mods/public/simulation/components/interfaces/TurretHolder.js
@@ -1,5 +1,3 @@
-Engine.RegisterInterface("TurretHolder");
-
/**
* Message of the form { "added": number[], "removed": number[] }
* sent from the TurretHolder component to the current entity whenever the turrets change.
Index: source/graphics/MapReader.cpp
===================================================================
--- source/graphics/MapReader.cpp
+++ source/graphics/MapReader.cpp
@@ -48,6 +48,7 @@
#include "simulation2/components/ICmpPlayerManager.h"
#include "simulation2/components/ICmpPosition.h"
#include "simulation2/components/ICmpTerrain.h"
+#include "simulation2/components/ICmpTurretHolder.h"
#include "simulation2/components/ICmpVisual.h"
#include "simulation2/components/ICmpWaterManager.h"
@@ -418,12 +419,14 @@
int el_template, el_player;
int el_position, el_orientation, el_obstruction;
int el_garrison;
+ int el_turrets;
int el_actor;
int at_x, at_y, at_z;
int at_group, at_group2;
int at_angle;
int at_uid;
int at_seed;
+ int at_turret;
XMBElementList nodes; // children of root
@@ -468,6 +471,7 @@
EL(player);
EL(position);
EL(garrison);
+ EL(turrets);
EL(orientation);
EL(obstruction);
EL(actor);
@@ -476,6 +480,7 @@
AT(angle);
AT(uid);
AT(seed);
+ AT(turret);
#undef AT
#undef EL
@@ -950,6 +955,7 @@
CStrW TemplateName;
int PlayerID = 0;
std::vector Garrison;
+ std::vector > Turrets;
CFixedVector3D Position;
CFixedVector3D Orientation;
long Seed = -1;
@@ -1009,6 +1015,20 @@
Garrison.push_back(attrs.GetNamedItem(at_uid).ToInt());
}
}
+ //
+ else if (element_name == el_turrets)
+ {
+ XMBElementList turrets = setting.GetChildNodes();
+ Turrets.reserve(turrets.size());
+ for (const XMBElement& turretPoint : turrets)
+ {
+ XMBAttributeList attrs = turretPoint.GetAttributes();
+ Turrets.push_back(std::make_pair(
+ attrs.GetNamedItem(at_turret),
+ attrs.GetNamedItem(at_uid).ToInt()
+ ));
+ }
+ }
//
else if (element_name == el_actor)
{
Index: source/graphics/MapWriter.cpp
===================================================================
--- source/graphics/MapWriter.cpp
+++ source/graphics/MapWriter.cpp
@@ -44,6 +44,7 @@
#include "simulation2/components/ICmpOwnership.h"
#include "simulation2/components/ICmpPosition.h"
#include "simulation2/components/ICmpTemplateManager.h"
+#include "simulation2/components/ICmpTurretHolder.h"
#include "simulation2/components/ICmpVisual.h"
#include "simulation2/components/ICmpWaterManager.h"
@@ -353,7 +354,22 @@
{
XMLWriter_Element garrisonedEntityTag(xmlMapFile, "GarrisonedEntity");
garrisonedEntityTag.Attribute("uid", static_cast(garr_ent_id));
- // ToDo: We can store turret position as well.
+ }
+ }
+ }
+
+ CmpPtr cmpTurretHolder(sim, ent);
+ if (cmpTurretHolder)
+ {
+ std::vector > turrets = cmpTurretHolder->GetTurrets();
+ if (!turrets.empty())
+ {
+ XMLWriter_Element turretTag(xmlMapFile, "Turrets");
+ for (const std::pair turret : turrets)
+ {
+ XMLWriter_Element turretedEntityTag(xmlMapFile, "Turret");
+ turretedEntityTag.Attribute("turret", turret.first);
+ turretedEntityTag.Attribute("uid", static_cast(turret.second));
}
}
}
Index: source/simulation2/TypeList.h
===================================================================
--- source/simulation2/TypeList.h
+++ source/simulation2/TypeList.h
@@ -189,6 +189,9 @@
INTERFACE(TerritoryManager)
COMPONENT(TerritoryManager)
+INTERFACE(TurretHolder)
+COMPONENT(TurretHolderScripted)
+
INTERFACE(UnitMotion)
COMPONENT(UnitMotion) // must be after Obstruction
COMPONENT(UnitMotionScripted)
Index: source/simulation2/components/ICmpTurretHolder.h
===================================================================
--- /dev/null
+++ source/simulation2/components/ICmpTurretHolder.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_ICMPTURRETHOLDER
+#define INCLUDED_ICMPTURRETHOLDER
+
+#include "simulation2/system/Interface.h"
+
+#include
+
+class ICmpTurretHolder : public IComponent
+{
+public:
+ virtual std::vector > GetTurrets() const = 0;
+
+ virtual void SetInitEntities(const std::vector > entities) = 0;
+
+ DECLARE_INTERFACE_TYPE(TurretHolder)
+};
+
+#endif // INCLUDED_ICMPTURRETHOLDER
Index: source/simulation2/components/ICmpTurretHolder.cpp
===================================================================
--- /dev/null
+++ source/simulation2/components/ICmpTurretHolder.cpp
@@ -0,0 +1,46 @@
+/* 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 "ICmpTurretHolder.h"
+
+#include "simulation2/scripting/ScriptComponent.h"
+#include "simulation2/system/InterfaceScripted.h"
+
+BEGIN_INTERFACE_WRAPPER(TurretHolder)
+END_INTERFACE_WRAPPER(TurretHolder)
+
+class CCmpTurretHolderScripted : public ICmpTurretHolder
+{
+public:
+ DEFAULT_SCRIPT_WRAPPER(TurretHolderScripted)
+
+ virtual std::vector > GetTurrets() const
+ {
+ // This does not exist.
+ return m_Script.Call > >("GetTurrets");
+ }
+
+ virtual void SetInitEntities(std::vector > entities)
+ {
+ for (const std::pair p : entities)
+ m_Script.CallVoid("SetInitEntity", p.first, p.second);
+ }
+};
+
+REGISTER_COMPONENT_SCRIPT_WRAPPER(TurretHolderScripted)