Index: binaries/data/mods/public/maps/scenario.rnc =================================================================== --- binaries/data/mods/public/maps/scenario.rnc +++ binaries/data/mods/public/maps/scenario.rnc @@ -106,6 +106,7 @@ element Garrison { element GarrisonedEntity { attribute uid { xsd:positiveInteger } & + attribute vgp { text } & } & } & element Actor { Index: binaries/data/mods/public/maps/scenario.rng =================================================================== --- binaries/data/mods/public/maps/scenario.rng +++ binaries/data/mods/public/maps/scenario.rng @@ -263,6 +263,9 @@ + + + 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,19 @@ }; /** + * 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. */ @@ -623,11 +637,10 @@ if (cmpGarrisonHolder) cmpGarrisonHolder.initGarrison = this.initGarrison; } - else + else if (this.initGarrison.has(msg.entity)) { - entityIndex = this.initGarrison.indexOf(msg.entity); - if (entityIndex != -1) - this.initGarrison[entityIndex] = msg.newentity; + this.initGarrison.set(msg.newentity, this.initGarrison.get(msg.entity)) + this.initGarrison.delete(msg.entity); } }; @@ -691,13 +704,16 @@ }; /** - * Sets the intitGarrison to the specified entities. Used by the mapreader. + * Adds an entity to the intitGarrison. Used by the mapreader. * - * @param {number[]} entities - The entity IDs to garrison on init. + * @param {number} entities - The entity ID to garrison on init. + * @param {string} vgp - The vgp to use. */ -GarrisonHolder.prototype.SetInitGarrison = function(entities) +GarrisonHolder.prototype.SetInitEntity = function(entity, vgp) { - this.initGarrison = clone(entities); + if (!this.initGarrison) + this.initGarrison = new Map(); + this.initGarrison.set(entity, vgp); }; /** @@ -708,10 +724,10 @@ if (!this.initGarrison) return; - for (let ent of this.initGarrison) + for (let [ent, vgp] of this.initGarrison) { let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); - if (cmpUnitAI && cmpUnitAI.CanGarrison(this.entity) && this.Garrison(ent)) + if (cmpUnitAI && cmpUnitAI.CanGarrison(this.entity) && this.Garrison(ent, this.visibleGarrisonPoints.find(point => point.name == vgp))) cmpUnitAI.Autogarrison(this.entity); } this.initGarrison = undefined; Index: source/graphics/MapReader.cpp =================================================================== --- source/graphics/MapReader.cpp +++ source/graphics/MapReader.cpp @@ -424,6 +424,7 @@ int at_angle; int at_uid; int at_seed; + int at_vgp; XMBElementList nodes; // children of root @@ -476,6 +477,7 @@ AT(angle); AT(uid); AT(seed); + AT(vgp); #undef AT #undef EL @@ -949,7 +951,7 @@ CStrW TemplateName; int PlayerID = 0; - std::vector Garrison; + std::vector > Garrison; CFixedVector3D Position; CFixedVector3D Orientation; long Seed = -1; @@ -1006,7 +1008,10 @@ for (const XMBElement& garr_ent : garrison) { XMBAttributeList attrs = garr_ent.GetAttributes(); - Garrison.push_back(attrs.GetNamedItem(at_uid).ToInt()); + Garrison.push_back(std::make_pair( + attrs.GetNamedItem(at_uid).ToInt(), + attrs.GetNamedItem(at_vgp) + )); } } // Index: source/graphics/MapWriter.cpp =================================================================== --- source/graphics/MapWriter.cpp +++ source/graphics/MapWriter.cpp @@ -351,7 +351,9 @@ { XMLWriter_Element garrisonedEntityTag(xmlMapFile, "GarrisonedEntity"); garrisonedEntityTag.Attribute("uid", static_cast(garr_ent_id)); - // ToDo: We can store turret position as well. + std::string visibleGarrisonPoint = cmpGarrisonHolder->GetVisibleGarrisonPoint(garr_ent_id); + if (!visibleGarrisonPoint.empty()) + garrisonedEntityTag.Attribute("vgp", visibleGarrisonPoint); } } Index: source/simulation2/components/ICmpGarrisonHolder.h =================================================================== --- source/simulation2/components/ICmpGarrisonHolder.h +++ source/simulation2/components/ICmpGarrisonHolder.h @@ -27,7 +27,9 @@ public: virtual std::vector GetEntities() const = 0; - virtual void SetInitEntities(const std::vector entities) = 0; + virtual std::string GetVisibleGarrisonPoint(entity_id_t entity) = 0; + + virtual void SetInitEntities(const std::vector > entities) = 0; DECLARE_INTERFACE_TYPE(GarrisonHolder) }; Index: source/simulation2/components/ICmpGarrisonHolder.cpp =================================================================== --- source/simulation2/components/ICmpGarrisonHolder.cpp +++ source/simulation2/components/ICmpGarrisonHolder.cpp @@ -35,9 +35,15 @@ return m_Script.Call >("GetEntities"); } - virtual void SetInitEntities(std::vector entities) + virtual std::string GetVisibleGarrisonPoint(entity_id_t entity) { - m_Script.CallVoid("SetInitGarrison", entities); + return m_Script.Call("GetVisibleGarrisonPoint", entity); + } + + virtual void SetInitEntities(std::vector > entities) + { + for (const std::pair p : entities) + m_Script.CallVoid("SetInitEntity", p.first, p.second); } };