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 @@ -519,7 +519,8 @@ "ExploreMap": "exploreMap", "DisableTreasures": "disableTreasures", "LockTeams": "lockTeams", - "LastManStanding" : "lastManStanding", + "LastManStanding": "lastManStanding", + "RegicideGarrison": "regicideGarrison", "CheatsEnabled": "enableCheats" }; @@ -1241,6 +1242,7 @@ { delete g_GameAttributes.settings.WonderDuration; delete g_GameAttributes.settings.LastManStanding; + delete g_GameAttributes.settings.RegicideGarrison; } if (mapSettings.PlayerData) @@ -1425,11 +1427,15 @@ setGUIBoolean("revealMap", "revealMapText", !!mapSettings.RevealMap); setGUIBoolean("lockTeams", "lockTeamsText", !!mapSettings.LockTeams); setGUIBoolean("lastManStanding", "lastManStandingText", !!mapSettings.LastManStanding); + setGUIBoolean("regicideGarrison", "regicideGarrisonText", !!mapSettings.RegicideGarrison); setGUIBoolean("enableRating", "enableRatingText", !!mapSettings.RatingEnabled); Engine.GetGUIObjectByName("optionWonderDuration").hidden = g_GameAttributes.settings.GameType && g_GameAttributes.settings.GameType != "wonder"; + Engine.GetGUIObjectByName("optionRegicideGarrison").hidden = + g_GameAttributes.settings.GameType && + g_GameAttributes.settings.GameType != "regicide"; Engine.GetGUIObjectByName("cheatWarningText").hidden = !g_IsNetworked || !mapSettings.CheatsEnabled; @@ -1448,7 +1454,8 @@ for (let ctrl of ["victoryCondition", "wonderDuration", "populationCap", "startingResources", "ceasefire", "revealMap", - "exploreMap", "disableTreasures", "lockTeams", "lastManStanding"]) + "exploreMap", "disableTreasures", "lockTeams", + "lastManStanding", "regicideGarrison"]) hideControl(ctrl, ctrl + "Text", notScenario); Engine.GetGUIObjectByName("civResetButton").hidden = !notScenario; Index: binaries/data/mods/public/gui/gamesetup/gamesetup.xml =================================================================== --- binaries/data/mods/public/gui/gamesetup/gamesetup.xml +++ binaries/data/mods/public/gui/gamesetup/gamesetup.xml @@ -347,8 +347,18 @@ - + + Hero Garrison: + + + + + + + Population Cap: @@ -357,7 +367,7 @@ - + Starting Resources: @@ -367,7 +377,7 @@ - + Ceasefire: @@ -452,7 +462,7 @@ name="hideMoreOptions" type="button" style="StoneButton" - size="50%-70 428 50%+70 456" + size="50%-70 458 50%+70 486" tooltip_style="onscreenToolTip" hotkey="cancel" > Index: binaries/data/mods/public/maps/scripts/Regicide.js =================================================================== --- binaries/data/mods/public/maps/scripts/Regicide.js +++ binaries/data/mods/public/maps/scripts/Regicide.js @@ -6,6 +6,9 @@ Trigger.prototype.InitRegicideGame = function(msg) { + let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); + this.regicideGarrison = cmpEndGameManager.GetGameTypeSettings().regicideGarrison; + let playersCivs = []; for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID) playersCivs[playerID] = QueryPlayerIDInterface(playerID).GetCiv(); @@ -30,7 +33,7 @@ if (heroTemplates[identity.Civ].indexOf(templateName) == -1) heroTemplates[identity.Civ].push({ - "templateName": templateName, + "templateName": this.regicideGarrison ? templateName : "regicide_hero_garrison_disabled|" + templateName, "classes": classes }); } @@ -51,6 +54,27 @@ return 0; }; + let cmpWaterManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_WaterManager); + let cmpTerritoryManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager); + + let gaiaSpawnPreferences = (shipEnt, entity) => { + + let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); + let cmpPosition = Engine.QueryInterface(entity, IID_Position); + + if (!cmpIdentity || !cmpPosition || !cmpPosition.IsInWorld()) + return Infinity; + + let pos = cmpPosition.GetPosition(); + + // Do not spawn heroes underwater + if (pos.y <= cmpWaterManager.GetWaterLevel(pos.x, pos.z) || + cmpTerritoryManager.GetOwner(Vector2D.from3D(pos).x, Vector2D.from3D(pos).y) != 0) + return Infinity; + + return Engine.QueryInterface(shipEnt, IID_Position).GetPosition2D().distanceTo(Vector2D.from3D(pos)); + } + // Attempt to spawn one hero per player let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID) @@ -58,6 +82,11 @@ let spawnPoints = cmpRangeManager.GetEntitiesByPlayer(playerID).sort((entity1, entity2) => getSpawnPreference(entity2) - getSpawnPreference(entity1)); + // Spawn the hero on land as close as possible + if (!this.regicideGarrison && TriggerHelper.EntityHasClass(spawnPoints[0], "Ship")) + spawnPoints = cmpRangeManager.GetEntitiesByPlayer(0).sort((entity1, entity2) => + gaiaSpawnPreferences(spawnPoints[0], entity1) - gaiaSpawnPreferences(spawnPoints[0], entity2)); + this.regicideHeroes[playerID] = this.SpawnRegicideHero(playerID, heroTemplates[playersCivs[playerID]], spawnPoints); } }; @@ -108,5 +137,6 @@ let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); cmpTrigger.regicideHeroes = []; +cmpTrigger.regicideGarrison = false; cmpTrigger.DoAfterDelay(0, "InitRegicideGame", {}); cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CheckRegicideDefeat", { "enabled": true }); Index: binaries/data/mods/public/simulation/ai/common-api/entity.js =================================================================== --- binaries/data/mods/public/simulation/ai/common-api/entity.js +++ binaries/data/mods/public/simulation/ai/common-api/entity.js @@ -747,6 +747,8 @@ "canGuard": function() { return this.get("UnitAI/CanGuard") === "true"; }, + "garrisonEnabled": function() { return this.get("UnitAI/GarrisonEnabled") === "true"; }, + move: function(x, z, queued = false) { Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued }); return this; Index: binaries/data/mods/public/simulation/ai/petra/garrisonManager.js =================================================================== --- binaries/data/mods/public/simulation/ai/petra/garrisonManager.js +++ binaries/data/mods/public/simulation/ai/petra/garrisonManager.js @@ -171,7 +171,7 @@ /** This is just a pre-garrison state, while the entity walk to the garrison holder */ m.GarrisonManager.prototype.garrison = function(gameState, ent, holder, type) { - if (this.numberOfGarrisonedUnits(holder) >= holder.garrisonMax()) + if (this.numberOfGarrisonedUnits(holder) >= holder.garrisonMax() || !ent.garrisonEnabled()) return; this.registerHolder(gameState, holder); Index: binaries/data/mods/public/simulation/ai/petra/navalManager.js =================================================================== --- binaries/data/mods/public/simulation/ai/petra/navalManager.js +++ binaries/data/mods/public/simulation/ai/petra/navalManager.js @@ -379,6 +379,9 @@ */ m.NavalManager.prototype.requireTransport = function(gameState, entity, startIndex, endIndex, endPos) { + if (!entity.garrisonEnabled()) + return; + if (entity.getMetadata(PlayerID, "transport") !== undefined) { if (this.Config.debug > 0) 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 @@ -197,10 +197,11 @@ return false; var cmpIdentity = Engine.QueryInterface(entity, IID_Identity); - if (!cmpIdentity) + let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); + if (!cmpIdentity || !cmpUnitAI) return false; var entityClasses = cmpIdentity.GetClassesList(); - return MatchesClassList(entityClasses, this.template.List._string); + return MatchesClassList(entityClasses, this.template.List._string) && cmpUnitAI.GarrisonEnabled(); }; /** 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 @@ -52,6 +52,11 @@ "" + ""+ "" + + "" + + "" + + "" + + "" + + "" + ""; // Unit stances. @@ -5164,6 +5169,14 @@ }; /** + * Can be set to directly prevent garrisoning + */ +UnitAI.prototype.GarrisonEnabled = function() +{ + return this.template.GarrisonEnabled == "true"; +}; + +/** * Adds gather order to the queue, forced by the player * until the target is reached */ 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 @@ -47,6 +47,8 @@ let gameTypeSettings = {}; if (settings.WonderDuration) gameTypeSettings.wonderDuration = settings.WonderDuration * 60 * 1000; + if (settings.GameType == "regicide") + gameTypeSettings.regicideGarrison = settings.RegicideGarrison; if (settings.GameType) cmpEndGameManager.SetGameType(settings.GameType, gameTypeSettings); Index: binaries/data/mods/public/simulation/templates/special_filter/regicide_hero_garrison_disabled.xml =================================================================== --- binaries/data/mods/public/simulation/templates/special_filter/regicide_hero_garrison_disabled.xml +++ binaries/data/mods/public/simulation/templates/special_filter/regicide_hero_garrison_disabled.xml @@ -0,0 +1,6 @@ + + + + false + + Index: binaries/data/mods/public/simulation/templates/template_unit.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit.xml +++ binaries/data/mods/public/simulation/templates/template_unit.xml @@ -102,6 +102,7 @@ 12.0 false true + true false