Merge branch 'master' into prediction

This commit is contained in:
Pieter-Jan Briers
2020-04-18 14:07:02 +02:00
237 changed files with 4278 additions and 1948 deletions

View File

@@ -1,5 +1,6 @@
using Content.Client.GameObjects.Components.Mobs;
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.UserInterface;
@@ -68,7 +69,7 @@ namespace Content.Client.GameObjects.Components.Actor
(SubText = new Label
{
SizeFlagsVertical = SizeFlags.None,
StyleClasses = {NanoStyle.StyleClassLabelSubText}
StyleClasses = {StyleNano.StyleClassLabelSubText}
})
}
}

View File

@@ -1,4 +1,5 @@
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Robust.Shared.Timing;
using Content.Shared.GameObjects.Components.Chemistry;
@@ -7,6 +8,7 @@ using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.ViewVariables;
using Content.Shared.Chemistry;
namespace Content.Client.GameObjects.Components.Chemistry
{
@@ -16,8 +18,8 @@ namespace Content.Client.GameObjects.Components.Chemistry
[RegisterComponent]
public class InjectorComponent : SharedInjectorComponent, IItemStatus
{
[ViewVariables] private int CurrentVolume { get; set; }
[ViewVariables] private int TotalVolume { get; set; }
[ViewVariables] private ReagentUnit CurrentVolume { get; set; }
[ViewVariables] private ReagentUnit TotalVolume { get; set; }
[ViewVariables] private InjectorToggleMode CurrentMode { get; set; }
[ViewVariables(VVAccess.ReadWrite)] private bool _uiUpdateNeeded;
@@ -28,7 +30,7 @@ namespace Content.Client.GameObjects.Components.Chemistry
//Handle net updates
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
var cast = (InjectorComponentState)curState;
var cast = (InjectorComponentState) curState;
if (cast != null)
{
CurrentVolume = cast.CurrentVolume;
@@ -49,7 +51,7 @@ namespace Content.Client.GameObjects.Components.Chemistry
public StatusControl(InjectorComponent parent)
{
_parent = parent;
_label = new RichTextLabel { StyleClasses = { NanoStyle.StyleClassItemStatus } };
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
AddChild(_label);
parent._uiUpdateNeeded = true;

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Content.Shared.Chemistry;
using Content.Shared.GameObjects.Components.Chemistry;
using Robust.Client.Graphics.Drawing;
@@ -170,7 +171,7 @@ namespace Content.Client.GameObjects.Components.Chemistry
Title = castState.DispenserName;
UpdateContainerInfo(castState);
switch (castState.SelectedDispenseAmount)
switch (castState.SelectedDispenseAmount.Int())
{
case 1:
DispenseButton1.Pressed = true;
@@ -218,7 +219,7 @@ namespace Content.Client.GameObjects.Components.Chemistry
new Label
{
Text = $"{state.BeakerCurrentVolume}/{state.BeakerMaxVolume}",
StyleClasses = {NanoStyle.StyleClassLabelSecondaryColor}
StyleClasses = {StyleNano.StyleClassLabelSecondaryColor}
}
}
});
@@ -247,12 +248,12 @@ namespace Content.Client.GameObjects.Components.Chemistry
new Label
{
Text = $"{name}: ",
StyleClasses = {NanoStyle.StyleClassPowerStateGood}
StyleClasses = {StyleNano.StyleClassPowerStateGood}
},
new Label
{
Text = $"{reagent.Quantity}u",
StyleClasses = {NanoStyle.StyleClassPowerStateGood}
StyleClasses = {StyleNano.StyleClassPowerStateGood}
}
}
});
@@ -267,7 +268,7 @@ namespace Content.Client.GameObjects.Components.Chemistry
new Label
{
Text = $"{reagent.Quantity}u",
StyleClasses = {NanoStyle.StyleClassLabelSecondaryColor}
StyleClasses = {StyleNano.StyleClassLabelSecondaryColor}
}
}
});

View File

