1
0
forked from mirrors/0ad

Gamesetup slider support, use it for Ceasefire, RelicCount, RelicDuration, WonderDuration.

Use Math.round until the slider GUI object type supports fixed step
sizes, refs D406.

Differential Revision: https://code.wildfiregames.com/D2571
Comments By: Vladislav (irc), nani (PM), bb (irc), Stan
This was SVN commit r23430.
This commit is contained in:
elexis
2020-01-22 21:37:14 +00:00
parent c50a621cea
commit 352d4ea78f
15 changed files with 274 additions and 153 deletions
@@ -196,27 +196,31 @@ function getGameDescription(mapCache)
let title = translateVictoryCondition(victoryCondition.Name);
if (victoryCondition.Name == "wonder")
{
let wonderDuration = Math.round(g_GameAttributes.settings.WonderDuration);
title = sprintf(
translatePluralWithContext(
"victory condition",
"Wonder (%(min)s minute)",
"Wonder (%(min)s minutes)",
g_GameAttributes.settings.WonderDuration
wonderDuration
),
{ "min": g_GameAttributes.settings.WonderDuration }
);
{ "min": wonderDuration });
}
let isCaptureTheRelic = victoryCondition.Name == "capture_the_relic";
if (isCaptureTheRelic)
{
let relicDuration = Math.round(g_GameAttributes.settings.RelicDuration);
title = sprintf(
translatePluralWithContext(
"victory condition",
"Capture the Relic (%(min)s minute)",
"Capture the Relic (%(min)s minutes)",
g_GameAttributes.settings.RelicDuration
relicDuration
),
{ "min": g_GameAttributes.settings.RelicDuration }
);
{ "min": relicDuration });
}
titles.push({
"label": title,
@@ -226,7 +230,7 @@ function getGameDescription(mapCache)
if (isCaptureTheRelic)
titles.push({
"label": translate("Relic Count"),
"value": g_GameAttributes.settings.RelicCount
"value": Math.round(g_GameAttributes.settings.RelicCount)
});
if (victoryCondition.Name == "regicide")
@@ -271,16 +275,17 @@ function getGameDescription(mapCache)
"value": translate("If one player wins, his or her allies win too. If one group of allies remains, they win.")
});
let ceasefire = Math.round(g_GameAttributes.settings.Ceasefire);
titles.push({
"label": translate("Ceasefire"),
"value":
g_GameAttributes.settings.Ceasefire == 0 ?
ceasefire == 0 ?
translate("disabled") :
sprintf(translatePlural(
"For the first minute, other players will stay neutral.",
"For the first %(min)s minutes, other players will stay neutral.",
g_GameAttributes.settings.Ceasefire),
{ "min": g_GameAttributes.settings.Ceasefire })
ceasefire),
{ "min": ceasefire })
});
if (g_GameAttributes.map == "random")
@@ -38,8 +38,6 @@ function loadSettingsValues()
"AIDescriptions": loadAIDescriptions(),
"AIDifficulties": loadAIDifficulties(),
"AIBehaviors": loadAIBehaviors(),
"Ceasefire": loadCeasefire(),
"VictoryDurations": loadVictoryDuration(),
"GameSpeeds": loadSettingValuesFile("game_speeds.json"),
"MapTypes": loadMapTypes(),
"MapSizes": loadSettingValuesFile("map_sizes.json"),
@@ -163,50 +161,6 @@ function loadAIBehaviors()
];
}
/**
* Loads available victory times for victory conditions like Wonder and Capture the Relic.
*/
function loadVictoryDuration()
{
var jsonFile = "victory_times.json";
var json = Engine.ReadJSONFile(g_SettingsDirectory + jsonFile);
if (!json || json.Default === undefined || !json.Times || !Array.isArray(json.Times))
{
error("Could not load " + jsonFile);
return undefined;
}
return json.Times.map(duration => ({
"Duration": duration,
"Default": duration == json.Default,
"Title": sprintf(translatePluralWithContext("victory duration", "%(min)s minute", "%(min)s minutes", duration), { "min": duration })
}));
}
/**
* Loads available ceasefire settings.
*
* @returns {Array|undefined}
*/
function loadCeasefire()
{
var json = Engine.ReadJSONFile(g_SettingsDirectory + "ceasefire.json");
if (!json || json.Default === undefined || !json.Times || !Array.isArray(json.Times))
{
error("Could not load ceasefire.json");
return undefined;
}
return json.Times.map(timeout => ({
"Duration": timeout,
"Default": timeout == json.Default,
"Title": timeout == 0 ? translateWithContext("ceasefire", "No ceasefire") :
sprintf(translatePluralWithContext("ceasefire", "%(minutes)s minute", "%(minutes)s minutes", timeout), { "minutes": timeout })
}));
}
/**
* Hardcoded, as modding is not supported without major changes.
*/
@@ -5,7 +5,7 @@
<object
name="dropdownSettingControl[n]"
type="dropdown"
size="175 0 100% 30"
size="175 0 100% 28"
style="ModernDropDown"
tooltip_style="onscreenToolTip"
hidden="true"
@@ -0,0 +1,63 @@
/**
* This class is implemented by gamesettings that are controlled by a slider.
*/
class GameSettingControlSlider extends GameSettingControl
{
constructor(...args)
{
super(...args);
this.isInGuiUpdate = false;
this.slider.onValueChange = this.onValueChangeSuper.bind(this);
if (this.MinValue !== undefined)
this.slider.min_value = this.MinValue;
if (this.MaxValue !== undefined)
this.slider.max_value = this.MaxValue;
}
setControl(gameSettingControlManager)
{
let row = gameSettingControlManager.getNextRow("sliderSettingFrame");
this.frame = Engine.GetGUIObjectByName("sliderSettingFrame[" + row + "]");
this.slider = Engine.GetGUIObjectByName("sliderSettingControl[" + row + "]");
this.valueLabel = Engine.GetGUIObjectByName("sliderSettingLabel[" + row + "]");
let labels = this.frame.children[0].children;
this.title = labels[0];
this.label = labels[1];
}
setControlTooltip(tooltip)
{
this.slider.tooltip = tooltip;
this.valueLabel.tooltip = tooltip;
}
setControlHidden(hidden)
{
this.slider.hidden = hidden;
this.valueLabel.hidden = hidden;
}
setSelectedValue(value, caption)
{
this.isInGuiUpdate = true;
this.slider.value = value;
this.isInGuiUpdate = false;
this.label.caption = caption;
this.valueLabel.caption = caption;
}
onValueChangeSuper()
{
if (!this.isInGuiUpdate)
this.onValueChange(this.slider.value);
}
}
GameSettingControlSlider.prototype.UnknownValue =
translateWithContext("settings value", "Unknown");
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<object name="sliderSettingFrame[n]" size="0 2 100% 36" hidden="true">
<include file="gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingControlLabels.xml"/>
<object
name="sliderSettingControl[n]"
type="slider"
size="175 7 100% 19"
style="ModernSlider"
tooltip_style="onscreenToolTip"
hidden="true"
z="1"
/>
<object
name="sliderSettingLabel[n]"
type="text"
style="ModernLabelText"
font="sans-bold-12"
size="175 22 100% 34"
z="1"
/>
</object>
@@ -1,55 +0,0 @@
GameSettingControls.Ceasefire = class extends GameSettingControlDropdown
{
constructor(...args)
{
super(...args);
this.values = prepareForDropdown(g_Settings.Ceasefire);
this.dropdown.list = this.values.Title;
this.dropdown.list_data = this.values.Duration;
}
onMapChange(mapData)
{
let mapValue =
mapData &&
mapData.settings &&
mapData.settings.Ceasefire || undefined;
if (mapValue !== undefined && mapValue != g_GameAttributes.settings.Ceasefire)
{
g_GameAttributes.settings.Ceasefire = mapValue;
this.gameSettingsControl.updateGameAttributes();
}
this.setEnabled(g_GameAttributes.mapType != "scenario");
}
onGameAttributesChange()
{
if (g_GameAttributes.settings.Ceasefire == undefined)
{
g_GameAttributes.settings.Ceasefire = this.values.Default;
this.gameSettingsControl.updateGameAttributes();
}
}
onGameAttributesBatchChange()
{
this.setSelectedValue(g_GameAttributes.settings.Ceasefire);
}
onSelectionChange(itemIdx)
{
g_GameAttributes.settings.Ceasefire = this.values.Duration[itemIdx];
this.gameSettingsControl.updateGameAttributes();
this.gameSettingsControl.setNetworkGameAttributes();
}
};
GameSettingControls.Ceasefire.prototype.TitleCaption =
translate("Ceasefire");
GameSettingControls.Ceasefire.prototype.Tooltip =
translate("Set time where no attacks are possible.");
@@ -0,0 +1,76 @@
GameSettingControls.Ceasefire = class extends GameSettingControlSlider
{
constructor(...args)
{
super(...args);
this.sprintfValue = {};
}
onMapChange(mapData)
{
let mapValue =
mapData &&
mapData.settings &&
mapData.settings.Ceasefire || undefined;
if (mapValue !== undefined && mapValue != g_GameAttributes.settings.Ceasefire)
{
g_GameAttributes.settings.Ceasefire = mapValue;
this.gameSettingsControl.updateGameAttributes();
}
this.setEnabled(g_GameAttributes.mapType != "scenario");
}
onGameAttributesChange()
{
if (g_GameAttributes.settings.Ceasefire == undefined)
{
g_GameAttributes.settings.Ceasefire = this.DefaultValue;
this.gameSettingsControl.updateGameAttributes();
}
}
onGameAttributesBatchChange()
{
let value = Math.round(g_GameAttributes.settings.Ceasefire);
this.sprintfValue.minutes = value;
this.setSelectedValue(
g_GameAttributes.settings.Ceasefire,
value == 0 ?
this.NoCeasefireCaption :
sprintf(this.CeasefireCaption(value), this.sprintfValue));
}
onValueChange(value)
{
g_GameAttributes.settings.Ceasefire = value;
this.gameSettingsControl.updateGameAttributes();
this.gameSettingsControl.setNetworkGameAttributes();
}
onGameAttributesFinalize()
{
g_GameAttributes.settings.Ceasefire = Math.round(g_GameAttributes.settings.Ceasefire);
}
};
GameSettingControls.Ceasefire.prototype.TitleCaption =
translate("Ceasefire");
GameSettingControls.Ceasefire.prototype.Tooltip =
translate("Set time where no attacks are possible.");
GameSettingControls.Ceasefire.prototype.NoCeasefireCaption =
translateWithContext("ceasefire", "No ceasefire");
GameSettingControls.Ceasefire.prototype.CeasefireCaption =
minutes => translatePluralWithContext("ceasefire", "%(minutes)s minute", "%(minutes)s minutes", minutes);
GameSettingControls.Ceasefire.prototype.DefaultValue = 0;
GameSettingControls.Ceasefire.prototype.MinValue = 0;
GameSettingControls.Ceasefire.prototype.MaxValue = 45;
@@ -1,14 +1,10 @@
GameSettingControls.RelicCount = class extends GameSettingControlDropdown
GameSettingControls.RelicCount = class extends GameSettingControlSlider
{
constructor(...args)
{
super(...args);
this.values = Object.keys(g_CivData).map((v, i) => i + 1);
this.dropdown.list = this.values;
this.dropdown.list_data = this.values;
this.sprintfValue = {};
this.available = false;
}
@@ -47,7 +43,7 @@ GameSettingControls.RelicCount = class extends GameSettingControlDropdown
{
if (g_GameAttributes.settings.RelicCount === undefined)
{
g_GameAttributes.settings.RelicCount = this.DefaultRelicCount;
g_GameAttributes.settings.RelicCount = this.DefaultValue;
this.gameSettingsControl.updateGameAttributes();
}
}
@@ -63,24 +59,43 @@ GameSettingControls.RelicCount = class extends GameSettingControlDropdown
this.setHidden(!this.available);
if (this.available)
this.setSelectedValue(g_GameAttributes.settings.RelicCount);
{
let value = Math.round(g_GameAttributes.settings.RelicCount);
this.sprintfValue.number = value;
this.setSelectedValue(
g_GameAttributes.settings.RelicCount,
value == 0 ? this.InstantVictory : sprintf(this.CaptionRelicCount(value), this.sprintfValue));
}
}
onSelectionChange(itemIdx)
onValueChange(value)
{
g_GameAttributes.settings.RelicCount = this.values[itemIdx];
g_GameAttributes.settings.RelicCount = value;
this.gameSettingsControl.updateGameAttributes();
this.gameSettingsControl.setNetworkGameAttributes();
}
onGameAttributesFinalize()
{
if (this.available)
g_GameAttributes.settings.RelicCount = Math.round(g_GameAttributes.settings.RelicCount);
}
};
GameSettingControls.RelicCount.prototype.TitleCaption =
translate("Relic Count");
GameSettingControls.RelicCount.prototype.CaptionRelicCount =
relicCount => translatePlural("%(number)s relic", "%(number)s relics", relicCount);
GameSettingControls.RelicCount.prototype.Tooltip =
translate("Total number of relics spawned on the map. Relic victory is most realistic with only one or two relics. With greater numbers, the relics are important to capture to receive aura bonuses.");
GameSettingControls.RelicCount.prototype.NameCaptureTheRelic =
"capture_the_relic";
GameSettingControls.RelicCount.prototype.DefaultRelicCount = 2;
GameSettingControls.RelicCount.prototype.MinValue = 1;
GameSettingControls.RelicCount.prototype.MaxValue = Object.keys(g_CivData).length;
GameSettingControls.RelicCount.prototype.DefaultValue = 2;
@@ -1,14 +1,10 @@
GameSettingControls.RelicDuration = class extends GameSettingControlDropdown
GameSettingControls.RelicDuration = class extends GameSettingControlSlider
{
constructor(...args)
{
super(...args);
this.values = prepareForDropdown(g_Settings.VictoryDurations);
this.dropdown.list = this.values.Title;
this.dropdown.list_data = this.values.Duration;
this.sprintfValue = {};
this.available = false;
}
@@ -33,7 +29,6 @@ GameSettingControls.RelicDuration = class extends GameSettingControlDropdown
g_GameAttributes.settings.VictoryConditions.push(this.NameCaptureTheRelic);
g_GameAttributes.settings.RelicDuration = mapValue;
this.gameSettingsControl.updateGameAttributes();
}
@@ -48,7 +43,7 @@ GameSettingControls.RelicDuration = class extends GameSettingControlDropdown
{
if (g_GameAttributes.settings.RelicDuration === undefined)
{
g_GameAttributes.settings.RelicDuration = this.values.Duration[this.values.Default];
g_GameAttributes.settings.RelicDuration = this.DefaultValue;
this.gameSettingsControl.updateGameAttributes();
}
}
@@ -64,15 +59,27 @@ GameSettingControls.RelicDuration = class extends GameSettingControlDropdown
this.setHidden(!this.available);
if (this.available)
this.setSelectedValue(g_GameAttributes.settings.RelicDuration);
{
let value = Math.round(g_GameAttributes.settings.RelicDuration);
this.sprintfValue.min = value;
this.setSelectedValue(
g_GameAttributes.settings.RelicDuration,
value == 0 ? this.InstantVictory : sprintf(this.CaptionVictoryTime(value), this.sprintfValue));
}
}
onSelectionChange(itemIdx)
onValueChange(value)
{
g_GameAttributes.settings.RelicDuration = this.values.Duration[itemIdx];
g_GameAttributes.settings.RelicDuration = value;
this.gameSettingsControl.updateGameAttributes();
this.gameSettingsControl.setNetworkGameAttributes();
}
onGameAttributesFinalize()
{
if (this.available)
g_GameAttributes.settings.RelicDuration = Math.round(g_GameAttributes.settings.RelicDuration);
}
};
GameSettingControls.RelicDuration.prototype.TitleCaption =
@@ -83,3 +90,15 @@ GameSettingControls.RelicDuration.prototype.Tooltip =
GameSettingControls.RelicDuration.prototype.NameCaptureTheRelic =
"capture_the_relic";
GameSettingControls.RelicDuration.prototype.CaptionVictoryTime =
min => translatePluralWithContext("victory duration", "%(min)s minute", "%(min)s minutes", min);
GameSettingControls.RelicDuration.prototype.InstantVictory =
translateWithContext("victory duration", "Immediate Victory.");
GameSettingControls.RelicDuration.prototype.MinValue = 0;
GameSettingControls.RelicDuration.prototype.MaxValue = 60;
GameSettingControls.RelicDuration.prototype.DefaultValue = 20;
@@ -1,14 +1,10 @@
GameSettingControls.WonderDuration = class extends GameSettingControlDropdown
GameSettingControls.WonderDuration = class extends GameSettingControlSlider
{
constructor(...args)
{
super(...args);
this.values = prepareForDropdown(g_Settings.VictoryDurations);
this.dropdown.list = this.values.Title;
this.dropdown.list_data = this.values.Duration;
this.sprintfValue = {};
this.available = false;
}
@@ -48,7 +44,7 @@ GameSettingControls.WonderDuration = class extends GameSettingControlDropdown
{
if (g_GameAttributes.settings.WonderDuration === undefined)
{
g_GameAttributes.settings.WonderDuration = this.values.Duration[this.values.Default];
g_GameAttributes.settings.WonderDuration = this.DefaultValue;
this.gameSettingsControl.updateGameAttributes();
}
}
@@ -64,15 +60,27 @@ GameSettingControls.WonderDuration = class extends GameSettingControlDropdown
this.setHidden(!this.available);
if (this.available)
this.setSelectedValue(g_GameAttributes.settings.WonderDuration);
{
let value = Math.round(g_GameAttributes.settings.WonderDuration);
this.sprintfValue.min = value;
this.setSelectedValue(
g_GameAttributes.settings.WonderDuration,
value == 0 ? this.InstantVictory : sprintf(this.CaptionVictoryTime(value), this.sprintfValue));
}
}
onSelectionChange(itemIdx)
onValueChange(value)
{
g_GameAttributes.settings.WonderDuration = this.values.Duration[itemIdx];
g_GameAttributes.settings.WonderDuration = value;
this.gameSettingsControl.updateGameAttributes();
this.gameSettingsControl.setNetworkGameAttributes();
}
onGameAttributesFinalize()
{
if (this.available)
g_GameAttributes.settings.WonderDuration = Math.round(g_GameAttributes.settings.WonderDuration);
}
};
GameSettingControls.WonderDuration.prototype.TitleCaption =
@@ -83,3 +91,15 @@ GameSettingControls.WonderDuration.prototype.Tooltip =
GameSettingControls.WonderDuration.prototype.NameWonderVictory =
"wonder";
GameSettingControls.WonderDuration.prototype.CaptionVictoryTime =
min => translatePluralWithContext("victory duration", "%(min)s minute", "%(min)s minutes", min);
GameSettingControls.WonderDuration.prototype.InstantVictory =
translateWithContext("victory duration", "Immediate Victory.");
GameSettingControls.WonderDuration.prototype.MinValue = 0;
GameSettingControls.WonderDuration.prototype.MaxValue = 60;
GameSettingControls.WonderDuration.prototype.DefaultValue = 20;
@@ -175,7 +175,7 @@ GameSettingsPanel.prototype.SlideSpeed = 1.2;
/**
* Vertical size of a setting frame.
*/
GameSettingsPanel.prototype.SettingHeight = 32;
GameSettingsPanel.prototype.SettingHeight = 36;
/**
* Horizontal space between two setting frames.
@@ -17,5 +17,11 @@
</object>
</repeat>
<repeat count="15" var="n">
<object>
<include file="gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingControlSlider.xml"/>
</object>
</repeat>
</object>
</object>
@@ -10,6 +10,7 @@
<script directory="gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/"/>
<script directory="gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Checkboxes/"/>
<script directory="gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/"/>
<script directory="gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Sliders/"/>
<script directory="gui/gamesetup/NetMessages/"/>
<script directory="gui/gamesetup/Pages/GameSetupPage/"/>
<script directory="gui/gamesetup/Pages/GameSetupPage/Panels/"/>
@@ -1,4 +0,0 @@
{
"Times": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 45, 60],
"Default": 0
}
@@ -1,4 +0,0 @@
{
"Times": [0, 1, 3, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 75, 90, 105, 120],
"Default": 20
}