_characterSetup.CloseButton.OnPressed += _ =>
{
+ // Reset sliders etc.
+ _characterSetup?.UpdateControls();
+
+ var controller = _userInterfaceManager.GetUIController<LobbyUIController>();
+ controller.SetClothes(true);
+ controller.UpdateProfile();
_lobby.SwitchState(LobbyGui.LobbyGuiState.Default);
};
_characterSetup.SaveButton.OnPressed += _ =>
{
_characterSetup.Save();
- _userInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
+ _userInterfaceManager.GetUIController<LobbyUIController>().ReloadProfile();
};
LayoutContainer.SetAnchorPreset(_lobby, LayoutContainer.LayoutPreset.Wide);
using Content.Client.Inventory;
using Content.Client.Lobby.UI;
using Content.Client.Preferences;
+using Content.Client.Preferences.UI;
using Content.Client.Station;
using Content.Shared.Clothing;
using Content.Shared.GameTicking;
private LobbyCharacterPreviewPanel? _previewPanel;
+ private bool _showClothes = true;
+
/*
* Each character profile has its own dummy. There is also a dummy for the lobby screen + character editor
* that is shared too.
private EntityUid? _previewDummy;
/// <summary>
- /// If we currently have a loadout selected.
+ /// If we currently have a job prototype selected.
/// </summary>
private JobPrototype? _dummyJob;
// TODO: Load the species directly and don't update entity ever.
public event Action<EntityUid>? PreviewDummyUpdated;
+ private HumanoidCharacterProfile? _profile;
+
public override void Initialize()
{
base.Initialize();
private void PreferencesDataLoaded()
{
- UpdateCharacterUI();
+ UpdateProfile();
}
public void OnStateEntered(LobbyState state)
public void SetPreviewPanel(LobbyCharacterPreviewPanel? panel)
{
_previewPanel = panel;
- UpdateCharacterUI();
+ ReloadProfile();
+ }
+
+ public void SetClothes(bool value)
+ {
+ if (_showClothes == value)
+ return;
+
+ _showClothes = value;
+ ReloadCharacterUI();
}
public void SetDummyJob(JobPrototype? job)
{
_dummyJob = job;
- UpdateCharacterUI();
+ ReloadCharacterUI();
}
- public void UpdateCharacterUI()
+ /// <summary>
+ /// Updates the character only with the specified profile change.
+ /// </summary>
+ public void ReloadProfile()
{
// Test moment
- if (_stateManager.CurrentState is not LobbyState)
+ if (_profile == null || _stateManager.CurrentState is not LobbyState)
+ return;
+
+ // Ignore job clothes and the likes so we don't spam entities out every frame of color changes.
+ var previewDummy = EnsurePreviewDummy(_profile);
+ _humanoid.LoadProfile(previewDummy, _profile);
+ }
+
+ /// <summary>
+ /// Updates the currently selected character's preview.
+ /// </summary>
+ public void ReloadCharacterUI()
+ {
+ // Test moment
+ if (_profile == null || _stateManager.CurrentState is not LobbyState)
return;
+ EntityManager.DeleteEntity(_previewDummy);
+ _previewDummy = null;
+ _previewDummy = EnsurePreviewDummy(_profile);
+ _previewPanel?.SetSprite(_previewDummy.Value);
+ _previewPanel?.SetSummaryText(_profile.Summary);
+ _humanoid.LoadProfile(_previewDummy.Value, _profile);
+
+ if (_showClothes)
+ GiveDummyJobClothesLoadout(_previewDummy.Value, _profile);
+ }
+
+ /// <summary>
+ /// Updates character profile to the default.
+ /// </summary>
+ public void UpdateProfile()
+ {
if (!_preferencesManager.ServerDataLoaded)
{
- _previewPanel?.SetLoaded(false);
+ _profile = null;
return;
}
- _previewPanel?.SetLoaded(true);
-
- if (_preferencesManager.Preferences?.SelectedCharacter is not HumanoidCharacterProfile selectedCharacter)
+ if (_preferencesManager.Preferences?.SelectedCharacter is HumanoidCharacterProfile selectedCharacter)
{
- _previewPanel?.SetSummaryText(string.Empty);
+ _profile = selectedCharacter;
+ _previewPanel?.SetLoaded(true);
}
else
{
- EntityManager.DeleteEntity(_previewDummy);
- _previewDummy = EntityManager.SpawnEntity(_prototypeManager.Index<SpeciesPrototype>(selectedCharacter.Species).DollPrototype, MapCoordinates.Nullspace);
- _previewPanel?.SetSprite(_previewDummy.Value);
- _previewPanel?.SetSummaryText(selectedCharacter.Summary);
- _humanoid.LoadProfile(_previewDummy.Value, selectedCharacter);
-
- GiveDummyJobClothesLoadout(_previewDummy.Value, selectedCharacter);
- PreviewDummyUpdated?.Invoke(_previewDummy.Value);
+ _previewPanel?.SetSummaryText(string.Empty);
+ _previewPanel?.SetLoaded(false);
}
+
+ ReloadCharacterUI();
+ }
+
+ public void UpdateProfile(HumanoidCharacterProfile? profile)
+ {
+ if (_profile?.Equals(profile) == true)
+ return;
+
+ if (_stateManager.CurrentState is not LobbyState)
+ return;
+
+ _profile = profile;
+ }
+
+ private EntityUid EnsurePreviewDummy(HumanoidCharacterProfile profile)
+ {
+ if (_previewDummy != null)
+ return _previewDummy.Value;
+
+ _previewDummy = EntityManager.SpawnEntity(_prototypeManager.Index<SpeciesPrototype>(profile.Species).DollPrototype, MapCoordinates.Nullspace);
+ PreviewDummyUpdated?.Invoke(_previewDummy.Value);
+ return _previewDummy.Value;
}
/// <summary>
UpdateUI();
}
+ public void UpdateControls()
+ {
+ // Reset sliders etc. upon going going back to GUI.
+ _humanoidProfileEditor.LoadServerData();
+ }
+
private void UpdateUI()
{
- UserInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
var numberOfFullSlots = 0;
var characterButtonsGroup = new ButtonGroup();
Characters.RemoveAllChildren();
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithHairStyleName(newStyle.id));
- IsDirty = true;
+ SetDirty();
};
_hairPicker.OnColorChanged += newColor =>
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithHairColor(newColor.marking.MarkingColors[0]));
UpdateCMarkingsHair();
- IsDirty = true;
+ SetDirty();
};
_facialHairPicker.OnMarkingSelect += newStyle =>
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithFacialHairStyleName(newStyle.id));
- IsDirty = true;
+ SetDirty();
};
_facialHairPicker.OnColorChanged += newColor =>
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithFacialHairColor(newColor.marking.MarkingColors[0]));
UpdateCMarkingsFacialHair();
- IsDirty = true;
+ SetDirty();
};
_hairPicker.OnSlotRemove += _ =>
);
UpdateHairPickers();
UpdateCMarkingsHair();
- IsDirty = true;
+ SetDirty();
};
_facialHairPicker.OnSlotRemove += _ =>
);
UpdateHairPickers();
UpdateCMarkingsFacialHair();
- IsDirty = true;
+ SetDirty();
};
_hairPicker.OnSlotAdd += delegate()
UpdateHairPickers();
UpdateCMarkingsHair();
- IsDirty = true;
+ SetDirty();
};
_facialHairPicker.OnSlotAdd += delegate()
UpdateHairPickers();
UpdateCMarkingsFacialHair();
- IsDirty = true;
+ SetDirty();
};
#endregion Hair
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithEyeColor(newColor));
CMarkings.CurrentEyeColor = Profile.Appearance.EyeColor;
- IsDirty = true;
+ SetDirty();
};
#endregion Eyes
_preferenceUnavailableButton.SelectId(args.Id);
Profile = Profile?.WithPreferenceUnavailable((PreferenceUnavailableMode) args.Id);
- IsDirty = true;
+ SetDirty();
};
_jobPriorities = new List<JobPrioritySelector>();
selector.PreferenceChanged += preference =>
{
Profile = Profile?.WithTraitPreference(trait.ID, preference);
- IsDirty = true;
+ SetDirty();
};
}
}
LoadServerData();
}
+ ShowClothes.OnToggled += args =>
+ {
+ var lobby = UserInterfaceManager.GetUIController<LobbyUIController>();
+ lobby.SetClothes(args.Pressed);
+ SetDirty();
+ };
+
preferencesManager.OnServerDataLoaded += LoadServerData;
SpeciesInfoButton.OnPressed += OnSpeciesInfoButtonPressed;
UpdateSpeciesGuidebookIcon();
IsDirty = false;
+ controller.UpdateProfile();
+ }
+
+ private void SetDirty()
+ {
+ var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
+ controller.UpdateProfile(Profile);
+ controller.ReloadCharacterUI();
+ IsDirty = true;
}
private void OnSpeciesInfoButtonPressed(BaseButton.ButtonEventArgs args)
if (selector.Disabled)
{
Profile = Profile?.WithAntagPreference(antag.ID, false);
- IsDirty = true;
+ SetDirty();
}
selector.PreferenceChanged += preference =>
{
Profile = Profile?.WithAntagPreference(antag.ID, preference);
- IsDirty = true;
+ SetDirty();
};
}
foreach (var job in jobs)
{
RoleLoadout? loadout = null;
+
+ // Clone so we don't modify the underlying loadout.
Profile?.Loadouts.TryGetValue(LoadoutSystem.GetJobPrototype(job.ID), out loadout);
+ loadout = loadout?.Clone();
var selector = new JobPrioritySelector(loadout, job, jobLoadoutGroup, _prototypeManager)
{
Margin = new Thickness(3f, 3f, 3f, 0f),
selector.LoadoutUpdated += args =>
{
- Profile?.SetLoadout(args);
- UserInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
- IsDirty = true;
+ Profile = Profile?.WithLoadout(args);
+ SetDirty();
};
selector.PriorityChanged += priority =>
{
Profile = Profile?.WithJobPriority(job.ID, priority);
- IsDirty = true;
foreach (var jobSelector in _jobPriorities)
{
Profile = Profile?.WithJobPriority(jobSelector.Proto.ID, JobPriority.Medium);
}
}
+
+ SetDirty();
};
}
return;
Profile = Profile.WithFlavorText(content);
- IsDirty = true;
+ SetDirty();
}
private void OnMarkingChange(MarkingSet markings)
return;
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithMarkings(markings.GetForwardEnumerator().ToList()));
- UpdatePreview();
IsDirty = true;
+ var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
+ controller.UpdateProfile(Profile);
+ controller.ReloadProfile();
}
private void OnSkinColorOnValueChanged()
}
IsDirty = true;
+ var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
+ controller.UpdateProfile(Profile);
+ controller.ReloadProfile();
}
protected override void Dispose(bool disposing)
_preferencesManager.OnServerDataLoaded -= LoadServerData;
}
- private void LoadServerData()
+ public void LoadServerData()
{
Profile = (HumanoidCharacterProfile) _preferencesManager.Preferences!.SelectedCharacter;
CharacterSlot = _preferencesManager.Preferences.SelectedCharacterIndex;
UpdateAntagRequirements();
UpdateRoleRequirements();
UpdateControls();
+ ShowClothes.Pressed = true;
}
private void SetAge(int newAge)
{
Profile = Profile?.WithAge(newAge);
- IsDirty = true;
+ SetDirty();
}
private void SetSex(Sex newSex)
}
UpdateGenderControls();
CMarkings.SetSex(newSex);
- IsDirty = true;
+ SetDirty();
}
private void SetGender(Gender newGender)
{
Profile = Profile?.WithGender(newGender);
- IsDirty = true;
+ SetDirty();
}
private void SetSpecies(string newSpecies)
CMarkings.SetSpecies(newSpecies); // Repopulate the markings tab as well.
UpdateSexControls(); // update sex for new species
UpdateSpeciesGuidebookIcon();
- IsDirty = true;
+ SetDirty();
UpdatePreview();
}
private void SetName(string newName)
{
Profile = Profile?.WithName(newName);
- IsDirty = true;
+ SetDirty();
}
private void SetSpawnPriority(SpawnPriorityPreference newSpawnPriority)
{
Profile = Profile?.WithSpawnPriorityPreference(newSpawnPriority);
- IsDirty = true;
+ SetDirty();
}
public void Save()
_preferencesManager.UpdateCharacter(Profile, CharacterSlot);
OnProfileChanged?.Invoke(Profile, CharacterSlot);
+ // Reset profile to default.
+ UserInterfaceManager.GetUIController<LobbyUIController>().UpdateProfile();
}
private bool IsDirty
if (Profile is null)
return;
- UserInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
+ UserInterfaceManager.GetUIController<LobbyUIController>().ReloadProfile();
SetPreviewRotation(_previewRotation);
}
_loadout.EnsureValid(session, collection);
_loadoutWindow.RefreshLoadouts(_loadout, session, collection);
var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
- controller.UpdateCharacterUI();
+ controller.ReloadProfile();
LoadoutUpdated?.Invoke(_loadout);
};
_loadout.EnsureValid(session, collection);
_loadoutWindow.RefreshLoadouts(_loadout, session, collection);
var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
- controller.UpdateCharacterUI();
+ controller.ReloadProfile();
LoadoutUpdated?.Invoke(_loadout);
};
list.Remove(antagId);
}
}
+
return new(this, _jobPriorities, list, _traitPreferences, _loadouts);
}
_loadouts[loadout.Role.Id] = loadout;
}
+ public HumanoidCharacterProfile WithLoadout(RoleLoadout loadout)
+ {
+ // Deep copies so we don't modify the DB profile.
+ var copied = new Dictionary<string, RoleLoadout>();
+
+ foreach (var proto in _loadouts)
+ {
+ if (proto.Key == loadout.Role)
+ continue;
+
+ copied[proto.Key] = proto.Value.Clone();
+ }
+
+ copied[loadout.Role] = loadout.Clone();
+ return new(this, _jobPriorities, _antagPreferences, _traitPreferences, copied);
+ }
+
public RoleLoadout GetLoadoutOrDefault(string id, IEntityManager entManager, IPrototypeManager protoManager)
{
if (!_loadouts.TryGetValue(id, out var loadout))
Role = role;
}
+ public RoleLoadout Clone()
+ {
+ var weh = new RoleLoadout(Role);
+
+ foreach (var selected in SelectedLoadouts)
+ {
+ weh.SelectedLoadouts.Add(selected.Key, new List<Loadout>(selected.Value));
+ }
+
+ return weh;
+ }
+
/// <summary>
/// Ensures all prototypes exist and effects can be applied.
/// </summary>