Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingsLayout.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingsLayout.js (revision 23433) +++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingsLayout.js (revision 23434) @@ -1,48 +1,49 @@ /** * This array determines the order in which the GUI controls are shown in the GameSettingTabs panel. * The names correspond to property names of the GameSettingControls prototype. */ var g_GameSettingsLayout = [ { "label": translateWithContext("Match settings tab name", "Map"), "settings": [ "MapType", "MapFilter", "MapSelection", "MapSize", "Landscape", "Biome", + "SeaLevelRiseTime", "Daytime", "TriggerDifficulty", "Nomad", "Treasures", "ExploredMap", "RevealedMap" ] }, { "label": translateWithContext("Match settings tab name", "Player"), "settings": [ "PlayerCount", "PopulationCap", "StartingResources", "Spies", "Cheats" ] }, { "label": translateWithContext("Match settings tab name", "Game Type"), "settings": [ ...g_VictoryConditions.map(victoryCondition => victoryCondition.Name), "RelicCount", "RelicDuration", "WonderDuration", "RegicideGarrison", "GameSpeed", "Ceasefire", "LockedTeams", "LastManStanding", "Rating" ] } ]; Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Sliders/SeaLevelRiseTime.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Sliders/SeaLevelRiseTime.js (nonexistent) +++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Sliders/SeaLevelRiseTime.js (revision 23434) @@ -0,0 +1,83 @@ +GameSettingControls.SeaLevelRiseTime = class extends GameSettingControlSlider +{ + constructor(...args) + { + super(...args); + + this.values = undefined; + this.sprintfValue = {}; + } + + onMapChange(mapData) + { + this.values = + mapData && + mapData.settings && + mapData.settings.SeaLevelRise || undefined; + + if (this.values) + { + this.slider.min_value = this.values.Min; + this.slider.max_value = this.values.Max; + } + + this.setHidden(!this.values); + this.setEnabled(g_GameAttributes.mapType != "scenario"); + } + + onGameAttributesChange() + { + if (this.values) + { + if (g_GameAttributes.settings.SeaLevelRiseTime === undefined) + { + g_GameAttributes.settings.SeaLevelRiseTime = this.values.Default; + this.gameSettingsControl.updateGameAttributes(); + } + } + else if (g_GameAttributes.settings.SeaLevelRiseTime !== undefined) + { + delete g_GameAttributes.settings.SeaLevelRiseTime; + this.gameSettingsControl.updateGameAttributes(); + } + } + + onGameAttributesBatchChange() + { + if (!this.values) + return; + + let value = Math.round(g_GameAttributes.settings.SeaLevelRiseTime); + this.sprintfValue.minutes = value; + + this.setSelectedValue( + g_GameAttributes.settings.SeaLevelRiseTime, + sprintf(this.SeaLevelRiseTimeCaption(value), this.sprintfValue)); + } + + onValueChange(value) + { + g_GameAttributes.settings.SeaLevelRiseTime = value; + this.gameSettingsControl.updateGameAttributes(); + this.gameSettingsControl.setNetworkGameAttributes(); + } + + onGameAttributesFinalize() + { + if (this.values) + g_GameAttributes.settings.SeaLevelRiseTime = Math.round(g_GameAttributes.settings.SeaLevelRiseTime); + } +}; + +GameSettingControls.SeaLevelRiseTime.prototype.TitleCaption = + translate("Sea Level Rise Time"); + +GameSettingControls.SeaLevelRiseTime.prototype.Tooltip = + translate("Set the time when the water will start to rise."); + +GameSettingControls.SeaLevelRiseTime.prototype.SeaLevelRiseTimeCaption = + minutes => translatePluralWithContext("sea level rise time", "%(minutes)s minute", "%(minutes)s minutes", minutes); + +GameSettingControls.SeaLevelRiseTime.prototype.MinValue = 0; + +GameSettingControls.SeaLevelRiseTime.prototype.MaxValue = 60; Property changes on: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Sliders/SeaLevelRiseTime.js ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano.json =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano.json (revision 23433) +++ ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano.json (revision 23434) @@ -1,17 +1,22 @@ { "settings" : { "Name" : "Extinct Volcano", "Script" : "extinct_volcano.js", "Description" : "[color=\"red\"]IMPORTANT NOTE: AI PLAYERS DO NOT WORK WITH THIS MAP[/color]\n\nA once fertile valley, desolated by the eruption of the long-dormant volcano in the heart of the region. Following years of empty, scorched deadness, signs of life started reappearing and spreading. Now the land is half-way to the full lushness of its former era. Alas, it is not to be: following a long stretch of drought, interminable rains have set in in the higher regions to the north. Water levels are rising at drastic levels, slowly forcing players to seek the high ground of the lesser, extinct volcanoes or the now again dormant great cone.", "DisabledTemplates": [ "structures/ptol_lighthouse" ], "Keywords": ["trigger"], "CircularMap" : true, "Preview" : "extinctvolcano.png", + "SeaLevelRise": { + "Min": 0, + "Max": 60, + "Default": 25 + }, "TriggerScripts": [ "scripts/TriggerHelper.js", "random/extinct_volcano_triggers.js" ] } } Index: ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano_triggers.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano_triggers.js (revision 23433) +++ ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano_triggers.js (revision 23434) @@ -1,198 +1,191 @@ /** * Whether to log the water levels and which units became killed or transformed to visual actors. */ var debugLog = false; /** * Whether to rise the water to the maximum level in a minute or two. */ var debugWaterRise = false; /** - * Time in minutes when the water level starts to rise. - * Allow players to build up the economy and military for some time. - */ -var waterRiseStartTime = [22, 26]; - -/** * Duration in minutes for which the notification will be shown that states that the water will rise soon. */ var waterRiseNotificationDuration = 1; /** * Time in minutes between increases of the water level. * If the water rises too fast, the hills are of no strategic importance, * building structures would be pointless. * * At height 27, most trees are not gatherable anymore and enemies not reachable. * At height 37 most hills are barely usable. * * At min 30 stuff at the ground level should not be gatherable anymore. * At min 45 CC should be destroyed. * * Notice regular and military docks will raise with the water! */ var waterIncreaseTime = [0.5, 1]; /** * Number of meters the waterheight increases each step. * Each time the water level is changed, the pathfinder grids have to be recomputed. * Therefore raising the level should occur as rarely as possible, i.e. have the value * as big as possible, but as small as needed to keep it visually authentic. */ var waterLevelIncreaseHeight = 1; /** * At which height to stop increasing the water level. * Since players can survive on ships, don't endlessly raise the water. */ var maxWaterLevel = 70; /** * Let buildings, relics and siege engines become actors, but kill organic units. */ var drownClass = "Organic"; /** * Maximum height that units and structures can be submerged before drowning or becoming destructed. */ var drownHeight = 1; /** * One of these warnings is printed some minutes before the water level starts to rise. */ var waterWarningTexts = [ markForTranslation("It keeps on raining, we will have to evacuate soon!"), markForTranslation("The rivers are standing high, we need to find a safe place!"), markForTranslation("We have to find dry ground, our lands will drown soon!"), markForTranslation("The lakes start swallowing the land, we have to find shelter!") ]; /** * Units to be garrisoned in the wooden towers. */ var garrisonedUnits = "units/rome_champion_infantry_swordsman_02"; Trigger.prototype.RaisingWaterNotification = function() { Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface).AddTimeNotification({ "message": pickRandom(waterWarningTexts), "translateMessage": true }, waterRiseNotificationDuration * 60 * 1000); }; Trigger.prototype.DebugLog = function(txt) { if (!debugLog) return; print("DEBUG [" + Math.round(TriggerHelper.GetMinutes()) + "] " + txt + "\n"); }; Trigger.prototype.GarrisonWoodenTowers = function() { for (let gaiaEnt of Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetEntitiesByPlayer(0)) { let cmpIdentity = Engine.QueryInterface(gaiaEnt, IID_Identity); if (!cmpIdentity || !cmpIdentity.HasClass("DefenseTower")) continue; let cmpGarrisonHolder = Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder); if (!cmpGarrisonHolder) continue; for (let newEnt of TriggerHelper.SpawnUnits(gaiaEnt, garrisonedUnits, cmpGarrisonHolder.GetCapacity(), 0)) if (Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder).Garrison(newEnt)) Engine.QueryInterface(newEnt, IID_UnitAI).Autogarrison(gaiaEnt); } }; Trigger.prototype.RaiseWaterLevelStep = function() { let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); let time = cmpTimer.GetTime(); let cmpWaterManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_WaterManager); let newLevel = cmpWaterManager.GetWaterLevel() + waterLevelIncreaseHeight; cmpWaterManager.SetWaterLevel(newLevel); this.DebugLog("Raising water level to " + Math.round(newLevel) + " took " + (cmpTimer.GetTime() - time)); if (newLevel < maxWaterLevel) this.DoAfterDelay((debugWaterRise ? 10 : randFloat(...waterIncreaseTime) * 60) * 1000, "RaiseWaterLevelStep", {}); else this.DebugLog("Water reached final level"); let actorTemplates = {}; let killedTemplates = {}; let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); for (let ent of cmpRangeManager.GetGaiaAndNonGaiaEntities()) { let cmpPosition = Engine.QueryInterface(ent, IID_Position); if (!cmpPosition || !cmpPosition.IsInWorld()) continue; let pos = cmpPosition.GetPosition(); if (pos.y + drownHeight >= newLevel) continue; let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); if (!cmpIdentity) continue; let templateName = cmpTemplateManager.GetCurrentTemplateName(ent); // Animals and units drown let cmpHealth = Engine.QueryInterface(ent, IID_Health); if (cmpHealth && cmpIdentity.HasClass(drownClass)) { cmpHealth.Kill(); if (debugLog) killedTemplates[templateName] = (killedTemplates[templateName] || 0) + 1; continue; } // Resources and buildings become actors // Do not use ChangeEntityTemplate for performance and // because we don't need nor want the effects of MT_EntityRenamed let cmpVisualActor = Engine.QueryInterface(ent, IID_Visual); if (!cmpVisualActor) continue; let height = cmpPosition.GetHeightOffset(); let rot = cmpPosition.GetRotation(); let actorTemplate = cmpTemplateManager.GetTemplate(templateName).VisualActor.Actor; let seed = cmpVisualActor.GetActorSeed(); Engine.DestroyEntity(ent); let newEnt = Engine.AddEntity("actor|" + actorTemplate); Engine.QueryInterface(newEnt, IID_Visual).SetActorSeed(seed); let cmpNewPos = Engine.QueryInterface(newEnt, IID_Position); cmpNewPos.JumpTo(pos.x, pos.z); cmpNewPos.SetHeightOffset(height); cmpNewPos.SetXZRotation(rot.x, rot.z); cmpNewPos.SetYRotation(rot.y); if (debugLog) actorTemplates[templateName] = (actorTemplates[templateName] || 0) + 1; } this.DebugLog("Checking entities took " + (cmpTimer.GetTime() - time)); this.DebugLog("Killed: " + uneval(killedTemplates)); this.DebugLog("Converted to actors: " + uneval(actorTemplates)); }; - { - let waterRiseTime = debugWaterRise ? 0 : randFloat(...waterRiseStartTime); + let waterRiseTime = debugWaterRise ? 0 : (InitAttributes.settings.SeaLevelRiseTime || 0); let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); cmpTrigger.GarrisonWoodenTowers(); cmpTrigger.DoAfterDelay((waterRiseTime - waterRiseNotificationDuration) * 60 * 1000, "RaisingWaterNotification", {}); cmpTrigger.DoAfterDelay(waterRiseTime * 60 * 1000, "RaiseWaterLevelStep", {}); }