diff --git a/binaries/data/mods/public/simulation/components/GarrisonHolder.js b/binaries/data/mods/public/simulation/components/GarrisonHolder.js index 77e0b78462..bad506bd5c 100644 --- a/binaries/data/mods/public/simulation/components/GarrisonHolder.js +++ b/binaries/data/mods/public/simulation/components/GarrisonHolder.js @@ -154,13 +154,18 @@ GarrisonHolder.prototype.IsAllowedToGarrison = function(entity) if (!this.IsGarrisoningAllowed()) return false; - if (!IsOwnedByMutualAllyOfEntity(entity, this.entity)) - return false; - let cmpGarrisonable = Engine.QueryInterface(entity, IID_Garrisonable); if (!cmpGarrisonable || this.OccupiedSlots() + cmpGarrisonable.TotalSize() > this.GetCapacity()) return false; + return this.IsAllowedToBeGarrisoned(entity); +}; + +GarrisonHolder.prototype.IsAllowedToBeGarrisoned = function(entity) +{ + if (!IsOwnedByMutualAllyOfEntity(entity, this.entity)) + return false; + let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); return cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), this.allowedClasses); }; @@ -427,37 +432,11 @@ GarrisonHolder.prototype.OnDestroy = function() * If a garrisoned entity is captured, or about to be killed (so its owner changes to '-1'), * remove it from the building so we only ever contain valid entities. */ -GarrisonHolder.prototype.OnGlobalOwnershipChanged = function(msg) +GarrisonHolder.prototype.OnOwnershipChanged = function(msg) { - // The ownership change may be on the garrisonholder - if (this.entity == msg.entity) - { - let entities = this.entities.filter(ent => msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, ent)); - - if (entities.length) - this.EjectOrKill(entities); - - return; - } - - // or on some of its garrisoned units - let entityIndex = this.entities.indexOf(msg.entity); - if (entityIndex != -1) - { - // If the entity is dead, remove it directly instead of ejecting the corpse - let cmpHealth = Engine.QueryInterface(msg.entity, IID_Health); - if (cmpHealth && cmpHealth.GetHitpoints() == 0) - { - this.entities.splice(entityIndex, 1); - Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { - "added": [], - "removed": [msg.entity] - }); - this.UpdateGarrisonFlag(); - } - else if (msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, msg.entity)) - this.EjectOrKill([msg.entity]); - } + let entities = this.entities.filter(ent => msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, ent)); + if (entities.length) + this.EjectOrKill(entities); }; /** @@ -583,7 +562,7 @@ GarrisonHolder.prototype.OnValueModification = function(msg) if (msg.valueNames.indexOf("GarrisonHolder/List/_string") !== -1) { this.allowedClasses = ApplyValueModificationsToEntity("GarrisonHolder/List/_string", this.template.List._string, this.entity); - this.EjectOrKill(this.entities.filter(entity => !this.IsAllowedToGarrison(entity))); + this.EjectOrKill(this.entities.filter(entity => !this.IsAllowedToBeGarrisoned(entity))); } if (msg.valueNames.indexOf("GarrisonHolder/BuffHeal") === -1) diff --git a/binaries/data/mods/public/simulation/components/Garrisonable.js b/binaries/data/mods/public/simulation/components/Garrisonable.js index 1b36547ec3..029c6cb1cb 100644 --- a/binaries/data/mods/public/simulation/components/Garrisonable.js +++ b/binaries/data/mods/public/simulation/components/Garrisonable.js @@ -197,4 +197,17 @@ Garrisonable.prototype.OnEntityRenamed = function(msg) delete this.holder; }; +/** + * @param {Object} msg - { "entity": this.entity, "from": {number}, "to": {number} } + */ +Garrisonable.prototype.OnOwnershipChanged = function(msg) +{ + if (!this.holder) + return; + + let cmpGarrisonHolder = Engine.QueryInterface(this.holder, IID_GarrisonHolder); + if (!cmpGarrisonHolder.IsAllowedToBeGarrisoned(this.entity)) + this.UnGarrison(msg.to == INVALID_PLAYER); +}; + Engine.RegisterComponentType(IID_Garrisonable, "Garrisonable", Garrisonable); diff --git a/binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js b/binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js index be7c65c80f..7d7a161de8 100644 --- a/binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js +++ b/binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js @@ -259,9 +259,9 @@ TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 1); // Eject enemy units. currentCavalryPlayer = enemyPlayer; -cmpGarrisonHolder.OnGlobalOwnershipChanged({ - "entity": cavalryId, - "to": enemyPlayer +cmpGarrisonHolder.OnOwnershipChanged({ + "entity": garrisonHolderId, + "to": player }); TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 0);