Index: binaries/data/mods/public/gui/common/gamedescription.js =================================================================== --- binaries/data/mods/public/gui/common/gamedescription.js +++ binaries/data/mods/public/gui/common/gamedescription.js @@ -412,6 +412,11 @@ }); titles.push({ + "label": translate("Capturable buildings"), + "value": g_GameAttributes.settings.Capturable + }); + + titles.push({ "label": translate("Revealed Map"), "value": g_GameAttributes.settings.RevealMap }); Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js =================================================================== --- binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -443,6 +443,7 @@ "ceasefire", "lockTeams", "lastManStanding", + "capturable", "enableRating" ] } @@ -948,6 +949,18 @@ !g_GameAttributes.settings.LockTeams, "initOrder": 1000 }, + "capturable": { + "title": () => translate("Capturable"), + "tooltip": () => translate("Toogle whether buildings can be captured."), + "default": () => true, + "defined": () => g_GameAttributes.settings.Capturable !== undefined, + "get": () => g_GameAttributes.settings.Capturable, + "set": checked => { + g_GameAttributes.settings.Capturable = checked; + }, + "enabled":() => true, + "initOrder": 1000 + }, "enableCheats": { "title": () => translate("Cheats"), "tooltip": () => translate("Toggle the usability of cheats."), Index: binaries/data/mods/public/simulation/ai/petra/defenseManager.js =================================================================== --- binaries/data/mods/public/simulation/ai/petra/defenseManager.js +++ binaries/data/mods/public/simulation/ai/petra/defenseManager.js @@ -220,6 +220,8 @@ let capture = ent.capturePoints(); if (capture === undefined) continue; + if (!capture.length) + continue; let lost = 0; for (let j = 0; j < capture.length; ++j) if (gameState.isPlayerEnemy(j)) 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 @@ -25,11 +25,19 @@ */ Capturable.prototype.GetCapturePoints = function() { + let cmpCaptureManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CaptureManager); + if (cmpCaptureManager && !cmpCaptureManager.IsCapturingAllowed(this.entity)) + return 0; + return this.cp; }; Capturable.prototype.GetMaxCapturePoints = function() { + let cmpCaptureManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CaptureManager); + if (cmpCaptureManager && !cmpCaptureManager.IsCapturingAllowed(this.entity)) + return 0; + return this.maxCp; }; @@ -55,6 +63,10 @@ */ Capturable.prototype.Reduce = function(amount, playerID) { + let cmpCaptureManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CaptureManager); + if (cmpCaptureManager && !cmpCaptureManager.IsCapturingAllowed(this.entity)) + return 0; + if (amount <= 0) return 0; @@ -115,6 +127,10 @@ */ Capturable.prototype.CanCapture = function(playerID) { + let cmpCaptureManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CaptureManager); + if (cmpCaptureManager && !cmpCaptureManager.IsCapturingAllowed(this.entity)) + return false; + var cmpPlayerSource = QueryPlayerIDInterface(playerID); if (!cmpPlayerSource) Index: binaries/data/mods/public/simulation/components/CaptureManager.js =================================================================== --- /dev/null +++ binaries/data/mods/public/simulation/components/CaptureManager.js @@ -0,0 +1,46 @@ +function CaptureManager() {} + +CaptureManager.prototype.Init = function() +{ + this.allowedCapturing = true; + this.wonderVictory = false; + this.relicVictory = false; +} + +CaptureManager.prototype.IsCapturingAllowed = function(entity) +{ + if (!this.relicVictory && !this.wonderVictory) + return this.allowedCapturing; + + if (!entity) + return this.allowedCapturing; + + if (this.relicVictory) { + let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); + if (cmpIdentity && cmpIdentity.HasClass("Relic")) + return true; + } + if (this.wonderVictory) { + let cmpWonder = Engine.QueryInterface(entity, IID_Wonder); + if (cmpWonder) + return true; + } + return this.allowedCapturing; +} + +CaptureManager.prototype.SetCapturableGame = function(allowedCapturing) +{ + this.allowedCapturing = allowedCapturing; +} + +CaptureManager.prototype.SetWonderVictory = function(wonderVictory) +{ + this.wonderVictory = wonderVictory; +} + +CaptureManager.prototype.SetRelicVictory = function(relicVictory) +{ + this.relicVictory = relicVictory; +} + +Engine.RegisterSystemComponentType(IID_CaptureManager, "CaptureManager", CaptureManager); Index: binaries/data/mods/public/simulation/components/StatusBars.js =================================================================== --- binaries/data/mods/public/simulation/components/StatusBars.js +++ binaries/data/mods/public/simulation/components/StatusBars.js @@ -202,6 +202,10 @@ if (!cmpCapturable) return 0; + let cmpCaptureManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CaptureManager); + if (cmpCaptureManager && !cmpCaptureManager.IsCapturingAllowed(this.entity)) + return 0; + let cmpOwnership = QueryMiragedInterface(this.entity, IID_Ownership); if (!cmpOwnership) return 0; Index: binaries/data/mods/public/simulation/components/TerritoryDecay.js =================================================================== --- binaries/data/mods/public/simulation/components/TerritoryDecay.js +++ binaries/data/mods/public/simulation/components/TerritoryDecay.js @@ -93,6 +93,21 @@ return; this.decaying = decaying; Engine.PostMessage(this.entity, MT_TerritoryDecayChanged, { "entity": this.entity, "to": decaying, "rate": this.GetDecayRate() }); + + let cmpCaptureManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CaptureManager); + if (!cmpCaptureManager || cmpCaptureManager.IsCapturingAllowed(this.entity)) + return; + + if (decaying) { + // Start decaying + let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + this.timer = cmpTimer.SetInterval(this.entity, IID_TerritoryDecay, "Decay", 1000, 1000, {"rate": this.GetDecayRate()}); + } else { + // Stop decaying + let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + cmpTimer.CancelTimer(this.timer); + this.timer = undefined; + } }; TerritoryDecay.prototype.UpdateOwner = function() @@ -152,5 +167,14 @@ { return this.territoryOwnership; }; +TerritoryDecay.prototype.Decay = function(msg) +{ + let cmpHealth = Engine.QueryInterface(this.entity, IID_Health); + if (!cmpHealth) + return; // error + + let decayRate = msg.rate; + cmpHealth.Reduce(Math.round(decayRate)); +}; Engine.RegisterComponentType(IID_TerritoryDecay, "TerritoryDecay", TerritoryDecay); Index: binaries/data/mods/public/simulation/components/interfaces/CaptureManager.js =================================================================== --- /dev/null +++ binaries/data/mods/public/simulation/components/interfaces/CaptureManager.js @@ -0,0 +1 @@ +Engine.RegisterInterface("CaptureManager"); 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 @@ -405,7 +405,7 @@ continue; let cmpCapturable = QueryMiragedInterface(ent, IID_Capturable); - if (cmpCapturable && + if (cmpCapturable && cmpCapturable.GetCapturePoints() && cmpCapturable.GetCapturePoints()[player] < cmpCapturable.GetMaxCapturePoints() / 2) continue; Index: binaries/data/mods/public/simulation/helpers/Setup.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Setup.js +++ binaries/data/mods/public/simulation/helpers/Setup.js @@ -64,6 +64,11 @@ if (settings.LockTeams && settings.LastManStanding) warn("Last man standing is only available in games with unlocked teams!"); + let cmpCaptureManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CaptureManager); + cmpCaptureManager.SetCapturableGame(settings.Capturable); + cmpCaptureManager.SetWonderVictory(gameSettings.victoryConditions.indexOf("wonder") != -1); + cmpCaptureManager.SetRelicVictory(gameSettings.victoryConditions.indexOf("capture_the_relic") != -1); + if (settings.Garrison) for (let holder in settings.Garrison) {