mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Use a slider for population cap
To allow Unlimited / Infinity the slider can't be linear. Refs: #2593
This commit is contained in:
parent
e79f8ea327
commit
38eb999ff9
10 changed files with 58 additions and 54 deletions
|
|
@ -35,8 +35,9 @@ GameSettings.prototype.Attributes.Population = class Population extends GameSett
|
|||
if (this.getLegacySetting(attribs, "PopulationCapType") !== undefined)
|
||||
this.setPopCapType(this.getLegacySetting(attribs, "PopulationCapType"));
|
||||
|
||||
if (this.getLegacySetting(attribs, "PopulationCap") !== undefined)
|
||||
this.setPopCap(this.getLegacySetting(attribs, "PopulationCap"));
|
||||
const cap = this.getLegacySetting(attribs, "PopulationCap");
|
||||
if (cap !== undefined)
|
||||
this.setPopCap(cap ?? Infinity);
|
||||
}
|
||||
|
||||
onMapChange()
|
||||
|
|
@ -64,7 +65,9 @@ GameSettings.prototype.Attributes.Population = class Population extends GameSett
|
|||
setPopCapType(capType)
|
||||
{
|
||||
this.capType = capType;
|
||||
const oldFactor = this.currentData?.Factor;
|
||||
this.currentData = g_Settings.PopulationCapacities.find(type => type.Name == capType);
|
||||
this.setPopCap(this.currentData.Options.Default);
|
||||
this.setPopCap(10 * Math.round(
|
||||
(this.cap && oldFactor ? (this.cap / oldFactor) : 1) * this.currentData.Factor / 10));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -382,9 +382,9 @@ function getGameDescription(initAttributes, mapCache)
|
|||
"value":
|
||||
initAttributes.settings.PlayerData?.some(pData => pData?.PopulationLimit !== undefined) ?
|
||||
translateWithContext("population capacity", "Per Player") :
|
||||
initAttributes.settings.PopulationCap < 10000 ?
|
||||
initAttributes.settings.PopulationCap :
|
||||
translateWithContext("population capacity", "Unlimited")
|
||||
initAttributes.settings.PopulationCap === Infinity ?
|
||||
translateWithContext("population capacity", "Unlimited") :
|
||||
initAttributes.settings.PopulationCap
|
||||
});
|
||||
|
||||
titles.push({
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ function translatePopulationCapacity(popCap, popCapType)
|
|||
if (!popCapTypeData)
|
||||
return translateWithContext("population capacity", "Unknown");
|
||||
|
||||
return popCap >= 10000 ?
|
||||
return popCap === Infinity ?
|
||||
translateWithContext("population capacity", "Unlimited") :
|
||||
sprintf(translate("%(populationCapacity)s (%(populationCapacityType)s)"), {
|
||||
"populationCapacity": popCap,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class GameSettingsGuiData
|
|||
Serialize()
|
||||
{
|
||||
const ret = {
|
||||
"linearPopulationCapacity": this.linearPopulationCapacity,
|
||||
"mapFilter": this.mapFilter.filter
|
||||
};
|
||||
if (Object.keys(this.lockSettings).length)
|
||||
|
|
@ -30,6 +31,7 @@ class GameSettingsGuiData
|
|||
Deserialize(data)
|
||||
{
|
||||
this.mapFilter.filter = data.mapFilter;
|
||||
this.linearPopulationCapacity = data.linearPopulationCapacity;
|
||||
this.lockSettings = data?.lockSettings || {};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ const CAPTYPE_PLAYER_POPULATION = "player";
|
|||
const CAPTYPE_TEAM_POPULATION = "team";
|
||||
const CAPTYPE_WORLD_POPULATION = "world";
|
||||
|
||||
GameSettingControls.PopulationCap = class PopulationCap extends GameSettingControlDropdown
|
||||
GameSettingControls.PopulationCap = class PopulationCap extends GameSettingControlSlider
|
||||
{
|
||||
constructor(...args)
|
||||
{
|
||||
|
|
@ -15,38 +15,52 @@ GameSettingControls.PopulationCap = class PopulationCap extends GameSettingContr
|
|||
this.render();
|
||||
}
|
||||
|
||||
round(value)
|
||||
{
|
||||
return Math.round(value / 10) * 10;
|
||||
}
|
||||
|
||||
linearToLogarythmic(value)
|
||||
{
|
||||
return this.round((1 / (1 - value) + 28 * value / (1 + 5 * value)) *
|
||||
g_GameSettings.population.currentData.Factor / 6);
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
this.setEnabled(g_GameSettings.map.type != "scenario" && !g_GameSettings.population.perPlayer);
|
||||
this.title.caption = g_GameSettings.population.currentData.CapTitle;
|
||||
if (g_GameSettings.population.perPlayer)
|
||||
this.label.caption = this.PerPlayerCaption;
|
||||
if (!this.enabled)
|
||||
return;
|
||||
else
|
||||
this.setTooltip(0);
|
||||
|
||||
this.dropdown.list_data = g_GameSettings.population.currentData.Options.List;
|
||||
this.dropdown.list = this.dropdown.list_data.map(population =>
|
||||
population < 10000 ? population : translate("Unlimited")
|
||||
);
|
||||
this.setSelectedValue(g_GameSettings.population.cap);
|
||||
const linear = this.gameSettingsController.guiData.linearPopulationCapacity ?? 0.5;
|
||||
const display = g_GameSettings.population.cap === Infinity ? translate("Unlimited") :
|
||||
g_GameSettings.population.cap;
|
||||
this.setSelectedValue(linear, display);
|
||||
}
|
||||
|
||||
|
||||
onHoverChange()
|
||||
onValueChange(value)
|
||||
{
|
||||
this.gameSettingsController.guiData.linearPopulationCapacity = value;
|
||||
const popCap = this.linearToLogarythmic(value);
|
||||
g_GameSettings.population.setPopCap(popCap);
|
||||
this.setTooltip(popCap);
|
||||
this.gameSettingsController.setNetworkInitAttributes();
|
||||
}
|
||||
|
||||
setTooltip(popCap)
|
||||
{
|
||||
if (this.dropdown.hovered == -1)
|
||||
return;
|
||||
let tooltip = g_GameSettings.population.currentData.CapTooltip;
|
||||
if (this.canTotalPopExceedRecommendedMax())
|
||||
if (this.canTotalPopExceedRecommendedMax(popCap))
|
||||
tooltip = setStringTags(this.WarningTooltip, this.WarningTags);
|
||||
|
||||
this.dropdown.tooltip = tooltip;
|
||||
this.slider.tooltip = tooltip;
|
||||
}
|
||||
|
||||
|
||||
canTotalPopExceedRecommendedMax()
|
||||
canTotalPopExceedRecommendedMax(popCap)
|
||||
{
|
||||
const popCap = g_GameSettings.population.currentData.Options.List[this.dropdown.hovered];
|
||||
const nbPlayers = g_GameSettings.playerCount.nbPlayers;
|
||||
const nbTeams = g_GameSettings.playerTeam.values.reduce((teamList, team) =>
|
||||
{
|
||||
|
|
@ -86,3 +100,6 @@ GameSettingControls.PopulationCap.prototype.WarningTags = {
|
|||
* It means a 4v4 with 150 population can still run nicely, but more than that might "lag".
|
||||
*/
|
||||
GameSettingControls.PopulationCap.prototype.PopulationCapacityRecommendation = 1200;
|
||||
|
||||
GameSettingControls.PopulationCap.prototype.MinValue = 0;
|
||||
GameSettingControls.PopulationCap.prototype.MaxValue = 1;
|
||||
|
|
@ -95,21 +95,11 @@ function initMapNameFilter(filters)
|
|||
*/
|
||||
function initPopCapFilter(filters)
|
||||
{
|
||||
var populationFilter = Engine.GetGUIObjectByName("populationFilter");
|
||||
const populationFilter = Engine.GetGUIObjectByName("populationFilter");
|
||||
const popCapSet = new Set(g_Replays.map(replay => replay.attribs.settings.PopulationCap));
|
||||
const popCapOptions = [...popCapSet.values()].sort((a, b) => b - a);
|
||||
|
||||
// Merge the pop cap options of all pop cap types into one single list.
|
||||
const popCapOptions = g_PopulationCapacities.Options
|
||||
.map(item => item.List)
|
||||
.flat()
|
||||
.reduce((list, cap) =>
|
||||
{
|
||||
if (!list.includes(cap))
|
||||
list.push(cap);
|
||||
return list;
|
||||
}, [])
|
||||
.sort((a, b) => a > b);
|
||||
|
||||
populationFilter.list = [translateWithContext("population capacity", "Any")].concat(popCapOptions.map(cap => cap >= 10000 ? "Unlimited" : cap));
|
||||
populationFilter.list = [translateWithContext("population capacity", "Any")].concat(popCapOptions.map(cap => cap === Infinity ? "Unlimited" : cap));
|
||||
populationFilter.list_data = [""].concat(popCapOptions);
|
||||
|
||||
if (filters?.popCap)
|
||||
|
|
|
|||
|
|
@ -174,8 +174,7 @@ function sanitizeInitAttributes(attribs)
|
|||
if (!attribs.settings.PlayerData)
|
||||
attribs.settings.PlayerData = [];
|
||||
|
||||
if (!attribs.settings.PopulationCap)
|
||||
attribs.settings.PopulationCap = 300;
|
||||
attribs.settings.PopulationCap ??= Infinity;
|
||||
|
||||
if (!attribs.settings.PopulationCapType)
|
||||
attribs.settings.PopulationCapType =
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ class CounterPopulation
|
|||
|
||||
rebuild(playerState, getAllyStatTooltip)
|
||||
{
|
||||
this.count.caption = sprintf(translate(this.CounterCaption), playerState);
|
||||
const state = Object.fromEntries(Object.entries(playerState).map(([key, value]) =>
|
||||
[key, value === Infinity ? translateWithContext("In other places refered as 'Unlimited', here is to litle space.", "∞") : value]));
|
||||
this.count.caption = sprintf(translate(this.CounterCaption), state);
|
||||
let total = 0;
|
||||
for (const resCode of g_ResourceData.GetCodes())
|
||||
total += playerState.resourceGatherers[resCode];
|
||||
|
|
|
|||
|
|
@ -9,10 +9,7 @@
|
|||
"Tooltip": "Locked population cap for all players.",
|
||||
"CapTooltip": "Choose the player population cap.",
|
||||
"Default": true,
|
||||
"Options": {
|
||||
"List": [50, 100, 150, 200, 250, 300, 10000],
|
||||
"Default": 300
|
||||
}
|
||||
"Factor": 300
|
||||
},
|
||||
{
|
||||
"Name": "team",
|
||||
|
|
@ -20,10 +17,7 @@
|
|||
"CapTitle": "Team Population Cap",
|
||||
"Tooltip": "Distributes a team's total population cap evenly over all its living members. Enables the setting 'Locked teams'.",
|
||||
"CapTooltip": "Choose the team population cap.",
|
||||
"Options": {
|
||||
"List": [100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 700, 800, 1000, 10000],
|
||||
"Default": 400
|
||||
}
|
||||
"Factor": 400
|
||||
},
|
||||
{
|
||||
"Name": "world",
|
||||
|
|
@ -31,10 +25,7 @@
|
|||
"CapTitle": "World Population Cap",
|
||||
"Tooltip": "Distributes the total population cap evenly over all living players.",
|
||||
"CapTooltip": "Choose the world population cap.",
|
||||
"Options": {
|
||||
"List": [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1600, 2000, 2400, 10000],
|
||||
"Default": 600
|
||||
}
|
||||
"Factor": 600
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ function InitGame(settings)
|
|||
}
|
||||
|
||||
{
|
||||
const popCap = settings.PopulationCap || 300;
|
||||
const popCap = settings.PopulationCap ?? Infinity;
|
||||
const cmpPopulationCapManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PopulationCapManager);
|
||||
const nonGaiaPlayers = settings.PlayerData.slice(1);
|
||||
if (nonGaiaPlayers.some(player => player.PopulationLimit))
|
||||
|
|
|
|||
Loading…
Reference in a new issue