@@ -0,0 +1,83 @@
using System;
using Content.Client.Command;
using Content.Shared.GameObjects.Components.Command;
using Robust.Client.GameObjects.Components.UserInterface;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components.Command
{
public class CommunicationsConsoleBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private CommunicationsConsoleMenu _menu;
[Dependency] private IGameTiming _gameTiming;
public bool CountdownStarted { get; private set; }
public int Countdown => _expectedCountdownTime == null
? 0 : Math.Max((int)_expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0);
private TimeSpan? _expectedCountdownTime;
public CommunicationsConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_menu = new CommunicationsConsoleMenu(this);
_menu.OnClose += Close;
_menu.OpenCentered();
}
public void EmergencyShuttleButtonPressed()
{
if(CountdownStarted)
RecallShuttle();
else
CallShuttle();
}
public void CallShuttle()
{
SendMessage(new CommunicationsConsoleCallEmergencyShuttleMessage());
}
public void RecallShuttle()
{
SendMessage(new CommunicationsConsoleRecallEmergencyShuttleMessage());
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
switch (message)
{
}
}
protected override void UpdateState(BoundUserInterfaceState state)
{
if (!(state is CommunicationsConsoleInterfaceState commsState))
return;
_expectedCountdownTime = commsState.ExpectedCountdownEnd;
CountdownStarted = commsState.CountdownStarted;
_menu?.UpdateCountdown();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_menu?.Dispose();
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Content.Shared.GameObjects.Components.Instruments;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Client.Audio.Midi;
using Robust.Shared.Audio.Midi;
@@ -28,6 +29,7 @@ namespace Content.Client.GameObjects.Components.Instruments
[Dependency] private readonly IGameTiming _timing;
#pragma warning restore 649
[CanBeNull]
private IMidiRenderer _renderer;
private int _instrumentProgram = 1;
@@ -42,8 +44,14 @@ namespace Content.Client.GameObjects.Components.Instruments
[ViewVariables(VVAccess.ReadWrite)]
public bool LoopMidi
{
get => _renderer.LoopMidi;
set => _renderer.LoopMidi = value;
get => _renderer?.LoopMidi ?? false;
set
{
if (_renderer != null)
{
_renderer.LoopMidi = value;
}
}
}
/// <summary>
@@ -53,9 +61,13 @@ namespace Content.Client.GameObjects.Components.Instruments
public int InstrumentProgram
{
get => _instrumentProgram;
set {
set
{
_instrumentProgram = value;
_renderer.MidiProgram = _instrumentProgram;
if (_renderer != null)
{
_renderer.MidiProgram = _instrumentProgram;
}
}
}
@@ -63,22 +75,26 @@ namespace Content.Client.GameObjects.Components.Instruments
/// Whether there's a midi song being played or not.
/// </summary>
[ViewVariables]
public bool IsMidiOpen => _renderer.Status == MidiRendererStatus.File;
public bool IsMidiOpen => _renderer?.Status == MidiRendererStatus.File;
/// <summary>
/// Whether the midi renderer is listening for midi input or not.
/// </summary>
[ViewVariables]
public bool IsInputOpen => _renderer.Status == MidiRendererStatus.Input;
public bool IsInputOpen => _renderer?.Status == MidiRendererStatus.Input;
public override void Initialize()
{
base.Initialize();
IoCManager.InjectDependencies(this);
_renderer = _midiManager.GetNewRenderer();
_renderer.MidiProgram = _instrumentProgram;
_renderer.TrackingEntity = Owner;
_renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); };
if (_renderer != null)
{
_renderer.MidiProgram = _instrumentProgram;
_renderer.TrackingEntity = Owner;
_renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); };
}
}
protected override void Shutdown()
@@ -93,9 +109,16 @@ namespace Content.Client.GameObjects.Components.Instruments
serializer.DataField(ref _instrumentProgram, "program", 1);
}
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
IComponent component = null)
{
base.HandleMessage(message, netChannel, component);
if (_renderer == null)
{
return;
}
switch (message)
{
case InstrumentMidiEventMessage midiEventMessage:
@@ -107,8 +130,8 @@ namespace Content.Client.GameObjects.Components.Instruments
case InstrumentStopMidiMessage _:
_renderer.StopAllNotes();
if(IsInputOpen) CloseInput();
if(IsMidiOpen) CloseMidi();
if (IsInputOpen) CloseInput();
if (IsMidiOpen) CloseMidi();
break;
}
}
@@ -116,7 +139,7 @@ namespace Content.Client.GameObjects.Components.Instruments
/// <inheritdoc cref="MidiRenderer.OpenInput"/>
public bool OpenInput()
{
if (_renderer.OpenInput())
if (_renderer != null && _renderer.OpenInput())
{
_renderer.OnMidiEvent += RendererOnMidiEvent;
return true;
@@ -128,28 +151,37 @@ namespace Content.Client.GameObjects.Components.Instruments
/// <inheritdoc cref="MidiRenderer.CloseInput"/>
public bool CloseInput()
{
if (!_renderer.CloseInput()) return false;
if (_renderer == null || !_renderer.CloseInput())
{
return false;
}
_renderer.OnMidiEvent -= RendererOnMidiEvent;
return true;
}
/// <inheritdoc cref="MidiRenderer.OpenMidi(string)"/>
public bool OpenMidi(string filename)
{
if (!_renderer.OpenMidi(filename)) return false;
if (_renderer == null || !_renderer.OpenMidi(filename))
{
return false;
}
_renderer.OnMidiEvent += RendererOnMidiEvent;
return true;
}
/// <inheritdoc cref="MidiRenderer.CloseMidi"/>
public bool CloseMidi()
{
if (!_renderer.CloseMidi()) return false;
if (_renderer == null || !_renderer.CloseMidi())
{
return false;
}
_renderer.OnMidiEvent -= RendererOnMidiEvent;
return true;
}
/// <summary>

View File

@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Content.Shared.Preferences.Appearance;
using JetBrains.Annotations;
using Robust.Client.GameObjects.Components.UserInterface;
@@ -126,9 +127,9 @@ namespace Content.Client.GameObjects.Components
var vBox = new VBoxContainer();
AddChild(vBox);
vBox.AddChild(_colorSliderR = new ColorSlider(NanoStyle.StyleClassSliderRed));
vBox.AddChild(_colorSliderG = new ColorSlider(NanoStyle.StyleClassSliderGreen));
vBox.AddChild(_colorSliderB = new ColorSlider(NanoStyle.StyleClassSliderBlue));
vBox.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
vBox.AddChild(_colorSliderG = new ColorSlider(StyleNano.StyleClassSliderGreen));
vBox.AddChild(_colorSliderB = new ColorSlider(StyleNano.StyleClassSliderBlue));
Action colorValueChanged = ColorValueChanged;
_colorSliderR.OnValueChanged += colorValueChanged;

View File

@@ -76,10 +76,6 @@ namespace Content.Client.GameObjects.Components.Mobs
private void PlayerDetached()
{
if (!CurrentlyControlled)
{
return;
}
_ui?.Dispose();
_ui = null;
}

View File

@@ -0,0 +1,108 @@
using Content.Client.UserInterface;
using Content.Shared.GameObjects.Components.Observer;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components.Observer
{
[RegisterComponent]
public class GhostComponent : SharedGhostComponent
{
private GhostGui _gui;
[ViewVariables(VVAccess.ReadOnly)]
public bool CanReturnToBody { get; private set; } = true;
private bool _isAttached;
#pragma warning disable 649
[Dependency] private readonly IGameHud _gameHud;
[Dependency] private readonly IPlayerManager _playerManager;
[Dependency] private IComponentManager _componentManager;
#pragma warning restore 649
public override void OnRemove()
{
base.OnRemove();
_gui?.Dispose();
// PlayerDetachedMsg might not fire due to deletion order so...
if (_isAttached)
{
SetGhostVisibility(false);
}
}
private void SetGhostVisibility(bool visibility)
{
foreach (var ghost in _componentManager.GetAllComponents(typeof(GhostComponent)))
{
if (ghost.Owner.TryGetComponent(out SpriteComponent component))
component.Visible = visibility;
}
}
public override void Initialize()
{
base.Initialize();
if (Owner.TryGetComponent(out SpriteComponent component))
component.Visible = _playerManager.LocalPlayer.ControlledEntity?.HasComponent<GhostComponent>() ?? false;
}
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
IComponent component = null)
{
base.HandleMessage(message, netChannel, component);
switch (message)
{
case PlayerAttachedMsg _:
if (_gui == null)
{
_gui = new GhostGui(this);
}
else
{
_gui.Orphan();
}
_gameHud.HandsContainer.AddChild(_gui);
SetGhostVisibility(true);
_isAttached = true;
break;
case PlayerDetachedMsg _:
_gui.Parent?.RemoveChild(_gui);
SetGhostVisibility(false);
_isAttached = false;
break;
}
}
public void SendReturnToBodyMessage() => SendNetworkMessage(new ReturnToBodyComponentMessage());
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
base.HandleComponentState(curState, nextState);
if (!(curState is GhostComponentState state)) return;
CanReturnToBody = state.CanReturnToBody;
if (Owner == _playerManager.LocalPlayer.ControlledEntity)
{
_gui?.Update();
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Content.Shared.GameObjects.Components.Power;
using Robust.Client.GameObjects.Components.UserInterface;
using Robust.Client.Graphics.Drawing;
@@ -47,15 +48,15 @@ namespace Content.Client.GameObjects.Components.Power
{
case ApcExternalPowerState.None:
_externalPowerStateLabel.Text = "None";
_externalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateNone);
_externalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
break;
case ApcExternalPowerState.Low:
_externalPowerStateLabel.Text = "Low";
_externalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateLow);
_externalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateLow);
break;
case ApcExternalPowerState.Good:
_externalPowerStateLabel.Text = "Good";
_externalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateGood);
_externalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
break;
default:
throw new ArgumentOutOfRangeException();
@@ -140,7 +141,7 @@ namespace Content.Client.GameObjects.Components.Power
var externalStatus = new HBoxContainer();
var externalStatusLabel = new Label {Text = "External Power: "};
ExternalPowerStateLabel = new Label {Text = "Good"};
ExternalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateGood);
ExternalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
externalStatus.AddChild(externalStatusLabel);
externalStatus.AddChild(ExternalPowerStateLabel);
rows.AddChild(externalStatus);

