Rework options menu.
It's much nicer now.
This commit is contained in:
@@ -21,6 +21,17 @@
|
|||||||
<ProjectReference Include="..\RobustToolbox\Robust.Client\Robust.Client.csproj" />
|
<ProjectReference Include="..\RobustToolbox\Robust.Client\Robust.Client.csproj" />
|
||||||
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj" />
|
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="UserInterface\OptionsMenu.Graphics.cs">
|
||||||
|
<DependentUpon>OptionsMenu.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="UserInterface\OptionsMenu.KeyRebind.cs">
|
||||||
|
<DependentUpon>OptionsMenu.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="UserInterface\OptionsMenu.Audio.cs">
|
||||||
|
<DependentUpon>OptionsMenu.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="..\RobustToolbox\MSBuild\Robust.Engine.targets" />
|
<Import Project="..\RobustToolbox\MSBuild\Robust.Engine.targets" />
|
||||||
<Target Name="ContentAfterBuild" DependsOnTargets="ClientAfterBuild" AfterTargets="Build" />
|
<Target Name="ContentAfterBuild" DependsOnTargets="ClientAfterBuild" AfterTargets="Build" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,29 +2,19 @@
|
|||||||
using Content.Client.UserInterface;
|
using Content.Client.UserInterface;
|
||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
using Robust.Client.Interfaces.Input;
|
using Robust.Client.Interfaces.Input;
|
||||||
using Robust.Client.Interfaces.Placement;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.Interfaces.State;
|
using Robust.Client.Interfaces.State;
|
||||||
using Robust.Shared.Input;
|
using Robust.Shared.Input;
|
||||||
using Robust.Shared.Input.Binding;
|
using Robust.Shared.Input.Binding;
|
||||||
using Robust.Shared.Interfaces.Configuration;
|
|
||||||
using Robust.Shared.Interfaces.Map;
|
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client
|
namespace Content.Client
|
||||||
{
|
{
|
||||||
internal sealed class EscapeMenuOwner : IEscapeMenuOwner
|
internal sealed class EscapeMenuOwner : IEscapeMenuOwner
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IClientConsole _clientConsole = default!;
|
[Dependency] private readonly IClientConsole _clientConsole = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
|
||||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||||
[Dependency] private readonly IPlacementManager _placementManager = default!;
|
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
|
||||||
[Dependency] private readonly IStateManager _stateManager = default!;
|
[Dependency] private readonly IStateManager _stateManager = default!;
|
||||||
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
|
|
||||||
[Dependency] private readonly IGameHud _gameHud = default!;
|
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
||||||
|
|
||||||
@@ -42,8 +32,7 @@ namespace Content.Client
|
|||||||
if (obj.NewState is GameScreenBase)
|
if (obj.NewState is GameScreenBase)
|
||||||
{
|
{
|
||||||
// Switched TO GameScreen.
|
// Switched TO GameScreen.
|
||||||
_escapeMenu = new EscapeMenu(_clientConsole, _tileDefinitionManager, _placementManager,
|
_escapeMenu = new EscapeMenu(_clientConsole, _localizationManager);
|
||||||
_prototypeManager, _resourceCache, _configurationManager, _localizationManager);
|
|
||||||
|
|
||||||
_escapeMenu.OnClose += () => _gameHud.EscapeButtonDown = false;
|
_escapeMenu.OnClose += () => _gameHud.EscapeButtonDown = false;
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Content.Client.State
|
|||||||
|
|
||||||
_client.RunLevelChanged += RunLevelChanged;
|
_client.RunLevelChanged += RunLevelChanged;
|
||||||
|
|
||||||
OptionsMenu = new OptionsMenu(_configurationManager);
|
OptionsMenu = new OptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1,24 +1,14 @@
|
|||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
using Robust.Client.Interfaces.Placement;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Interfaces.Configuration;
|
|
||||||
using Robust.Shared.Interfaces.Map;
|
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
namespace Content.Client.UserInterface
|
||||||
{
|
{
|
||||||
internal sealed class EscapeMenu : SS14Window
|
internal sealed class EscapeMenu : SS14Window
|
||||||
{
|
{
|
||||||
private readonly IClientConsole _console;
|
private readonly IClientConsole _console;
|
||||||
private readonly ITileDefinitionManager _tileDefinitionManager;
|
|
||||||
private readonly IPlacementManager _placementManager;
|
|
||||||
private readonly IPrototypeManager _prototypeManager;
|
|
||||||
private readonly IResourceCache _resourceCache;
|
|
||||||
private readonly IConfigurationManager _configSystem;
|
|
||||||
private readonly ILocalizationManager _localizationManager;
|
private readonly ILocalizationManager _localizationManager;
|
||||||
|
|
||||||
private BaseButton DisconnectButton;
|
private BaseButton DisconnectButton;
|
||||||
@@ -26,20 +16,10 @@ namespace Content.Client.UserInterface
|
|||||||
private BaseButton OptionsButton;
|
private BaseButton OptionsButton;
|
||||||
private OptionsMenu optionsMenu;
|
private OptionsMenu optionsMenu;
|
||||||
|
|
||||||
public EscapeMenu(IClientConsole console,
|
public EscapeMenu(IClientConsole console, ILocalizationManager localizationManager)
|
||||||
ITileDefinitionManager tileDefinitionManager,
|
|
||||||
IPlacementManager placementManager,
|
|
||||||
IPrototypeManager prototypeManager,
|
|
||||||
IResourceCache resourceCache,
|
|
||||||
IConfigurationManager configSystem, ILocalizationManager localizationManager)
|
|
||||||
{
|
{
|
||||||
_configSystem = configSystem;
|
|
||||||
_localizationManager = localizationManager;
|
_localizationManager = localizationManager;
|
||||||
_console = console;
|
_console = console;
|
||||||
_tileDefinitionManager = tileDefinitionManager;
|
|
||||||
_placementManager = placementManager;
|
|
||||||
_prototypeManager = prototypeManager;
|
|
||||||
_resourceCache = resourceCache;
|
|
||||||
|
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
@@ -48,7 +28,7 @@ namespace Content.Client.UserInterface
|
|||||||
|
|
||||||
private void PerformLayout()
|
private void PerformLayout()
|
||||||
{
|
{
|
||||||
optionsMenu = new OptionsMenu(_configSystem);
|
optionsMenu = new OptionsMenu();
|
||||||
|
|
||||||
Resizable = false;
|
Resizable = false;
|
||||||
|
|
||||||
@@ -95,10 +75,5 @@ namespace Content.Client.UserInterface
|
|||||||
optionsMenu.Dispose();
|
optionsMenu.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
|
||||||
{
|
|
||||||
base.Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
Content.Client/UserInterface/KeyRebindControl.cs
Normal file
19
Content.Client/UserInterface/KeyRebindControl.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Client.UserInterface.Stylesheets;
|
||||||
|
using Content.Shared.Input;
|
||||||
|
using Robust.Client.Input;
|
||||||
|
using Robust.Client.Interfaces.Input;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,468 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.UserInterface.Stylesheets;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.Input;
|
|
||||||
using Robust.Client.Interfaces.Console;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
|
||||||
{
|
|
||||||
[UsedImplicitly]
|
|
||||||
public sealed class RebindCommand : IConsoleCommand
|
|
||||||
{
|
|
||||||
public string Command => "rebind";
|
|
||||||
public string Description => "";
|
|
||||||
public string Help => "";
|
|
||||||
|
|
||||||
public bool Execute(IDebugConsole console, params string[] args)
|
|
||||||
{
|
|
||||||
new KeyRebindWindow().OpenCentered();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class KeyRebindWindow : SS14Window
|
|
||||||
{
|
|
||||||
// List of key functions that must be registered as toggle instead.
|
|
||||||
private static readonly HashSet<BoundKeyFunction> ToggleFunctions = new HashSet<BoundKeyFunction>
|
|
||||||
{
|
|
||||||
EngineKeyFunctions.ShowDebugMonitors,
|
|
||||||
EngineKeyFunctions.HideUI,
|
|
||||||
};
|
|
||||||
|
|
||||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
|
||||||
|
|
||||||
private BindButton? _currentlyRebinding;
|
|
||||||
|
|
||||||
private readonly Dictionary<BoundKeyFunction, KeyControl> _keyControls =
|
|
||||||
new Dictionary<BoundKeyFunction, KeyControl>();
|
|
||||||
|
|
||||||
private readonly List<Action> _deferCommands = new List<Action>();
|
|
||||||
|
|
||||||
public KeyRebindWindow()
|
|
||||||
{
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
Title = Loc.GetString("Controls");
|
|
||||||
|
|
||||||
CustomMinimumSize = (800, 400);
|
|
||||||
|
|
||||||
Button resetAllButton;
|
|
||||||
var vBox = new VBoxContainer();
|
|
||||||
Contents.AddChild(new VBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new ScrollContainer
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
Children = {vBox}
|
|
||||||
},
|
|
||||||
|
|
||||||
new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Label
|
|
||||||
{
|
|
||||||
StyleClasses = {StyleBase.StyleClassLabelSubText},
|
|
||||||
Text = "Click to change binding, right-click to clear"
|
|
||||||
},
|
|
||||||
(resetAllButton = new Button
|
|
||||||
{
|
|
||||||
Text = "Reset ALL keybinds",
|
|
||||||
StyleClasses = {StyleBase.ButtonCaution},
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Expand
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
resetAllButton.OnPressed += args =>
|
|
||||||
{
|
|
||||||
_deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
_inputManager.ResetAllBindings();
|
|
||||||
_inputManager.SaveToUserData();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
void AddHeader(string headerContents)
|
|
||||||
{
|
|
||||||
vBox.AddChild(new Control {CustomMinimumSize = (0, 8)});
|
|
||||||
vBox.AddChild(new Label
|
|
||||||
{
|
|
||||||
Text = headerContents,
|
|
||||||
FontColorOverride = StyleNano.NanoGold,
|
|
||||||
StyleClasses = {StyleNano.StyleClassLabelKeyText}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddButton(BoundKeyFunction function, string name)
|
|
||||||
{
|
|
||||||
var control = new KeyControl(this, name, function);
|
|
||||||
vBox.AddChild(control);
|
|
||||||
_keyControls.Add(function, control);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddHeader("Movement");
|
|
||||||
AddButton(EngineKeyFunctions.MoveUp, "Move up");
|
|
||||||
AddButton(EngineKeyFunctions.MoveLeft, "Move left");
|
|
||||||
AddButton(EngineKeyFunctions.MoveDown, "Move down");
|
|
||||||
AddButton(EngineKeyFunctions.MoveRight, "Move right");
|
|
||||||
AddButton(EngineKeyFunctions.Walk, "Walk");
|
|
||||||
|
|
||||||
AddHeader("Basic Interaction");
|
|
||||||
AddButton(EngineKeyFunctions.Use, "Use");
|
|
||||||
AddButton(ContentKeyFunctions.WideAttack, "Wide attack");
|
|
||||||
AddButton(ContentKeyFunctions.ActivateItemInHand, "Activate item in hand");
|
|
||||||
AddButton(ContentKeyFunctions.ActivateItemInWorld, "Activate item in world");
|
|
||||||
AddButton(ContentKeyFunctions.Drop, "Drop item");
|
|
||||||
AddButton(ContentKeyFunctions.ExamineEntity, "Examine");
|
|
||||||
AddButton(ContentKeyFunctions.SwapHands, "Swap hands");
|
|
||||||
AddButton(ContentKeyFunctions.ToggleCombatMode, "Toggle combat mode");
|
|
||||||
|
|
||||||
AddHeader("Advanced Interaction");
|
|
||||||
AddButton(ContentKeyFunctions.SmartEquipBackpack, "Smart-equip to backpack");
|
|
||||||
AddButton(ContentKeyFunctions.SmartEquipBelt, "Smart-equip to belt");
|
|
||||||
AddButton(ContentKeyFunctions.ThrowItemInHand, "Throw item");
|
|
||||||
AddButton(ContentKeyFunctions.TryPullObject, "Pull object");
|
|
||||||
AddButton(ContentKeyFunctions.MovePulledObject, "Move pulled object");
|
|
||||||
AddButton(ContentKeyFunctions.Point, "Point at location");
|
|
||||||
|
|
||||||
|
|
||||||
AddHeader("User Interface");
|
|
||||||
AddButton(ContentKeyFunctions.FocusChat, "Focus chat");
|
|
||||||
AddButton(ContentKeyFunctions.FocusOOC, "Focus chat (OOC)");
|
|
||||||
AddButton(ContentKeyFunctions.FocusAdminChat, "Focus chat (admin)");
|
|
||||||
AddButton(ContentKeyFunctions.OpenCharacterMenu, "Open character menu");
|
|
||||||
AddButton(ContentKeyFunctions.OpenContextMenu, "Open context menu");
|
|
||||||
AddButton(ContentKeyFunctions.OpenCraftingMenu, "Open crafting menu");
|
|
||||||
AddButton(ContentKeyFunctions.OpenInventoryMenu, "Open inventory");
|
|
||||||
AddButton(ContentKeyFunctions.OpenTutorial, "Open tutorial");
|
|
||||||
AddButton(ContentKeyFunctions.OpenEntitySpawnWindow, "Open entity spawn menu");
|
|
||||||
AddButton(ContentKeyFunctions.OpenSandboxWindow, "Open sandbox menu");
|
|
||||||
AddButton(ContentKeyFunctions.OpenTileSpawnWindow, "Open tile spawn menu");
|
|
||||||
AddButton(ContentKeyFunctions.OpenAdminMenu, "Open admin menu");
|
|
||||||
|
|
||||||
AddHeader("Miscellaneous");
|
|
||||||
AddButton(ContentKeyFunctions.TakeScreenshot, "Take screenshot");
|
|
||||||
AddButton(ContentKeyFunctions.TakeScreenshotNoUI, "Take screenshot (without UI)");
|
|
||||||
|
|
||||||
AddHeader("Map Editor");
|
|
||||||
AddButton(EngineKeyFunctions.EditorPlaceObject, "Place object");
|
|
||||||
AddButton(EngineKeyFunctions.EditorCancelPlace, "Cancel placement");
|
|
||||||
AddButton(EngineKeyFunctions.EditorGridPlace, "Place in grid");
|
|
||||||
AddButton(EngineKeyFunctions.EditorLinePlace, "Place line");
|
|
||||||
AddButton(EngineKeyFunctions.EditorRotateObject, "Rotate");
|
|
||||||
|
|
||||||
AddHeader("Development");
|
|
||||||
AddButton(EngineKeyFunctions.ShowDebugConsole, "Open Console");
|
|
||||||
AddButton(EngineKeyFunctions.ShowDebugMonitors, "Show Debug Monitors");
|
|
||||||
AddButton(EngineKeyFunctions.HideUI, "Hide UI");
|
|
||||||
|
|
||||||
foreach (var control in _keyControls.Values)
|
|
||||||
{
|
|
||||||
UpdateKeyControl(control);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateKeyControl(KeyControl control)
|
|
||||||
{
|
|
||||||
var activeBinds = _inputManager.GetKeyBindings(control.Function);
|
|
||||||
|
|
||||||
IKeyBinding? bind1 = null;
|
|
||||||
IKeyBinding? bind2 = null;
|
|
||||||
|
|
||||||
if (activeBinds.Count > 0)
|
|
||||||
{
|
|
||||||
bind1 = activeBinds[0];
|
|
||||||
|
|
||||||
if (activeBinds.Count > 1)
|
|
||||||
{
|
|
||||||
bind2 = activeBinds[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
control.BindButton1.Binding = bind1;
|
|
||||||
control.BindButton1.UpdateText();
|
|
||||||
|
|
||||||
control.BindButton2.Binding = bind2;
|
|
||||||
control.BindButton2.UpdateText();
|
|
||||||
|
|
||||||
control.BindButton2.Button.Disabled = activeBinds.Count == 0;
|
|
||||||
control.ResetButton.Disabled = !_inputManager.IsKeyFunctionModified(control.Function);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Opened()
|
|
||||||
{
|
|
||||||
base.Opened();
|
|
||||||
|
|
||||||
_inputManager.FirstChanceOnKeyEvent += InputManagerOnFirstChanceOnKeyEvent;
|
|
||||||
_inputManager.OnKeyBindingAdded += OnKeyBindAdded;
|
|
||||||
_inputManager.OnKeyBindingRemoved += OnKeyBindRemoved;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Close()
|
|
||||||
{
|
|
||||||
base.Close();
|
|
||||||
|
|
||||||
_inputManager.FirstChanceOnKeyEvent -= InputManagerOnFirstChanceOnKeyEvent;
|
|
||||||
_inputManager.OnKeyBindingAdded -= OnKeyBindAdded;
|
|
||||||
_inputManager.OnKeyBindingRemoved -= OnKeyBindRemoved;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnKeyBindRemoved(IKeyBinding obj)
|
|
||||||
{
|
|
||||||
OnKeyBindModified(obj, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnKeyBindAdded(IKeyBinding obj)
|
|
||||||
{
|
|
||||||
OnKeyBindModified(obj, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnKeyBindModified(IKeyBinding bind, bool removal)
|
|
||||||
{
|
|
||||||
if (!_keyControls.TryGetValue(bind.Function, out var keyControl))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removal && _currentlyRebinding?.KeyControl == keyControl)
|
|
||||||
{
|
|
||||||
// Don't do update if the removal was from initiating a rebind.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateKeyControl(keyControl);
|
|
||||||
|
|
||||||
if (_currentlyRebinding == keyControl.BindButton1 || _currentlyRebinding == keyControl.BindButton2)
|
|
||||||
{
|
|
||||||
_currentlyRebinding = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InputManagerOnFirstChanceOnKeyEvent(KeyEventArgs keyEvent, KeyEventType type)
|
|
||||||
{
|
|
||||||
DebugTools.Assert(IsOpen);
|
|
||||||
|
|
||||||
if (_currentlyRebinding == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
keyEvent.Handle();
|
|
||||||
|
|
||||||
if (type != KeyEventType.Up)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var key = keyEvent.Key;
|
|
||||||
|
|
||||||
// Figure out modifiers based on key event.
|
|
||||||
// TODO: this won't allow for combinations with keys other than the standard modifier keys,
|
|
||||||
// even though the input system totally supports it.
|
|
||||||
var mods = new Keyboard.Key[3];
|
|
||||||
var i = 0;
|
|
||||||
if (keyEvent.Control && key != Keyboard.Key.Control)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.Control;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyEvent.Shift && key != Keyboard.Key.Shift)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.Shift;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyEvent.Alt && key != Keyboard.Key.Alt)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.Alt;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The input system can only handle 3 modifier keys so if you hold all 4 of the modifier keys
|
|
||||||
// then system gets the shaft, I guess.
|
|
||||||
if (keyEvent.System && i != 3 && key != Keyboard.Key.LSystem && key != Keyboard.Key.RSystem)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.LSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
var function = _currentlyRebinding.KeyControl.Function;
|
|
||||||
var bindType = KeyBindingType.State;
|
|
||||||
if (ToggleFunctions.Contains(function))
|
|
||||||
{
|
|
||||||
bindType = KeyBindingType.Toggle;
|
|
||||||
}
|
|
||||||
|
|
||||||
var registration = new KeyBindingRegistration
|
|
||||||
{
|
|
||||||
Function = function,
|
|
||||||
BaseKey = key,
|
|
||||||
Mod1 = mods[0],
|
|
||||||
Mod2 = mods[1],
|
|
||||||
Mod3 = mods[2],
|
|
||||||
Priority = 0,
|
|
||||||
Type = bindType,
|
|
||||||
CanFocus = key == Keyboard.Key.MouseLeft
|
|
||||||
|| key == Keyboard.Key.MouseRight
|
|
||||||
|| key == Keyboard.Key.MouseMiddle,
|
|
||||||
CanRepeat = false
|
|
||||||
};
|
|
||||||
|
|
||||||
_inputManager.RegisterBinding(registration);
|
|
||||||
// OnKeyBindModified will cause _currentlyRebinding to be reset and the UI to update.
|
|
||||||
_inputManager.SaveToUserData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RebindButtonPressed(BindButton button)
|
|
||||||
{
|
|
||||||
if (_currentlyRebinding != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentlyRebinding = button;
|
|
||||||
_currentlyRebinding.Button.Text = Loc.GetString("Press a key...");
|
|
||||||
|
|
||||||
if (button.Binding != null)
|
|
||||||
{
|
|
||||||
_deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
// Have to do defer this or else there will be an exception in InputManager.
|
|
||||||
// Because this IS fired from an input event.
|
|
||||||
_inputManager.RemoveBinding(button.Binding);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void FrameUpdate(FrameEventArgs args)
|
|
||||||
{
|
|
||||||
base.FrameUpdate(args);
|
|
||||||
|
|
||||||
if (_deferCommands.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var command in _deferCommands)
|
|
||||||
{
|
|
||||||
command();
|
|
||||||
}
|
|
||||||
|
|
||||||
_deferCommands.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class KeyControl : Control
|
|
||||||
{
|
|
||||||
private readonly KeyRebindWindow _window;
|
|
||||||
public readonly BoundKeyFunction Function;
|
|
||||||
public readonly BindButton BindButton1;
|
|
||||||
public readonly BindButton BindButton2;
|
|
||||||
public readonly Button ResetButton;
|
|
||||||
|
|
||||||
public KeyControl(KeyRebindWindow window, string niceName, BoundKeyFunction function)
|
|
||||||
{
|
|
||||||
Function = function;
|
|
||||||
_window = window;
|
|
||||||
var name = new Label
|
|
||||||
{
|
|
||||||
Text = Loc.GetString(niceName),
|
|
||||||
SizeFlagsHorizontal = SizeFlags.Expand
|
|
||||||
};
|
|
||||||
|
|
||||||
BindButton1 = new BindButton(window, this, StyleBase.ButtonOpenRight);
|
|
||||||
BindButton2 = new BindButton(window, this, StyleBase.ButtonOpenLeft);
|
|
||||||
ResetButton = new Button {Text = "Reset", StyleClasses = {StyleBase.ButtonCaution}};
|
|
||||||
|
|
||||||
var hBox = new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Control {CustomMinimumSize = (5, 0)},
|
|
||||||
name,
|
|
||||||
BindButton1,
|
|
||||||
BindButton2,
|
|
||||||
new Control {CustomMinimumSize = (10, 0)},
|
|
||||||
ResetButton
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ResetButton.OnPressed += args =>
|
|
||||||
{
|
|
||||||
_window._deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
_window._inputManager.ResetBindingsFor(function);
|
|
||||||
_window._inputManager.SaveToUserData();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
AddChild(hBox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class BindButton : Control
|
|
||||||
{
|
|
||||||
private readonly KeyRebindWindow _window;
|
|
||||||
public readonly KeyControl KeyControl;
|
|
||||||
public readonly Button Button;
|
|
||||||
public IKeyBinding? Binding;
|
|
||||||
|
|
||||||
public BindButton(KeyRebindWindow window, KeyControl keyControl, string styleClass)
|
|
||||||
{
|
|
||||||
_window = window;
|
|
||||||
KeyControl = keyControl;
|
|
||||||
Button = new Button {StyleClasses = {styleClass}};
|
|
||||||
UpdateText();
|
|
||||||
AddChild(Button);
|
|
||||||
|
|
||||||
Button.OnPressed += args =>
|
|
||||||
{
|
|
||||||
window.RebindButtonPressed(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Button.OnKeyBindDown += ButtonOnOnKeyBindDown;
|
|
||||||
|
|
||||||
CustomMinimumSize = (200, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ButtonOnOnKeyBindDown(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Function == EngineKeyFunctions.UIRightClick)
|
|
||||||
{
|
|
||||||
if (Binding != null)
|
|
||||||
{
|
|
||||||
_window._deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
_window._inputManager.RemoveBinding(Binding);
|
|
||||||
_window._inputManager.SaveToUserData();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateText()
|
|
||||||
{
|
|
||||||
Button.Text = Binding?.GetKeyString() ?? "Unbound";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
21
Content.Client/UserInterface/OptionsMenu.Audio.cs
Normal file
21
Content.Client/UserInterface/OptionsMenu.Audio.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using Robust.Client.Interfaces.ResourceManagement;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Shared.Interfaces.Configuration;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface
|
||||||
|
{
|
||||||
|
public sealed partial class OptionsMenu
|
||||||
|
{
|
||||||
|
private sealed class AudioControl : Control
|
||||||
|
{
|
||||||
|
public AudioControl(IConfigurationManager cfg)
|
||||||
|
{
|
||||||
|
AddChild(new Placeholder(IoCManager.Resolve<IResourceCache>())
|
||||||
|
{
|
||||||
|
PlaceholderText = "Pretend there's a bunch of volume sliders here."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
185
Content.Client/UserInterface/OptionsMenu.Graphics.cs
Normal file
185
Content.Client/UserInterface/OptionsMenu.Graphics.cs
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Interfaces.ResourceManagement;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Shared.Interfaces.Configuration;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface
|
||||||
|
{
|
||||||
|
public sealed partial class OptionsMenu
|
||||||
|
{
|
||||||
|
private sealed class GraphicsControl : Control
|
||||||
|
{
|
||||||
|
private readonly IConfigurationManager _cfg;
|
||||||
|
|
||||||
|
private readonly Button ApplyButton;
|
||||||
|
private readonly CheckBox VSyncCheckBox;
|
||||||
|
private readonly CheckBox FullscreenCheckBox;
|
||||||
|
private readonly OptionButton LightingPresetOption;
|
||||||
|
|
||||||
|
|
||||||
|
public GraphicsControl(IConfigurationManager cfg)
|
||||||
|
{
|
||||||
|
_cfg = cfg;
|
||||||
|
var vBox = new VBoxContainer();
|
||||||
|
|
||||||
|
var contents = new VBoxContainer();
|
||||||
|
|
||||||
|
VSyncCheckBox = new CheckBox {Text = Loc.GetString("VSync")};
|
||||||
|
contents.AddChild(VSyncCheckBox);
|
||||||
|
VSyncCheckBox.OnToggled += OnCheckBoxToggled;
|
||||||
|
|
||||||
|
FullscreenCheckBox = new CheckBox {Text = Loc.GetString("Fullscreen")};
|
||||||
|
contents.AddChild(FullscreenCheckBox);
|
||||||
|
FullscreenCheckBox.OnToggled += OnCheckBoxToggled;
|
||||||
|
|
||||||
|
LightingPresetOption = new OptionButton {CustomMinimumSize = (100, 0)};
|
||||||
|
LightingPresetOption.AddItem(Loc.GetString("Very Low"));
|
||||||
|
LightingPresetOption.AddItem(Loc.GetString("Low"));
|
||||||
|
LightingPresetOption.AddItem(Loc.GetString("Medium"));
|
||||||
|
LightingPresetOption.AddItem(Loc.GetString("High"));
|
||||||
|
LightingPresetOption.OnItemSelected += OnLightingQualityChanged;
|
||||||
|
|
||||||
|
var lightingHBox = new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new Label {Text = Loc.GetString("Lighting Quality:")},
|
||||||
|
new Control {CustomMinimumSize = (4, 0)},
|
||||||
|
LightingPresetOption
|
||||||
|
}
|
||||||
|
};
|
||||||
|
contents.AddChild(lightingHBox);
|
||||||
|
|
||||||
|
ApplyButton = new Button
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("Apply"), TextAlign = Label.AlignMode.Center,
|
||||||
|
SizeFlagsHorizontal = SizeFlags.ShrinkEnd
|
||||||
|
};
|
||||||
|
|
||||||
|
var resourceCache = IoCManager.Resolve<IResourceCache>();
|
||||||
|
|
||||||
|
contents.AddChild(new Placeholder(resourceCache)
|
||||||
|
{
|
||||||
|
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||||
|
PlaceholderText = "UI Scaling"
|
||||||
|
});
|
||||||
|
|
||||||
|
contents.AddChild(new Placeholder(resourceCache)
|
||||||
|
{
|
||||||
|
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||||
|
PlaceholderText = "Viewport settings"
|
||||||
|
});
|
||||||
|
|
||||||
|
vBox.AddChild(new MarginContainer
|
||||||
|
{
|
||||||
|
MarginLeftOverride = 2,
|
||||||
|
MarginTopOverride = 2,
|
||||||
|
MarginRightOverride = 2,
|
||||||
|
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
contents
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
vBox.AddChild(new StripeBack
|
||||||
|
{
|
||||||
|
HasBottomEdge = false,
|
||||||
|
HasMargins = false,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
ApplyButton
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ApplyButton.OnPressed += OnApplyButtonPressed;
|
||||||
|
|
||||||
|
VSyncCheckBox.Pressed = _cfg.GetCVar<bool>("display.vsync");
|
||||||
|
FullscreenCheckBox.Pressed = ConfigIsFullscreen;
|
||||||
|
LightingPresetOption.SelectId(GetConfigLightingQuality());
|
||||||
|
|
||||||
|
|
||||||
|
AddChild(vBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
|
||||||
|
{
|
||||||
|
_cfg.SetCVar("display.vsync", VSyncCheckBox.Pressed);
|
||||||
|
SetConfigLightingQuality(LightingPresetOption.SelectedId);
|
||||||
|
_cfg.SetCVar("display.windowmode",
|
||||||
|
(int) (FullscreenCheckBox.Pressed ? WindowMode.Fullscreen : WindowMode.Windowed));
|
||||||
|
_cfg.SaveToFile();
|
||||||
|
UpdateApplyButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCheckBoxToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
|
{
|
||||||
|
UpdateApplyButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLightingQualityChanged(OptionButton.ItemSelectedEventArgs args)
|
||||||
|
{
|
||||||
|
LightingPresetOption.SelectId(args.Id);
|
||||||
|
UpdateApplyButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateApplyButton()
|
||||||
|
{
|
||||||
|
var isVSyncSame = VSyncCheckBox.Pressed == _cfg.GetCVar<bool>("display.vsync");
|
||||||
|
var isFullscreenSame = FullscreenCheckBox.Pressed == ConfigIsFullscreen;
|
||||||
|
var isLightingQualitySame = LightingPresetOption.SelectedId == GetConfigLightingQuality();
|
||||||
|
ApplyButton.Disabled = isVSyncSame && isFullscreenSame && isLightingQualitySame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ConfigIsFullscreen =>
|
||||||
|
_cfg.GetCVar<int>("display.windowmode") == (int) WindowMode.Fullscreen;
|
||||||
|
|
||||||
|
private int GetConfigLightingQuality()
|
||||||
|
{
|
||||||
|
var val = _cfg.GetCVar<int>("display.lightmapdivider");
|
||||||
|
var soft = _cfg.GetCVar<bool>("display.softshadows");
|
||||||
|
if (val >= 8)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ((val >= 2) && !soft)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (val >= 2)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetConfigLightingQuality(int value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
_cfg.SetCVar("display.lightmapdivider", 8);
|
||||||
|
_cfg.SetCVar("display.softshadows", false);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
_cfg.SetCVar("display.lightmapdivider", 2);
|
||||||
|
_cfg.SetCVar("display.softshadows", false);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
_cfg.SetCVar("display.lightmapdivider", 2);
|
||||||
|
_cfg.SetCVar("display.softshadows", true);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
_cfg.SetCVar("display.lightmapdivider", 1);
|
||||||
|
_cfg.SetCVar("display.softshadows", true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
473
Content.Client/UserInterface/OptionsMenu.KeyRebind.cs
Normal file
473
Content.Client/UserInterface/OptionsMenu.KeyRebind.cs
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Client.UserInterface.Stylesheets;
|
||||||
|
using Content.Shared.Input;
|
||||||
|
using Robust.Client.Input;
|
||||||
|
using Robust.Client.Interfaces.Input;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface
|
||||||
|
{
|
||||||
|
public sealed partial class OptionsMenu
|
||||||
|
{
|
||||||
|
private sealed class KeyRebindControl : Control
|
||||||
|
{
|
||||||
|
// List of key functions that must be registered as toggle instead.
|
||||||
|
private static readonly HashSet<BoundKeyFunction> ToggleFunctions = new HashSet<BoundKeyFunction>
|
||||||
|
{
|
||||||
|
EngineKeyFunctions.ShowDebugMonitors,
|
||||||
|
EngineKeyFunctions.HideUI,
|
||||||
|
};
|
||||||
|
|
||||||
|
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||||
|
|
||||||
|
private BindButton? _currentlyRebinding;
|
||||||
|
|
||||||
|
private readonly Dictionary<BoundKeyFunction, KeyControl> _keyControls =
|
||||||
|
new Dictionary<BoundKeyFunction, KeyControl>();
|
||||||
|
|
||||||
|
private readonly List<Action> _deferCommands = new List<Action>();
|
||||||
|
|
||||||
|
public KeyRebindControl()
|
||||||
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
|
Button resetAllButton;
|
||||||
|
var vBox = new VBoxContainer();
|
||||||
|
AddChild(new VBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new ScrollContainer
|
||||||
|
{
|
||||||
|
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new MarginContainer
|
||||||
|
{
|
||||||
|
MarginLeftOverride = 2,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
vBox
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
new StripeBack
|
||||||
|
{
|
||||||
|
HasBottomEdge = false,
|
||||||
|
HasMargins = false,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new Control {CustomMinimumSize = (2, 0)},
|
||||||
|
new Label
|
||||||
|
{
|
||||||
|
StyleClasses = {StyleBase.StyleClassLabelSubText},
|
||||||
|
Text = "Click to change binding, right-click to clear"
|
||||||
|
},
|
||||||
|
(resetAllButton = new Button
|
||||||
|
{
|
||||||
|
Text = "Reset ALL keybinds",
|
||||||
|
StyleClasses = {StyleBase.ButtonCaution},
|
||||||
|
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Expand
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resetAllButton.OnPressed += args =>
|
||||||
|
{
|
||||||
|
_deferCommands.Add(() =>
|
||||||
|
{
|
||||||
|
_inputManager.ResetAllBindings();
|
||||||
|
_inputManager.SaveToUserData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var first = true;
|
||||||
|
|
||||||
|
void AddHeader(string headerContents)
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
{
|
||||||
|
vBox.AddChild(new Control {CustomMinimumSize = (0, 8)});
|
||||||
|
}
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
vBox.AddChild(new Label
|
||||||
|
{
|
||||||
|
Text = headerContents,
|
||||||
|
FontColorOverride = StyleNano.NanoGold,
|
||||||
|
StyleClasses = {StyleNano.StyleClassLabelKeyText}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddButton(BoundKeyFunction function, string name)
|
||||||
|
{
|
||||||
|
var control = new KeyControl(this, name, function);
|
||||||
|
vBox.AddChild(control);
|
||||||
|
_keyControls.Add(function, control);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddHeader("Movement");
|
||||||
|
AddButton(EngineKeyFunctions.MoveUp, "Move up");
|
||||||
|
AddButton(EngineKeyFunctions.MoveLeft, "Move left");
|
||||||
|
AddButton(EngineKeyFunctions.MoveDown, "Move down");
|
||||||
|
AddButton(EngineKeyFunctions.MoveRight, "Move right");
|
||||||
|
AddButton(EngineKeyFunctions.Walk, "Walk");
|
||||||
|
|
||||||
|
AddHeader("Basic Interaction");
|
||||||
|
AddButton(EngineKeyFunctions.Use, "Use");
|
||||||
|
AddButton(ContentKeyFunctions.WideAttack, "Wide attack");
|
||||||
|
AddButton(ContentKeyFunctions.ActivateItemInHand, "Activate item in hand");
|
||||||
|
AddButton(ContentKeyFunctions.ActivateItemInWorld, "Activate item in world");
|
||||||
|
AddButton(ContentKeyFunctions.Drop, "Drop item");
|
||||||
|
AddButton(ContentKeyFunctions.ExamineEntity, "Examine");
|
||||||
|
AddButton(ContentKeyFunctions.SwapHands, "Swap hands");
|
||||||
|
AddButton(ContentKeyFunctions.ToggleCombatMode, "Toggle combat mode");
|
||||||
|
|
||||||
|
AddHeader("Advanced Interaction");
|
||||||
|
AddButton(ContentKeyFunctions.SmartEquipBackpack, "Smart-equip to backpack");
|
||||||
|
AddButton(ContentKeyFunctions.SmartEquipBelt, "Smart-equip to belt");
|
||||||
|
AddButton(ContentKeyFunctions.ThrowItemInHand, "Throw item");
|
||||||
|
AddButton(ContentKeyFunctions.TryPullObject, "Pull object");
|
||||||
|
AddButton(ContentKeyFunctions.MovePulledObject, "Move pulled object");
|
||||||
|
AddButton(ContentKeyFunctions.Point, "Point at location");
|
||||||
|
|
||||||
|
|
||||||
|
AddHeader("User Interface");
|
||||||
|
AddButton(ContentKeyFunctions.FocusChat, "Focus chat");
|
||||||
|
AddButton(ContentKeyFunctions.FocusOOC, "Focus chat (OOC)");
|
||||||
|
AddButton(ContentKeyFunctions.FocusAdminChat, "Focus chat (admin)");
|
||||||
|
AddButton(ContentKeyFunctions.OpenCharacterMenu, "Open character menu");
|
||||||
|
AddButton(ContentKeyFunctions.OpenContextMenu, "Open context menu");
|
||||||
|
AddButton(ContentKeyFunctions.OpenCraftingMenu, "Open crafting menu");
|
||||||
|
AddButton(ContentKeyFunctions.OpenInventoryMenu, "Open inventory");
|
||||||
|
AddButton(ContentKeyFunctions.OpenTutorial, "Open tutorial");
|
||||||
|
AddButton(ContentKeyFunctions.OpenEntitySpawnWindow, "Open entity spawn menu");
|
||||||
|
AddButton(ContentKeyFunctions.OpenSandboxWindow, "Open sandbox menu");
|
||||||
|
AddButton(ContentKeyFunctions.OpenTileSpawnWindow, "Open tile spawn menu");
|
||||||
|
AddButton(ContentKeyFunctions.OpenAdminMenu, "Open admin menu");
|
||||||
|
|
||||||
|
AddHeader("Miscellaneous");
|
||||||
|
AddButton(ContentKeyFunctions.TakeScreenshot, "Take screenshot");
|
||||||
|
AddButton(ContentKeyFunctions.TakeScreenshotNoUI, "Take screenshot (without UI)");
|
||||||
|
|
||||||
|
AddHeader("Map Editor");
|
||||||
|
AddButton(EngineKeyFunctions.EditorPlaceObject, "Place object");
|
||||||
|
AddButton(EngineKeyFunctions.EditorCancelPlace, "Cancel placement");
|
||||||
|
AddButton(EngineKeyFunctions.EditorGridPlace, "Place in grid");
|
||||||
|
AddButton(EngineKeyFunctions.EditorLinePlace, "Place line");
|
||||||
|
AddButton(EngineKeyFunctions.EditorRotateObject, "Rotate");
|
||||||
|
|
||||||
|
AddHeader("Development");
|
||||||
|
AddButton(EngineKeyFunctions.ShowDebugConsole, "Open Console");
|
||||||
|
AddButton(EngineKeyFunctions.ShowDebugMonitors, "Show Debug Monitors");
|
||||||
|
AddButton(EngineKeyFunctions.HideUI, "Hide UI");
|
||||||
|
|
||||||
|
foreach (var control in _keyControls.Values)
|
||||||
|
{
|
||||||
|
UpdateKeyControl(control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateKeyControl(KeyControl control)
|
||||||
|
{
|
||||||
|
var activeBinds = _inputManager.GetKeyBindings(control.Function);
|
||||||
|
|
||||||
|
IKeyBinding? bind1 = null;
|
||||||
|
IKeyBinding? bind2 = null;
|
||||||
|
|
||||||
|
if (activeBinds.Count > 0)
|
||||||
|
{
|
||||||
|
bind1 = activeBinds[0];
|
||||||
|
|
||||||
|
if (activeBinds.Count > 1)
|
||||||
|
{
|
||||||
|
bind2 = activeBinds[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
control.BindButton1.Binding = bind1;
|
||||||
|
control.BindButton1.UpdateText();
|
||||||
|
|
||||||
|
control.BindButton2.Binding = bind2;
|
||||||
|
control.BindButton2.UpdateText();
|
||||||
|
|
||||||
|
control.BindButton2.Button.Disabled = activeBinds.Count == 0;
|
||||||
|
control.ResetButton.Disabled = !_inputManager.IsKeyFunctionModified(control.Function);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void EnteredTree()
|
||||||
|
{
|
||||||
|
base.EnteredTree();
|
||||||
|
|
||||||
|
_inputManager.FirstChanceOnKeyEvent += InputManagerOnFirstChanceOnKeyEvent;
|
||||||
|
_inputManager.OnKeyBindingAdded += OnKeyBindAdded;
|
||||||
|
_inputManager.OnKeyBindingRemoved += OnKeyBindRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ExitedTree()
|
||||||
|
{
|
||||||
|
base.ExitedTree();
|
||||||
|
|
||||||
|
_inputManager.FirstChanceOnKeyEvent -= InputManagerOnFirstChanceOnKeyEvent;
|
||||||
|
_inputManager.OnKeyBindingAdded -= OnKeyBindAdded;
|
||||||
|
_inputManager.OnKeyBindingRemoved -= OnKeyBindRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnKeyBindRemoved(IKeyBinding obj)
|
||||||
|
{
|
||||||
|
OnKeyBindModified(obj, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnKeyBindAdded(IKeyBinding obj)
|
||||||
|
{
|
||||||
|
OnKeyBindModified(obj, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnKeyBindModified(IKeyBinding bind, bool removal)
|
||||||
|
{
|
||||||
|
if (!_keyControls.TryGetValue(bind.Function, out var keyControl))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removal && _currentlyRebinding?.KeyControl == keyControl)
|
||||||
|
{
|
||||||
|
// Don't do update if the removal was from initiating a rebind.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateKeyControl(keyControl);
|
||||||
|
|
||||||
|
if (_currentlyRebinding == keyControl.BindButton1 || _currentlyRebinding == keyControl.BindButton2)
|
||||||
|
{
|
||||||
|
_currentlyRebinding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputManagerOnFirstChanceOnKeyEvent(KeyEventArgs keyEvent, KeyEventType type)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(IsInsideTree);
|
||||||
|
|
||||||
|
if (_currentlyRebinding == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyEvent.Handle();
|
||||||
|
|
||||||
|
if (type != KeyEventType.Up)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = keyEvent.Key;
|
||||||
|
|
||||||
|
// Figure out modifiers based on key event.
|
||||||
|
// TODO: this won't allow for combinations with keys other than the standard modifier keys,
|
||||||
|
// even though the input system totally supports it.
|
||||||
|
var mods = new Keyboard.Key[3];
|
||||||
|
var i = 0;
|
||||||
|
if (keyEvent.Control && key != Keyboard.Key.Control)
|
||||||
|
{
|
||||||
|
mods[i] = Keyboard.Key.Control;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyEvent.Shift && key != Keyboard.Key.Shift)
|
||||||
|
{
|
||||||
|
mods[i] = Keyboard.Key.Shift;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyEvent.Alt && key != Keyboard.Key.Alt)
|
||||||
|
{
|
||||||
|
mods[i] = Keyboard.Key.Alt;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The input system can only handle 3 modifier keys so if you hold all 4 of the modifier keys
|
||||||
|
// then system gets the shaft, I guess.
|
||||||
|
if (keyEvent.System && i != 3 && key != Keyboard.Key.LSystem && key != Keyboard.Key.RSystem)
|
||||||
|
{
|
||||||
|
mods[i] = Keyboard.Key.LSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
var function = _currentlyRebinding.KeyControl.Function;
|
||||||
|
var bindType = KeyBindingType.State;
|
||||||
|
if (ToggleFunctions.Contains(function))
|
||||||
|
{
|
||||||
|
bindType = KeyBindingType.Toggle;
|
||||||
|
}
|
||||||
|
|
||||||
|
var registration = new KeyBindingRegistration
|
||||||
|
{
|
||||||
|
Function = function,
|
||||||
|
BaseKey = key,
|
||||||
|
Mod1 = mods[0],
|
||||||
|
Mod2 = mods[1],
|
||||||
|
Mod3 = mods[2],
|
||||||
|
Priority = 0,
|
||||||
|
Type = bindType,
|
||||||
|
CanFocus = key == Keyboard.Key.MouseLeft
|
||||||
|
|| key == Keyboard.Key.MouseRight
|
||||||
|
|| key == Keyboard.Key.MouseMiddle,
|
||||||
|
CanRepeat = false
|
||||||
|
};
|
||||||
|
|
||||||
|
_inputManager.RegisterBinding(registration);
|
||||||
|
// OnKeyBindModified will cause _currentlyRebinding to be reset and the UI to update.
|
||||||
|
_inputManager.SaveToUserData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RebindButtonPressed(BindButton button)
|
||||||
|
{
|
||||||
|
if (_currentlyRebinding != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentlyRebinding = button;
|
||||||
|
_currentlyRebinding.Button.Text = Loc.GetString("Press a key...");
|
||||||
|
|
||||||
|
if (button.Binding != null)
|
||||||
|
{
|
||||||
|
_deferCommands.Add(() =>
|
||||||
|
{
|
||||||
|
// Have to do defer this or else there will be an exception in InputManager.
|
||||||
|
// Because this IS fired from an input event.
|
||||||
|
_inputManager.RemoveBinding(button.Binding);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void FrameUpdate(FrameEventArgs args)
|
||||||
|
{
|
||||||
|
base.FrameUpdate(args);
|
||||||
|
|
||||||
|
if (_deferCommands.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var command in _deferCommands)
|
||||||
|
{
|
||||||
|
command();
|
||||||
|
}
|
||||||
|
|
||||||
|
_deferCommands.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class KeyControl : Control
|
||||||
|
{
|
||||||
|
public readonly BoundKeyFunction Function;
|
||||||
|
public readonly BindButton BindButton1;
|
||||||
|
public readonly BindButton BindButton2;
|
||||||
|
public readonly Button ResetButton;
|
||||||
|
|
||||||
|
public KeyControl(KeyRebindControl parent, string niceName, BoundKeyFunction function)
|
||||||
|
{
|
||||||
|
Function = function;
|
||||||
|
var name = new Label
|
||||||
|
{
|
||||||
|
Text = Loc.GetString(niceName),
|
||||||
|
SizeFlagsHorizontal = SizeFlags.Expand
|
||||||
|
};
|
||||||
|
|
||||||
|
BindButton1 = new BindButton(parent, this, StyleBase.ButtonOpenRight);
|
||||||
|
BindButton2 = new BindButton(parent, this, StyleBase.ButtonOpenLeft);
|
||||||
|
ResetButton = new Button {Text = "Reset", StyleClasses = {StyleBase.ButtonCaution}};
|
||||||
|
|
||||||
|
var hBox = new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new Control {CustomMinimumSize = (5, 0)},
|
||||||
|
name,
|
||||||
|
BindButton1,
|
||||||
|
BindButton2,
|
||||||
|
new Control {CustomMinimumSize = (10, 0)},
|
||||||
|
ResetButton
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ResetButton.OnPressed += args =>
|
||||||
|
{
|
||||||
|
parent._deferCommands.Add(() =>
|
||||||
|
{
|
||||||
|
parent._inputManager.ResetBindingsFor(function);
|
||||||
|
parent._inputManager.SaveToUserData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
AddChild(hBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class BindButton : Control
|
||||||
|
{
|
||||||
|
private readonly KeyRebindControl _control;
|
||||||
|
public readonly KeyControl KeyControl;
|
||||||
|
public readonly Button Button;
|
||||||
|
public IKeyBinding? Binding;
|
||||||
|
|
||||||
|
public BindButton(KeyRebindControl control, KeyControl keyControl, string styleClass)
|
||||||
|
{
|
||||||
|
_control = control;
|
||||||
|
KeyControl = keyControl;
|
||||||
|
Button = new Button {StyleClasses = {styleClass}};
|
||||||
|
UpdateText();
|
||||||
|
AddChild(Button);
|
||||||
|
|
||||||
|
Button.OnPressed += args =>
|
||||||
|
{
|
||||||
|
control.RebindButtonPressed(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
Button.OnKeyBindDown += ButtonOnOnKeyBindDown;
|
||||||
|
|
||||||
|
CustomMinimumSize = (200, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ButtonOnOnKeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Function == EngineKeyFunctions.UIRightClick)
|
||||||
|
{
|
||||||
|
if (Binding != null)
|
||||||
|
{
|
||||||
|
_control._deferCommands.Add(() =>
|
||||||
|
{
|
||||||
|
_control._inputManager.RemoveBinding(Binding);
|
||||||
|
_control._inputManager.SaveToUserData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateText()
|
||||||
|
{
|
||||||
|
Button.Text = Binding?.GetKeyString() ?? "Unbound";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,136 +1,45 @@
|
|||||||
using Robust.Client.Graphics;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Interfaces.Configuration;
|
using Robust.Shared.Interfaces.Configuration;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
namespace Content.Client.UserInterface
|
||||||
{
|
{
|
||||||
public sealed class OptionsMenu : SS14Window
|
public sealed partial class OptionsMenu : SS14Window
|
||||||
{
|
{
|
||||||
private readonly Button ApplyButton;
|
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||||
private readonly CheckBox VSyncCheckBox;
|
|
||||||
private readonly CheckBox FullscreenCheckBox;
|
|
||||||
private readonly OptionButton LightingPresetOption;
|
|
||||||
private readonly IConfigurationManager configManager;
|
|
||||||
|
|
||||||
protected override Vector2? CustomSize => (180, 160);
|
protected override Vector2? CustomSize => (800, 450);
|
||||||
|
|
||||||
public OptionsMenu(IConfigurationManager configMan)
|
public OptionsMenu()
|
||||||
{
|
{
|
||||||
configManager = configMan;
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
Title = "Options";
|
Title = Loc.GetString("Game Options");
|
||||||
|
|
||||||
var vBox = new VBoxContainer();
|
GraphicsControl graphicsControl;
|
||||||
Contents.AddChild(vBox);
|
KeyRebindControl rebindControl;
|
||||||
//vBox.SetAnchorAndMarginPreset(LayoutPreset.Wide);
|
AudioControl audioControl;
|
||||||
|
|
||||||
VSyncCheckBox = new CheckBox {Text = "VSync"};
|
var tabs = new TabContainer
|
||||||
vBox.AddChild(VSyncCheckBox);
|
|
||||||
VSyncCheckBox.OnToggled += OnCheckBoxToggled;
|
|
||||||
|
|
||||||
FullscreenCheckBox = new CheckBox {Text = "Fullscreen"};
|
|
||||||
vBox.AddChild(FullscreenCheckBox);
|
|
||||||
FullscreenCheckBox.OnToggled += OnCheckBoxToggled;
|
|
||||||
|
|
||||||
vBox.AddChild(new Label {Text = "Lighting Quality"});
|
|
||||||
|
|
||||||
LightingPresetOption = new OptionButton();
|
|
||||||
LightingPresetOption.AddItem("Very Low");
|
|
||||||
LightingPresetOption.AddItem("Low");
|
|
||||||
LightingPresetOption.AddItem("Medium");
|
|
||||||
LightingPresetOption.AddItem("High");
|
|
||||||
vBox.AddChild(LightingPresetOption);
|
|
||||||
LightingPresetOption.OnItemSelected += OnLightingQualityChanged;
|
|
||||||
|
|
||||||
ApplyButton = new Button
|
|
||||||
{
|
{
|
||||||
Text = "Apply", TextAlign = Label.AlignMode.Center,
|
Children =
|
||||||
SizeFlagsVertical = SizeFlags.ShrinkCenter
|
{
|
||||||
|
(graphicsControl = new GraphicsControl(_configManager)),
|
||||||
|
(rebindControl = new KeyRebindControl()),
|
||||||
|
(audioControl = new AudioControl(_configManager)),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
vBox.AddChild(ApplyButton);
|
|
||||||
ApplyButton.OnPressed += OnApplyButtonPressed;
|
|
||||||
|
|
||||||
VSyncCheckBox.Pressed = configManager.GetCVar<bool>("display.vsync");
|
TabContainer.SetTabTitle(graphicsControl, Loc.GetString("Graphics"));
|
||||||
FullscreenCheckBox.Pressed = ConfigIsFullscreen;
|
TabContainer.SetTabTitle(rebindControl, Loc.GetString("Controls"));
|
||||||
LightingPresetOption.SelectId(GetConfigLightingQuality());
|
TabContainer.SetTabTitle(audioControl, Loc.GetString("Audio"));
|
||||||
}
|
|
||||||
|
|
||||||
private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
|
Contents.AddChild(tabs);
|
||||||
{
|
|
||||||
configManager.SetCVar("display.vsync", VSyncCheckBox.Pressed);
|
|
||||||
SetConfigLightingQuality(LightingPresetOption.SelectedId);
|
|
||||||
configManager.SetCVar("display.windowmode",
|
|
||||||
(int) (FullscreenCheckBox.Pressed ? WindowMode.Fullscreen : WindowMode.Windowed));
|
|
||||||
configManager.SaveToFile();
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCheckBoxToggled(BaseButton.ButtonToggledEventArgs args)
|
|
||||||
{
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLightingQualityChanged(OptionButton.ItemSelectedEventArgs args)
|
|
||||||
{
|
|
||||||
LightingPresetOption.SelectId(args.Id);
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateApplyButton()
|
|
||||||
{
|
|
||||||
var isVSyncSame = VSyncCheckBox.Pressed == configManager.GetCVar<bool>("display.vsync");
|
|
||||||
var isFullscreenSame = FullscreenCheckBox.Pressed == ConfigIsFullscreen;
|
|
||||||
var isLightingQualitySame = LightingPresetOption.SelectedId == GetConfigLightingQuality();
|
|
||||||
ApplyButton.Disabled = isVSyncSame && isFullscreenSame && isLightingQualitySame;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ConfigIsFullscreen =>
|
|
||||||
configManager.GetCVar<int>("display.windowmode") == (int) WindowMode.Fullscreen;
|
|
||||||
|
|
||||||
private int GetConfigLightingQuality()
|
|
||||||
{
|
|
||||||
var val = configManager.GetCVar<int>("display.lightmapdivider");
|
|
||||||
var soft = configManager.GetCVar<bool>("display.softshadows");
|
|
||||||
if (val >= 8)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if ((val >= 2) && !soft)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (val >= 2)
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void SetConfigLightingQuality(int value)
|
|
||||||
{
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
configManager.SetCVar("display.lightmapdivider", 8);
|
|
||||||
configManager.SetCVar("display.softshadows", false);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
configManager.SetCVar("display.lightmapdivider", 2);
|
|
||||||
configManager.SetCVar("display.softshadows", false);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
configManager.SetCVar("display.lightmapdivider", 2);
|
|
||||||
configManager.SetCVar("display.softshadows", true);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
configManager.SetCVar("display.lightmapdivider", 1);
|
|
||||||
configManager.SetCVar("display.softshadows", true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user