Merge branch 'master' into 2020-08-19-firelocks

This commit is contained in:
Víctor Aguilera Puerto
2020-08-21 16:51:50 +02:00
212 changed files with 3718 additions and 462 deletions

View File

@@ -33,7 +33,7 @@ namespace Content.Client.GameObjects.Components.Body
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession? session = null)
{
if (!Owner.TryGetComponent(out ISpriteComponent sprite))
if (!Owner.TryGetComponent(out ISpriteComponent? sprite))
{
return;
}
@@ -50,7 +50,7 @@ namespace Content.Client.GameObjects.Components.Body
if (!partRemoved.Dropped.HasValue ||
!_entityManager.TryGetEntity(partRemoved.Dropped.Value, out var entity) ||
!entity.TryGetComponent(out ISpriteComponent droppedSprite))
!entity.TryGetComponent(out ISpriteComponent? droppedSprite))
{
break;
}

View File

@@ -37,7 +37,7 @@ namespace Content.Client.GameObjects.Components
/// <returns>True if the click worked, false otherwise.</returns>
public bool CheckClick(Vector2 worldPos, out int drawDepth, out uint renderOrder)
{
if (!Owner.TryGetComponent(out ISpriteComponent sprite) || !sprite.Visible)
if (!Owner.TryGetComponent(out ISpriteComponent? sprite) || !sprite.Visible)
{
drawDepth = default;
renderOrder = default;

View File

@@ -0,0 +1,67 @@
#nullable enable
using JetBrains.Annotations;
using Robust.Client.GameObjects.Components.UserInterface;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.Localization;
using static Content.Shared.GameObjects.Components.Disposal.SharedDisposalRouterComponent;
namespace Content.Client.GameObjects.Components.Disposal
{
/// <summary>
/// Initializes a <see cref="DisposalRouterWindow"/> and updates it when new server messages are received.
/// </summary>
[UsedImplicitly]
public class DisposalRouterBoundUserInterface : BoundUserInterface
{
private DisposalRouterWindow? _window;
public DisposalRouterBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_window = new DisposalRouterWindow();
_window.OpenCentered();
_window.OnClose += Close;
_window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text);
_window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text);
}
private void ButtonPressed(UiAction action, string tag)
{
SendMessage(new UiActionMessage(action, tag));
_window?.Close();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (!(state is DisposalRouterUserInterfaceState cast))
{
return;
}
_window?.UpdateState(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
}
}

View File

@@ -0,0 +1,51 @@
using Content.Shared.GameObjects.Components.Disposal;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using static Content.Shared.GameObjects.Components.Disposal.SharedDisposalRouterComponent;
namespace Content.Client.GameObjects.Components.Disposal
{
/// <summary>
/// Client-side UI used to control a <see cref="SharedDisposalRouterComponent"/>
/// </summary>
public class DisposalRouterWindow : SS14Window
{
public readonly LineEdit TagInput;
public readonly Button Confirm;
protected override Vector2? CustomSize => (400, 80);
public DisposalRouterWindow()
{
Title = Loc.GetString("Disposal Router");
Contents.AddChild(new VBoxContainer
{
Children =
{
new Label {Text = Loc.GetString("Tags:")},
new Control {CustomMinimumSize = (0, 10)},
new HBoxContainer
{
Children =
{
(TagInput = new LineEdit {SizeFlagsHorizontal = SizeFlags.Expand, CustomMinimumSize = (320, 0),
ToolTip = Loc.GetString("A comma separated list of tags"), IsValid = tags => TagRegex.IsMatch(tags)}),
new Control {CustomMinimumSize = (10, 0)},
(Confirm = new Button {Text = Loc.GetString("Confirm")})
}
}
}
});
}
public void UpdateState(DisposalRouterUserInterfaceState state)
{
TagInput.Text = state.Tags;
}
}
}

View File

@@ -0,0 +1,67 @@
#nullable enable
using JetBrains.Annotations;
using Robust.Client.GameObjects.Components.UserInterface;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.Localization;
using static Content.Shared.GameObjects.Components.Disposal.SharedDisposalTaggerComponent;
namespace Content.Client.GameObjects.Components.Disposal
{
/// <summary>
/// Initializes a <see cref="DisposalTaggerWindow"/> and updates it when new server messages are received.
/// </summary>
[UsedImplicitly]
public class DisposalTaggerBoundUserInterface : BoundUserInterface
{
private DisposalTaggerWindow? _window;
public DisposalTaggerBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_window = new DisposalTaggerWindow();
_window.OpenCentered();
_window.OnClose += Close;
_window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text);
_window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text);
}
private void ButtonPressed(UiAction action, string tag)
{
SendMessage(new UiActionMessage(action, tag));
_window?.Close();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (!(state is DisposalTaggerUserInterfaceState cast))
{
return;
}
_window?.UpdateState(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
}
}

