Changeset View
Standalone View
binaries/data/mods/public/gui/gamesettings/attributes/PlayerName.js
/** | /** | ||||
* Stores in-game names for all players. | * Stores in-game names for all players. | ||||
* | * | ||||
* NB: the regular gamesetup has a particular handling of this setting. | * NB: the regular gamesetup has a particular handling of this setting. | ||||
* The names are loaded from the map, but the GUI also show playernames | * The names are loaded from the map, but the GUI also show playernames. | ||||
* and forces them when starting the game. | * Force these at the start of the match. | ||||
* This is therefore just handling map-defined names & AI random bot names. | |||||
*/ | */ | ||||
GameSettings.prototype.Attributes.PlayerName = class PlayerName extends GameSetting | GameSettings.prototype.Attributes.PlayerName = class PlayerName extends GameSetting | ||||
{ | { | ||||
init() | init() | ||||
{ | { | ||||
// NB: watchers aren't auto-triggered when modifying array elements. | // NB: watchers aren't auto-triggered when modifying array elements. | ||||
this.values = []; | this.values = []; | ||||
this.settings.playerCount.watch(() => this.maybeUpdate(), ["nbPlayers"]); | this.settings.playerCount.watch(() => this.maybeUpdate(), ["nbPlayers"]); | ||||
this.settings.map.watch(() => this.onMapChange(), ["map"]); | this.settings.map.watch(() => this.onMapChange(), ["map"]); | ||||
} | } | ||||
toInitAttributes(attribs) | toInitAttributes(attribs) | ||||
{ | { | ||||
if (!attribs.settings.PlayerData) | if (!attribs.settings.PlayerData) | ||||
attribs.settings.PlayerData = []; | attribs.settings.PlayerData = []; | ||||
while (attribs.settings.PlayerData.length < this.values.length) | while (attribs.settings.PlayerData.length < this.values.length) | ||||
attribs.settings.PlayerData.push({}); | attribs.settings.PlayerData.push({}); | ||||
for (let i in this.values) | for (let i in this.values) | ||||
if (this.values[i]) | if (this.values[i]) | ||||
attribs.settings.PlayerData[i].Name = this.values[i]; | attribs.settings.PlayerData[i].Name = this.values[i]; | ||||
} | } | ||||
fromInitAttributes(attribs) | |||||
{ | |||||
if (!this.getLegacySetting(attribs, "PlayerData")) | |||||
return; | |||||
const pData = this.getLegacySetting(attribs, "PlayerData"); | |||||
if (this.values.length < pData.length) | |||||
this._resize(pData.length); | |||||
for (const i in pData) | |||||
if (pData[i] && pData[i].Name !== undefined) | |||||
{ | |||||
this.values[i] = pData[i].Name; | |||||
this.trigger("values"); | |||||
} | |||||
} | |||||
_resize(nb) | _resize(nb) | ||||
{ | { | ||||
while (this.values.length > nb) | while (this.values.length > nb) | ||||
this.values.pop(); | this.values.pop(); | ||||
while (this.values.length < nb) | while (this.values.length < nb) | ||||
this.values.push(undefined); | this.values.push(undefined); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | for (let i in this.values) | ||||
}) : | }) : | ||||
chosenName; | chosenName; | ||||
} | } | ||||
if (picked) | if (picked) | ||||
this.trigger("values"); | this.trigger("values"); | ||||
return picked; | return picked; | ||||
} | } | ||||
onFinalizeAttributes(attribs, playerAssignments) | |||||
{ | |||||
// Replace client player names with the real players. | |||||
for (const guid in playerAssignments) | |||||
if (playerAssignments[guid].player !== -1) | |||||
attribs.settings.PlayerData[playerAssignments[guid].player -1].Name = playerAssignments[guid].name; | |||||
} | |||||
wraitii: This doesn't seem good to me. You end up having to pass playerAssignments to every setting, and… | |||||
Done Inline ActionsThis is the best part of it. Look better. Doing setting specific things in launchGame shouldn't be allowed. As playerAssignments can very well change any setting, it should be passed. bb: This is the best part of it. Look better. Doing setting specific things in launchGame shouldn't… | |||||
Not Done Inline ActionsI guess I see this more as an engine hardcoding that ideally shouldn't be in JS at all than as a feature, where doing it here possibly makes sense. I'm not sure it's a good thing that player assignments can change game settings at the last minute to be honest, because it makes the class less predictable. Part of my intent in separating the settings was that the GameSetting object could give you the _actual_ settings that the game would play on at any given time T, not having to redo custom logic in a number of places. The player names are an exception to this which I've found annoying, but treating player assignments as a game setting didn't really work either. Guess I'm not sure how to handle this. wraitii: I guess I see this more as an engine hardcoding that ideally shouldn't be in JS at all than as… | |||||
_getMapData(i) | _getMapData(i) | ||||
{ | { | ||||
let data = this.settings.map.data; | let data = this.settings.map.data; | ||||
if (!data || !data.settings || !data.settings.PlayerData) | if (!data || !data.settings || !data.settings.PlayerData) | ||||
return undefined; | return undefined; | ||||
if (data.settings.PlayerData.length <= i) | if (data.settings.PlayerData.length <= i) | ||||
return undefined; | return undefined; | ||||
return data.settings.PlayerData[i].Name; | return data.settings.PlayerData[i].Name; | ||||
Show All 14 Lines |
This doesn't seem good to me. You end up having to pass playerAssignments to every setting, and it's not particularly relevant to do this here. over launchGame, which avoids the argument issue.