View File

@@ -17,9 +17,9 @@ namespace Content.Client.GameObjects.Components.Research
private IPrototypeManager _prototypeManager;
#pragma warning restore
[ViewVariables]
private LatheMenu menu;
private LatheMenu _menu;
[ViewVariables]
private LatheQueueMenu queueMenu;
private LatheQueueMenu _queueMenu;
public MaterialStorageComponent Storage { get; private set; }
public SharedLatheComponent Lathe { get; private set; }
@@ -48,30 +48,30 @@ namespace Content.Client.GameObjects.Components.Research
Lathe = lathe;
Database = database;
menu = new LatheMenu(this);
queueMenu = new LatheQueueMenu { Owner = this };
_menu = new LatheMenu(this);
_queueMenu = new LatheQueueMenu { Owner = this };
menu.OnClose += Close;
_menu.OnClose += Close;
menu.Populate();
menu.PopulateMaterials();
_menu.Populate();
_menu.PopulateMaterials();
menu.QueueButton.OnPressed += (args) => { queueMenu.OpenCentered(); };
_menu.QueueButton.OnPressed += (args) => { _queueMenu.OpenCentered(); };
menu.ServerConnectButton.OnPressed += (args) =>
_menu.ServerConnectButton.OnPressed += (args) =>
{
SendMessage(new SharedLatheComponent.LatheServerSelectionMessage());
};
menu.ServerSyncButton.OnPressed += (args) =>
_menu.ServerSyncButton.OnPressed += (args) =>
{
SendMessage(new SharedLatheComponent.LatheServerSyncMessage());
};
storage.OnMaterialStorageChanged += menu.PopulateDisabled;
storage.OnMaterialStorageChanged += menu.PopulateMaterials;
storage.OnMaterialStorageChanged += _menu.PopulateDisabled;
storage.OnMaterialStorageChanged += _menu.PopulateMaterials;
menu.OpenCentered();
_menu.OpenCentered();
}
public void Queue(LatheRecipePrototype recipe, int quantity = 1)
@@ -85,10 +85,10 @@ namespace Content.Client.GameObjects.Components.Research
{
case SharedLatheComponent.LatheProducingRecipeMessage msg:
if (!_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe)) break;
queueMenu?.SetInfo(recipe);
_queueMenu?.SetInfo(recipe);
break;
case SharedLatheComponent.LatheStoppedProducingRecipeMessage _:
queueMenu?.ClearInfo();
_queueMenu?.ClearInfo();
break;
case SharedLatheComponent.LatheFullQueueMessage msg:
_queuedRecipes.Clear();
@@ -97,7 +97,7 @@ namespace Content.Client.GameObjects.Components.Research
if (!_prototypeManager.TryIndex(id, out LatheRecipePrototype recipePrototype)) break;
_queuedRecipes.Enqueue(recipePrototype);
}
queueMenu?.PopulateList();
_queueMenu?.PopulateList();
break;
}
}
@@ -106,8 +106,8 @@ namespace Content.Client.GameObjects.Components.Research
{
base.Dispose(disposing);
if (!disposing) return;
menu?.Dispose();
queueMenu?.Dispose();
_menu?.Dispose();
_queueMenu?.Dispose();
}
}
}