View File

@@ -0,0 +1,51 @@
using Content.Shared.GameObjects.Components.Disposal;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using static Content.Shared.GameObjects.Components.Disposal.SharedDisposalTaggerComponent;
namespace Content.Client.GameObjects.Components.Disposal
{
/// <summary>
/// Client-side UI used to control a <see cref="SharedDisposalTaggerComponent"/>
/// </summary>
public class DisposalTaggerWindow : SS14Window
{
public readonly LineEdit TagInput;
public readonly Button Confirm;
protected override Vector2? CustomSize => (400, 80);
public DisposalTaggerWindow()
{
Title = Loc.GetString("Disposal Tagger");
Contents.AddChild(new VBoxContainer
{
Children =
{
new Label {Text = Loc.GetString("Tag:")},
new Control {CustomMinimumSize = (0, 10)},
new HBoxContainer
{
Children =
{
(TagInput = new LineEdit {SizeFlagsHorizontal = SizeFlags.Expand, CustomMinimumSize = (320, 0),
IsValid = tag => TagRegex.IsMatch(tag)}),
new Control {CustomMinimumSize = (10, 0)},
(Confirm = new Button {Text = Loc.GetString("Confirm")})
}
}
}
});
}
public void UpdateState(DisposalTaggerUserInterfaceState state)
{
TagInput.Text = state.Tag;
}
}
}

View File

@@ -113,12 +113,12 @@ namespace Content.Client.GameObjects.Components.Disposal
if (normalized <= leftSideSize)
{
normalized /= leftSideSize; // Adjust range to 0.0 to 1.0
finalHue = FloatMath.Lerp(leftHue, middleHue, normalized);
finalHue = MathHelper.Lerp(leftHue, middleHue, normalized);
}
else
{
normalized = (normalized - leftSideSize) / rightSideSize; // Adjust range to 0.0 to 1.0.
finalHue = FloatMath.Lerp(middleHue, rightHue, normalized);
finalHue = MathHelper.Lerp(middleHue, rightHue, normalized);
}
// Check if null first to avoid repeatedly creating this.

View File

@@ -78,7 +78,7 @@ namespace Content.Client.GameObjects.Components
int level;
if (FloatMath.CloseTo(charge, 0))
if (MathHelper.CloseTo(charge, 0))
{
level = 0;
}

View File

@@ -148,7 +148,7 @@ namespace Content.Client.GameObjects.Components.Items
return;
}
if (!entity.TryGetComponent(out ItemComponent item)) return;
if (!entity.TryGetComponent(out ItemComponent? item)) return;
var maybeInHands = item.GetInHandStateInfo(hand.Location);

View File

@@ -243,7 +243,7 @@ namespace Content.Client.GameObjects.Components
if (int.TryParse(ev.Text, out var result))
{
result = FloatMath.Clamp(result, 0, byte.MaxValue);
result = MathHelper.Clamp(result, 0, byte.MaxValue);
_ignoreEvents = true;
_colorValue = (byte) result;

View File

@@ -22,6 +22,7 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
Title = Owner.Owner.Name,
};
_window.OnClose += Close;
_window.ScanButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.ScanDNA));
_window.OpenCentered();
}

View File

@@ -12,18 +12,38 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
{
public class MedicalScannerWindow : SS14Window
{
public readonly Button ScanButton;
private readonly Label _diagnostics;
protected override Vector2? CustomSize => (485, 90);
public MedicalScannerWindow()
{
Contents.AddChild(new VBoxContainer
{
Children =
{
(ScanButton = new Button
{
Text = "Scan and Save DNA"
}),
(_diagnostics = new Label
{
Text = ""
})
}
});
}
public void Populate(MedicalScannerBoundUserInterfaceState state)
{
Contents.RemoveAllChildren();
var text = new StringBuilder();
if (!state.Entity.HasValue ||
!state.HasDamage() ||
!IoCManager.Resolve<IEntityManager>().TryGetEntity(state.Entity.Value, out var entity))
{
text.Append(Loc.GetString("No patient data."));
_diagnostics.Text = Loc.GetString("No patient data.");
ScanButton.Disabled = true;
}
else
{
@@ -45,9 +65,10 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
text.Append("\n");
}
}
Contents.AddChild(new Label() {Text = text.ToString()});
_diagnostics.Text = text.ToString();
ScanButton.Disabled = state.IsScanned;
}
}
}
}

View File

