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 @@ -1884,8 +1884,8 @@ if (entState.resourceSupply && entState.resourceSupply.killBeforeGather) return translate("The entity has to be killed before it can be gathered from"); - if (entState.capturePoints && entState.capturePoints[entState.player] < entState.maxCapturePoints / 2) - return translate("You cannot destroy this entity as you own less than half the capture points"); + if (entState.capturePoints && entState.capturePoints[entState.player] < entState.maxCapturePoints) + return translate("You cannot destroy this entity as you don't own it completely"); if (!entState.identity.canDelete) return translate("This entity is undeletable"); Index: binaries/data/mods/public/simulation/components/Capturable.js =================================================================== --- binaries/data/mods/public/simulation/components/Capturable.js +++ binaries/data/mods/public/simulation/components/Capturable.js @@ -13,6 +13,7 @@ Capturable.prototype.Init = function() { + this.doesHealthAllowCaptureFactor = 0.5; this.maxCapturePoints = +this.template.CapturePoints; this.garrisonRegenRate = +this.template.GarrisonRegenRate; this.regenRate = +this.template.RegenRate; @@ -138,16 +139,38 @@ */ Capturable.prototype.CanCapture = function(playerID) { - let cmpPlayerSource = QueryPlayerIDInterface(playerID); + if (!this.entity) + return false; + const cmpPlayerSource = QueryPlayerIDInterface(playerID); if (!cmpPlayerSource) warn(playerID + " has no player component defined on its id."); - let capturePoints = this.GetCapturePoints(); - let sourceEnemyCapturePoints = 0; - for (let i in this.GetCapturePoints()) - if (cmpPlayerSource.IsEnemy(i)) - sourceEnemyCapturePoints += capturePoints[i]; - return sourceEnemyCapturePoints > 0; + + var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + if (!cmpPosition || !cmpPosition.IsInWorld()) + return false; + + var pos = cmpPosition.GetPosition2D(); + + const cmpTerritoryManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager); + + var tileOwner = cmpTerritoryManager.GetOwner(pos.x, pos.y); + var cmpPlayer = QueryOwnerInterface(this.entity); + + var cmpHealth = Engine.QueryInterface(this.entity, IID_Health); + if (!cmpHealth) + return false; + + if (cmpPlayer.GetPlayerID() != tileOwner || tileOwner == 0 || cmpHealth.GetHitpoints() / cmpHealth.GetMaxHitpoints() <= this.doesHealthAllowCaptureFactor) + { + const capturePoints = this.GetCapturePoints(); + let sourceEnemyCapturePoints = 0; + for (const i in this.GetCapturePoints()) + if (cmpPlayerSource.IsEnemy(i)) + sourceEnemyCapturePoints += capturePoints[i]; + return sourceEnemyCapturePoints > 0; + } + return false; }; // Private functions Index: binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Commands.js +++ binaries/data/mods/public/simulation/helpers/Commands.js @@ -413,7 +413,7 @@ let cmpCapturable = QueryMiragedInterface(ent, IID_Capturable); if (cmpCapturable && - cmpCapturable.GetCapturePoints()[player] < cmpCapturable.GetMaxCapturePoints() / 2) + cmpCapturable.GetCapturePoints()[player] < cmpCapturable.GetMaxCapturePoints()) continue; let cmpResourceSupply = QueryMiragedInterface(ent, IID_ResourceSupply);