Index: binaries/data/mods/public/gui/session/session.js
===================================================================
--- binaries/data/mods/public/gui/session/session.js
+++ binaries/data/mods/public/gui/session/session.js
@@ -406,14 +406,13 @@
}
/**
- * Returns the entity itself except when garrisoned where it returns its garrisonHolder
+ * Returns the entity itself except when garrisoned where it returns its garrisonHolder.
*/
function getEntityOrHolder(ent)
{
let entState = GetEntityState(ent);
- if (entState && !entState.position && entState.unitAI && entState.unitAI.orders.length &&
- entState.unitAI.orders[0].type == "Garrison")
- return getEntityOrHolder(entState.unitAI.orders[0].data.target);
+ if (entState && !entState.position && entState.garrisonable && entState.garrisonable.garrisonHolder != INVALID_ENTITY)
+ return getEntityOrHolder(entState.garrisonable.garrisonHolder);
return ent;
}
Index: binaries/data/mods/public/gui/session/unit_actions.js
===================================================================
--- binaries/data/mods/public/gui/session/unit_actions.js
+++ binaries/data/mods/public/gui/session/unit_actions.js
@@ -705,7 +705,7 @@
},
"getActionInfo": function(entState, targetState)
{
- if (!entState.canGarrison || !targetState.garrisonHolder ||
+ if (!entState.garrisonable || !targetState.garrisonHolder ||
!playerCheck(entState, targetState, ["Player", "MutualAlly"]))
return false;
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
@@ -175,7 +175,7 @@
return false;
let entityClasses = cmpIdentity.GetClassesList();
- return MatchesClassList(entityClasses, this.template.List._string) && !!Engine.QueryInterface(ent, IID_Garrisonable);
+ return MatchesClassList(entityClasses, this.template.List._string);
};
/**
@@ -232,18 +232,23 @@
};
/**
- * @return {boolean} Whether the entity was garrisonned.
+ * @param {number} entity - The entity ID to garrison.
+ * @return {boolean} - Whether the entity was garrisoned.
*/
GarrisonHolder.prototype.PerformGarrison = function(entity)
{
if (!this.HasEnoughHealth())
return false;
- // Check if the unit is allowed to be garrisoned inside the building
+ let cmpGarrisonable = Engine.QueryInterface(entity, IID_Garrisonable);
+ if (!cmpGarrisonable)
+ return false;
+
+ // Check if the unit is allowed to be garrisoned inside the building.
if (!this.IsAllowedToGarrison(entity))
return false;
- // Check the capacity
+ // Check the capacity.
let extraCount = 0;
let cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
if (cmpGarrisonHolder)
@@ -257,7 +262,8 @@
this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
}
- // Actual garrisoning happens here
+ // Actual garrisoning happens here.
+ cmpGarrisonable.Garrison(this.entity);
this.entities.push(entity);
this.UpdateGarrisonFlag();
let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
@@ -345,6 +351,10 @@
if (cmpPosition)
cmpEntPosition.SetYRotation(cmpPosition.GetPosition().horizAngleTo(pos));
+ let cmpGarrisonable = Engine.QueryInterface(entity, IID_Garrisonable);
+ if (cmpGarrisonable)
+ cmpGarrisonable.UnGarrison();
+
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": [entity] });
return true;
Index: binaries/data/mods/public/simulation/components/Garrisonable.js
===================================================================
--- binaries/data/mods/public/simulation/components/Garrisonable.js
+++ binaries/data/mods/public/simulation/components/Garrisonable.js
@@ -1,11 +1,39 @@
-function Garrisonable() {}
+class Garrisonable
+{
+ Init()
+ {
+ this.garrisonHolder = INVALID_ENTITY;
+ }
-Garrisonable.prototype.Schema = "";
+ /**
+ * Which garrisonholder this entity is garrisoned in.
+ *
+ * @return {number} - The entity ID of the entity this entity is garrisoned in.
+ */
+ GetGarrisonHolder()
+ {
+ return this.garrisonHolder;
+ }
-Garrisonable.prototype.Init = function()
-{
-};
+ /**
+ * Sets the garrisonholder, where this entity is garrisoned in.
+ *
+ * @param {number} entity - The entity ID of the entity this entity is garrisoned in.
+ */
+ Garrison(entity)
+ {
+ this.garrisonHolder = entity;
+ }
-Garrisonable.prototype.Serialize = null;
+ /**
+ * Resets the garrisonholder.
+ */
+ UnGarrison()
+ {
+ this.garrisonHolder = INVALID_ENTITY;
+ }
+}
+
+Garrisonable.prototype.Schema = "";
Engine.RegisterComponentType(IID_Garrisonable, "Garrisonable", Garrisonable);
Index: binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/GuiInterface.js
+++ binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -366,7 +366,11 @@
"garrisonedEntitiesCount": cmpGarrisonHolder.GetGarrisonedEntitiesCount()
};
- ret.canGarrison = !!Engine.QueryInterface(ent, IID_Garrisonable);
+ let cmpGarrisonable = Engine.QueryInterface(ent, IID_Garrisonable);
+ if (cmpGarrisonable)
+ ret.garrisonable = {
+ "garrisonHolder": cmpGarrisonable.GetGarrisonHolder()
+ };
let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
if (cmpUnitAI)
Index: binaries/data/mods/public/simulation/components/UnitAI.js
===================================================================
--- binaries/data/mods/public/simulation/components/UnitAI.js
+++ binaries/data/mods/public/simulation/components/UnitAI.js
@@ -3399,13 +3399,11 @@
UnitAI.prototype.GetGarrisonHolder = function()
{
- if (this.IsGarrisoned())
- {
- for (let order of this.orderQueue)
- if (order.type == "Garrison")
- return order.data.target;
- }
- return INVALID_ENTITY;
+ if (!this.IsGarrisoned())
+ return INVALID_ENTITY;
+
+ let cmpGarrisonable = Engine.QueryInterface(this.entity, IID_Garrisonable)
+ return cmpGarrisonable ? cmpGarrisonable.GetGarrisonHolder() : INVALID_ENTITY;
};
UnitAI.prototype.ShouldRespondToEndOfAlert = function()
Index: binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js
+++ binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js
@@ -72,7 +72,10 @@
"GetOwner": () => friendlyPlayer
});
- AddMock(i, IID_Garrisonable, {});
+ AddMock(i, IID_Garrisonable, {
+ "Garrison": entity => {},
+ "UnGarrison": () => {}
+ });
AddMock(i, IID_Position, {
"GetHeightOffset": () => 0,
Index: binaries/data/mods/public/simulation/components/tests/test_Garrisonable.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/simulation/components/tests/test_Garrisonable.js
@@ -0,0 +1,14 @@
+Engine.LoadComponentScript("interfaces/Garrisonable.js");
+Engine.LoadComponentScript("Garrisonable.js");
+
+const garrisonHolderID = 1;
+const garrisonableID = 2;
+
+let cmpGarrisonable = ConstructComponent(garrisonableID, "Garrisonable", {
+});
+
+cmpGarrisonable.Garrison(garrisonHolderID);
+TS_ASSERT_UNEVAL_EQUALS(cmpGarrisonable.GetGarrisonHolder(), garrisonHolderID);
+
+cmpGarrisonable.UnGarrison();
+TS_ASSERT_UNEVAL_EQUALS(cmpGarrisonable.GetGarrisonHolder(), INVALID_ENTITY);
Index: binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
+++ binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
@@ -586,7 +586,6 @@
"needsRepair": false,
"needsHeal": true,
"builder": true,
- "canGarrison": false,
"visibility": "visible",
"isBarterMarket":true,
"resourceTrickle": {