@@ -23,7 +23,7 @@ namespace Content.Client.GameObjects.Components.Mobs
private const float RestoreRateRamp = 0.1f;
// The maximum magnitude of the kick applied to the camera at any point.
private const float KickMagnitudeMax = 5f;
private const float KickMagnitudeMax = 2f;
private Vector2 _currentKick;
private float _lastKickTime;
@@ -87,7 +87,7 @@ namespace Content.Client.GameObjects.Components.Mobs
// Continually restore camera to 0.
var normalized = _currentKick.Normalized;
_lastKickTime += frameTime;
var restoreRate = FloatMath.Lerp(RestoreRateMin, RestoreRateMax, Math.Min(1, _lastKickTime/RestoreRateRamp));
var restoreRate = MathHelper.Lerp(RestoreRateMin, RestoreRateMax, Math.Min(1, _lastKickTime/RestoreRateRamp));
var restore = normalized * restoreRate * frameTime;
var (x, y) = _currentKick - restore;
if (Math.Sign(x) != Math.Sign(_currentKick.X))

View File

@@ -152,7 +152,7 @@ namespace Content.Client.GameObjects.Components.Mobs
var progress = (_gameTiming.CurTime - start).TotalSeconds / length;
var ratio = (progress <= 1 ? (1 - progress) : (_gameTiming.CurTime - end).TotalSeconds * -5);
cooldownGraphic.Progress = FloatMath.Clamp((float)ratio, -1, 1);
cooldownGraphic.Progress = MathHelper.Clamp((float)ratio, -1, 1);
cooldownGraphic.Visible = ratio > -1f;
}
}

View File

@@ -34,7 +34,7 @@ namespace Content.Client.GameObjects.Components.Mobs
WalkModifierOverride = state.WalkModifierOverride;
RunModifierOverride = state.RunModifierOverride;
if (Owner.TryGetComponent(out MovementSpeedModifierComponent movement))
if (Owner.TryGetComponent(out MovementSpeedModifierComponent? movement))
{
movement.RefreshMovementSpeedModifiers();
}

View File

@@ -0,0 +1,12 @@
using Robust.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Movement;
namespace Content.Client.GameObjects.Components.Movement
{
[RegisterComponent]
[ComponentReference(typeof(IClimbable))]
public class ClimbableComponent : SharedClimbableComponent
{
}
}

View File

@@ -0,0 +1,34 @@
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
using Content.Shared.GameObjects.Components.Movement;
using Content.Client.Interfaces.GameObjects.Components.Interaction;
using Content.Shared.Physics;
namespace Content.Client.GameObjects.Components.Movement
{
[RegisterComponent]
public class ClimbingComponent : SharedClimbingComponent, IClientDraggable
{
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
if (!(curState is ClimbModeComponentState climbModeState) || Body == null)
{
return;
}
IsClimbing = climbModeState.Climbing;
}
public override bool IsClimbing { get; set; }
bool IClientDraggable.ClientCanDropOn(CanDropEventArgs eventArgs)
{
return eventArgs.Target.HasComponent<IClimbable>();
}
bool IClientDraggable.ClientCanDrag(CanDragEventArgs eventArgs)
{
return true;
}
}
}

View File

@@ -20,7 +20,7 @@ namespace Content.Client.GameObjects.Components.Nutrition
_currentHungerThreshold = hunger.CurrentThreshold;
if (Owner.TryGetComponent(out MovementSpeedModifierComponent movement))
if (Owner.TryGetComponent(out MovementSpeedModifierComponent? movement))
{
movement.RefreshMovementSpeedModifiers();
}

View File

@@ -20,7 +20,7 @@ namespace Content.Client.GameObjects.Components.Nutrition
_currentThirstThreshold = thirst.CurrentThreshold;
if (Owner.TryGetComponent(out MovementSpeedModifierComponent movement))
if (Owner.TryGetComponent(out MovementSpeedModifierComponent? movement))
{
movement.RefreshMovementSpeedModifiers();
}

View File

