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,4 +1,5 @@
using System;
using Content.Shared.Chemistry;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
@@ -18,11 +19,11 @@ namespace Content.Shared.GameObjects.Components.Chemistry
[Serializable, NetSerializable]
protected sealed class InjectorComponentState : ComponentState
{
public int CurrentVolume { get; }
public int TotalVolume { get; }
public ReagentUnit CurrentVolume { get; }
public ReagentUnit TotalVolume { get; }
public InjectorToggleMode CurrentMode { get; }
public InjectorComponentState(int currentVolume, int totalVolume, InjectorToggleMode currentMode) : base(ContentNetIDs.REAGENT_INJECTOR)
public InjectorComponentState(ReagentUnit currentVolume, ReagentUnit totalVolume, InjectorToggleMode currentMode) : base(ContentNetIDs.REAGENT_INJECTOR)
{
CurrentVolume = currentVolume;
TotalVolume = totalVolume;

View File

@@ -26,8 +26,8 @@ namespace Content.Shared.GameObjects.Components.Chemistry
public class ReagentDispenserBoundUserInterfaceState : BoundUserInterfaceState
{
public readonly bool HasBeaker;
public readonly int BeakerCurrentVolume;
public readonly int BeakerMaxVolume;
public readonly ReagentUnit BeakerCurrentVolume;
public readonly ReagentUnit BeakerMaxVolume;
public readonly string ContainerName;
/// <summary>
/// A list of the reagents which this dispenser can dispense.
@@ -38,10 +38,10 @@ namespace Content.Shared.GameObjects.Components.Chemistry
/// </summary>
public readonly List<Solution.ReagentQuantity> ContainerReagents;
public readonly string DispenserName;
public readonly int SelectedDispenseAmount;
public readonly ReagentUnit SelectedDispenseAmount;
public ReagentDispenserBoundUserInterfaceState(bool hasBeaker, int beakerCurrentVolume, int beakerMaxVolume, string containerName,
List<ReagentDispenserInventoryEntry> inventory, string dispenserName, List<Solution.ReagentQuantity> containerReagents, int selectedDispenseAmount)
public ReagentDispenserBoundUserInterfaceState(bool hasBeaker, ReagentUnit beakerCurrentVolume, ReagentUnit beakerMaxVolume, string containerName,
List<ReagentDispenserInventoryEntry> inventory, string dispenserName, List<Solution.ReagentQuantity> containerReagents, ReagentUnit selectedDispenseAmount)
{
HasBeaker = hasBeaker;
BeakerCurrentVolume = beakerCurrentVolume;

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using Content.Shared.Chemistry;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Shared.GameObjects.Components.Chemistry
{
public class SharedSolutionComponent : Component
{
public override string Name => "Solution";
/// <inheritdoc />
public sealed override uint? NetID => ContentNetIDs.SOLUTION;
[Serializable, NetSerializable]
public class SolutionComponentState : ComponentState
{
public SolutionComponentState() : base(ContentNetIDs.SOLUTION) { }
}
/// <inheritdoc />
public override ComponentState GetComponentState()
{
return new SolutionComponentState();
}
/// <inheritdoc />
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
base.HandleComponentState(curState, nextState);
if(curState == null)
return;
var compState = (SolutionComponentState)curState;
//TODO: Make me work!
}
}
}

View File

@@ -1,238 +0,0 @@
using System;
using System.Collections.Generic;
using Content.Shared.Chemistry;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Shared.GameObjects.Components.Chemistry
{
public class SolutionComponent : Component
{
#pragma warning disable 649
[Dependency] private readonly IPrototypeManager _prototypeManager;
#pragma warning restore 649
[ViewVariables]
protected Solution _containedSolution = new Solution();
protected int _maxVolume;
private SolutionCaps _capabilities;
/// <summary>
/// Triggered when the solution contents change.
/// </summary>
public event Action SolutionChanged;
/// <summary>
/// The maximum volume of the container.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public int MaxVolume
{
get => _maxVolume;
set => _maxVolume = value; // Note that the contents won't spill out if the capacity is reduced.
}
/// <summary>
/// The total volume of all the of the reagents in the container.
/// </summary>
[ViewVariables]
public int CurrentVolume => _containedSolution.TotalVolume;
/// <summary>
/// The volume without reagents remaining in the container.
/// </summary>
[ViewVariables]
public int EmptyVolume => MaxVolume - CurrentVolume;
/// <summary>
/// The current blended color of all the reagents in the container.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public Color SubstanceColor { get; private set; }
/// <summary>
/// The current capabilities of this container (is the top open to pour? can I inject it into another object?).
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public SolutionCaps Capabilities
{
get => _capabilities;
set => _capabilities = value;
}
public IReadOnlyList<Solution.ReagentQuantity> ReagentList => _containedSolution.Contents;
/// <summary>
/// Shortcut for Capabilities PourIn flag to avoid binary operators.
/// </summary>
public bool CanPourIn => (Capabilities & SolutionCaps.PourIn) != 0;
/// <summary>
/// Shortcut for Capabilities PourOut flag to avoid binary operators.
/// </summary>
public bool CanPourOut => (Capabilities & SolutionCaps.PourOut) != 0;
/// <summary>
/// Shortcut for Capabilities Injectable flag
/// </summary>
public bool Injectable => (Capabilities & SolutionCaps.Injectable) != 0;
/// <summary>
/// Shortcut for Capabilities Injector flag
/// </summary>
public bool Injector => (Capabilities & SolutionCaps.Injector) != 0;
/// <inheritdoc />
public override string Name => "Solution";
/// <inheritdoc />
public sealed override uint? NetID => ContentNetIDs.SOLUTION;
/// <inheritdoc />
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _maxVolume, "maxVol", 0);
serializer.DataField(ref _containedSolution, "contents", _containedSolution);
serializer.DataField(ref _capabilities, "caps", SolutionCaps.None);
}
/// <inheritdoc />
protected override void Startup()
{
base.Startup();
RecalculateColor();
}
/// <inheritdoc />
protected override void Shutdown()
{
base.Shutdown();
_containedSolution.RemoveAllSolution();
_containedSolution = new Solution();
}
public void RemoveAllSolution()
{
_containedSolution.RemoveAllSolution();
OnSolutionChanged();
}
public bool TryRemoveReagent(string reagentId, int quantity)
{
if (!ContainsReagent(reagentId, out var currentQuantity)) return false;
_containedSolution.RemoveReagent(reagentId, quantity);
OnSolutionChanged();
return true;
}
/// <summary>
/// Attempt to remove the specified quantity from this solution
/// </summary>
/// <param name="quantity">Quantity of this solution to remove</param>
/// <returns>Whether or not the solution was successfully removed</returns>
public bool TryRemoveSolution(int quantity)
{
if (CurrentVolume == 0)
return false;
_containedSolution.RemoveSolution(quantity);
OnSolutionChanged();
return true;
}
public Solution SplitSolution(int quantity)
{
var solutionSplit = _containedSolution.SplitSolution(quantity);
OnSolutionChanged();
return solutionSplit;
}
protected void RecalculateColor()
{
if(_containedSolution.TotalVolume == 0)
SubstanceColor = Color.White;
Color mixColor = default;
float runningTotalQuantity = 0;
foreach (var reagent in _containedSolution)
{
runningTotalQuantity += reagent.Quantity;
if(!_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype proto))
continue;
if (mixColor == default)
mixColor = proto.SubstanceColor;
mixColor = BlendRGB(mixColor, proto.SubstanceColor, reagent.Quantity / runningTotalQuantity);
}
}
private Color BlendRGB(Color rgb1, Color rgb2, float amount)
{
var r = (float)Math.Round(rgb1.R + (rgb2.R - rgb1.R) * amount, 1);
var g = (float)Math.Round(rgb1.G + (rgb2.G - rgb1.G) * amount, 1);
var b = (float)Math.Round(rgb1.B + (rgb2.B - rgb1.B) * amount, 1);
var alpha = (float)Math.Round(rgb1.A + (rgb2.A - rgb1.A) * amount, 1);
return new Color(r, g, b, alpha);
}
/// <inheritdoc />
public override ComponentState GetComponentState()
{
return new SolutionComponentState();
}
/// <inheritdoc />
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
base.HandleComponentState(curState, nextState);
if(curState == null)
return;
var compState = (SolutionComponentState)curState;
//TODO: Make me work!
}
[Serializable, NetSerializable]
public class SolutionComponentState : ComponentState
{
public SolutionComponentState() : base(ContentNetIDs.SOLUTION) { }
}
/// <summary>
/// Check if the solution contains the specified reagent.
/// </summary>
/// <param name="reagentId">The reagent to check for.</param>
/// <param name="quantity">Output the quantity of the reagent if it is contained, 0 if it isn't.</param>
/// <returns>Return true if the solution contains the reagent.</returns>
public bool ContainsReagent(string reagentId, out int quantity)
{
foreach (var reagent in _containedSolution.Contents)
{
if (reagent.ReagentId == reagentId)
{
quantity = reagent.Quantity;
return true;
}
}
quantity = 0;
return false;
}
protected virtual void OnSolutionChanged()
{
SolutionChanged?.Invoke();
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.Serialization;
namespace Content.Shared.GameObjects.Components.Command
{
public class SharedCommunicationsConsoleComponent : Component
{
public override string Name => "CommunicationsConsole";
}
[Serializable, NetSerializable]
public class CommunicationsConsoleInterfaceState : BoundUserInterfaceState
{
public readonly TimeSpan? ExpectedCountdownEnd;
public readonly bool CountdownStarted;
public CommunicationsConsoleInterfaceState(TimeSpan? expectedCountdownEnd = null)
{
ExpectedCountdownEnd = expectedCountdownEnd;
CountdownStarted = expectedCountdownEnd != null;
}
}
[Serializable, NetSerializable]
public class CommunicationsConsoleCallEmergencyShuttleMessage : BoundUserInterfaceMessage
{
public CommunicationsConsoleCallEmergencyShuttleMessage()
{
}
}
[Serializable, NetSerializable]
public class CommunicationsConsoleRecallEmergencyShuttleMessage : BoundUserInterfaceMessage
{
public CommunicationsConsoleRecallEmergencyShuttleMessage()
{
}
}
[Serializable, NetSerializable]
public enum CommunicationsConsoleUiKey
{
Key
}
}

View File

@@ -0,0 +1,29 @@
using System;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
namespace Content.Shared.GameObjects.Components.Observer
{
public class SharedGhostComponent : Component
{
public override string Name => "Ghost";
public override uint? NetID => ContentNetIDs.GHOST;
}
[Serializable, NetSerializable]
public class GhostComponentState : ComponentState
{
public bool CanReturnToBody { get; }
public GhostComponentState(bool canReturnToBody) : base(ContentNetIDs.GHOST)
{
CanReturnToBody = canReturnToBody;
}
}
[Serializable, NetSerializable]
public class ReturnToBodyComponentMessage : ComponentMessage
{
public ReturnToBodyComponentMessage() => Directed = true;
}
}

View File

@@ -1,16 +1,109 @@
using System;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Shared.GameObjects.Components
{
public abstract class SharedStackComponent : Component
{
private const string SerializationCache = "stack";
public sealed override string Name => "Stack";
public sealed override uint? NetID => ContentNetIDs.STACK;
private int _count;
private int _maxCount;
[ViewVariables(VVAccess.ReadWrite)]
public virtual int Count
{
get => _count;
set
{
_count = value;
if (_count <= 0)
{
Owner.Delete();
}
Dirty();
}
}
[ViewVariables]
public int MaxCount
{
get => _maxCount;
private set
{
_maxCount = value;
Dirty();
}
}
[ViewVariables] public int AvailableSpace => MaxCount - Count;
[ViewVariables] public object StackType { get; private set; }
public override void ExposeData(ObjectSerializer serializer)
{
serializer.DataFieldCached(ref _maxCount, "max", 50);
serializer.DataFieldCached(ref _count, "count", MaxCount);
if (!serializer.Reading)
{
return;
}
if (serializer.TryGetCacheData(SerializationCache, out object stackType))
{
StackType = stackType;
return;
}
if (serializer.TryReadDataFieldCached("stacktype", out string raw))
{
var refl = IoCManager.Resolve<IReflectionManager>();
if (refl.TryParseEnumReference(raw, out var @enum))
{
stackType = @enum;
}
else
{
stackType = raw;
}
}
else
{
stackType = Owner.Prototype.ID;
}
serializer.SetCacheData(SerializationCache, stackType);
StackType = stackType;
}
public override ComponentState GetComponentState()
{
return new StackComponentState(Count, MaxCount);
}
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
if (!(curState is StackComponentState cast))
{
return;
}
Count = cast.Count;
MaxCount = cast.MaxCount;
}
[Serializable, NetSerializable]
protected sealed class StackComponentState : ComponentState
private sealed class StackComponentState : ComponentState
{
public int Count { get; }
public int MaxCount { get; }
@@ -22,4 +115,14 @@ namespace Content.Shared.GameObjects.Components
}
}
}
public enum StackType
{
Metal,
Glass,
Cable,
Ointment,
Brutepack,
FloorTileSteel
}
}