View File

@@ -1,4 +1,4 @@
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Content.Shared.GameObjects.Components;
using Robust.Client.UserInterface;
@@ -13,21 +13,19 @@ namespace Content.Client.GameObjects.Components
[RegisterComponent]
public class StackComponent : SharedStackComponent, IItemStatus
{
[ViewVariables] public int Count { get; private set; }
[ViewVariables] public int MaxCount { get; private set; }
[ViewVariables(VVAccess.ReadWrite)] private bool _uiUpdateNeeded;
public Control MakeControl() => new StatusControl(this);
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
public override int Count
{
if (!(curState is StackComponentState cast))
return;
get => base.Count;
set
{
base.Count = value;
Count = cast.Count;
MaxCount = cast.MaxCount;
_uiUpdateNeeded = true;
_uiUpdateNeeded = true;
}
}
private sealed class StatusControl : Control
@@ -38,7 +36,7 @@ namespace Content.Client.GameObjects.Components
public StatusControl(StackComponent parent)
{
_parent = parent;
_label = new RichTextLabel {StyleClasses = {NanoStyle.StyleClassItemStatus}};
_label = new RichTextLabel {StyleClasses = {StyleNano.StyleClassItemStatus}};
AddChild(_label);
parent._uiUpdateNeeded = true;

View File

@@ -1,6 +1,7 @@
using System;
using Content.Client.Animations;
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged;
@@ -174,7 +175,7 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged
(_noMagazineLabel = new Label
{
Text = "No Magazine!",
StyleClasses = {NanoStyle.StyleClassItemStatus}
StyleClasses = {StyleNano.StyleClassItemStatus}
})
}
},

View File

@@ -1,5 +1,6 @@
using System;
using Content.Client.UserInterface;
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components;
@@ -46,7 +47,7 @@ namespace Content.Client.GameObjects.Components
public StatusControl(WelderComponent parent)
{
_parent = parent;
_label = new RichTextLabel {StyleClasses = {NanoStyle.StyleClassItemStatus}};
_label = new RichTextLabel {StyleClasses = {StyleNano.StyleClassItemStatus}};
AddChild(_label);
parent._uiUpdateNeeded = true;