@@ -1,4 +1,4 @@
using Content.Shared.GameObjects.Components.PDA;
using Content.Shared.GameObjects.Components.PDA;
using Robust.Client.GameObjects;
using Robust.Client.Interfaces.GameObjects.Components;
@@ -10,7 +10,7 @@ namespace Content.Client.GameObjects.Components.PDA
private enum PDAVisualLayers
{
Base,
Unlit
Flashlight
}
@@ -22,13 +22,13 @@ namespace Content.Client.GameObjects.Components.PDA
return;
}
var sprite = component.Owner.GetComponent<ISpriteComponent>();
sprite.LayerSetVisible(PDAVisualLayers.Unlit, false);
if(!component.TryGetData<bool>(PDAVisuals.ScreenLit, out var isScreenLit))
sprite.LayerSetVisible(PDAVisualLayers.Flashlight, false);
if(!component.TryGetData<bool>(PDAVisuals.FlashlightLit, out var isScreenLit))
{
return;
}
sprite.LayerSetState(PDAVisualLayers.Unlit, "unlit_pda_screen");
sprite.LayerSetVisible(PDAVisualLayers.Unlit, isScreenLit);
sprite.LayerSetState(PDAVisualLayers.Flashlight, "light_overlay");
sprite.LayerSetVisible(PDAVisualLayers.Flashlight, isScreenLit);
}

View File

@@ -86,12 +86,12 @@ namespace Content.Client.GameObjects.Components.Power
if (normalizedCharge <= leftSideSize)
{
normalizedCharge /= leftSideSize; // Adjust range to 0.0 to 1.0
finalHue = FloatMath.Lerp(leftHue, middleHue, normalizedCharge);
finalHue = MathHelper.Lerp(leftHue, middleHue, normalizedCharge);
}
else
{
normalizedCharge = (normalizedCharge - leftSideSize) / rightSideSize; // Adjust range to 0.0 to 1.0.
finalHue = FloatMath.Lerp(middleHue, rightHue, normalizedCharge);
finalHue = MathHelper.Lerp(middleHue, rightHue, normalizedCharge);
}
// Check if null first to avoid repeatedly creating this.

View File

@@ -141,7 +141,7 @@ namespace Content.Client.GameObjects.Components.Weapons
const float xOffset = 0.0f;
// Overkill but easy to adjust if you want to mess around with the design
var result = (float) FloatMath.Clamp(slope * (float) Math.Pow(ratio - xOffset, exponent) + yOffset, 0.0, 1.0);
var result = (float) MathHelper.Clamp(slope * (float) Math.Pow(ratio - xOffset, exponent) + yOffset, 0.0, 1.0);
DebugTools.Assert(!float.IsNaN(result));
return result;
}

View File

@@ -143,7 +143,7 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
{
base.FrameUpdate(args);
if (AttachedEntity?.IsValid() != true || !AttachedEntity.TryGetComponent(out DoAfterComponent doAfterComponent))
if (AttachedEntity?.IsValid() != true || !AttachedEntity.TryGetComponent(out DoAfterComponent? doAfterComponent))
{
return;
}

View File

@@ -67,7 +67,7 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
Gui ??= new DoAfterGui();
Gui.AttachedEntity = entity;
if (entity.TryGetComponent(out DoAfterComponent doAfterComponent))
if (entity.TryGetComponent(out DoAfterComponent? doAfterComponent))
{
foreach (var (_, doAfter) in doAfterComponent.DoAfters)
{
@@ -87,7 +87,7 @@ namespace Content.Client.GameObjects.EntitySystems.DoAfter
return;
}
if (!_player.TryGetComponent(out DoAfterComponent doAfterComponent))
if (!_player.TryGetComponent(out DoAfterComponent? doAfterComponent))
{
return;
}

View File

@@ -25,7 +25,7 @@ namespace Content.Client.GameObjects.EntitySystems
{
var playerEnt = _playerManager.LocalPlayer?.ControlledEntity;
if (playerEnt == null || !playerEnt.TryGetComponent(out IMoverComponent mover))
if (playerEnt == null || !playerEnt.TryGetComponent(out IMoverComponent? mover))
{
return;
}

View File

@@ -207,11 +207,10 @@ namespace Content.Client.GameObjects.EntitySystems
//Get verbs, component dependent.
foreach (var (component, verb) in VerbUtility.GetVerbs(entity))
{
if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(user, entity))
continue;
if (verb.BlockedByContainers && !user.IsInSameOrNoContainer(entity))
if (!VerbUtility.VerbAccessChecks(user, entity, verb))
{
continue;
}
var verbData = verb.GetData(user, component);
@@ -232,11 +231,10 @@ namespace Content.Client.GameObjects.EntitySystems
//Get global verbs. Visible for all entities regardless of their components.
foreach (var globalVerb in VerbUtility.GetGlobalVerbs(Assembly.GetExecutingAssembly()))
{
if (globalVerb.RequireInteractionRange && !VerbUtility.InVerbUseRange(user, entity))
continue;
if (globalVerb.BlockedByContainers && !user.IsInSameOrNoContainer(entity))
if (!VerbUtility.VerbAccessChecks(user, entity, globalVerb))
{
continue;
}
var verbData = globalVerb.GetData(user, entity);