Merge branch 'master' into replace-sounds-with-sound-specifier

This commit is contained in:
ShadowCommander
2021-08-10 15:05:49 -07:00
183 changed files with 5472 additions and 2022 deletions

View File

@@ -0,0 +1,54 @@
using Content.Shared.Movement.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.Players;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using System;
using Robust.Shared.GameStates;
using Robust.Shared.Timing;
using Robust.Shared.IoC;
namespace Content.Shared.Chemistry.Components
{
//TODO: refactor movement modifier component because this is a pretty poor solution
[RegisterComponent]
[NetworkedComponent]
public sealed class MovespeedModifierMetabolismComponent : Component, IMoveSpeedModifier
{
[ViewVariables]
public override string Name => "MovespeedModifierMetabolism";
[ViewVariables]
public float WalkSpeedModifier { get; set; }
[ViewVariables]
public float SprintSpeedModifier { get; set; }
/// <summary>
/// When the current modifier is expected to end.
/// </summary>
[ViewVariables]
public TimeSpan ModifierTimer { get; set; } = TimeSpan.Zero;
public override ComponentState GetComponentState(ICommonSession player)
{
return new MovespeedModifierMetabolismComponentState(WalkSpeedModifier, SprintSpeedModifier, ModifierTimer);
}
[Serializable, NetSerializable]
public class MovespeedModifierMetabolismComponentState : ComponentState
{
public float WalkSpeedModifier { get; }
public float SprintSpeedModifier { get; }
public TimeSpan ModifierTimer { get; }
public MovespeedModifierMetabolismComponentState(float walkSpeedModifier, float sprintSpeedModifier, TimeSpan modifierTimer)
{
WalkSpeedModifier = walkSpeedModifier;
SprintSpeedModifier = sprintSpeedModifier;
ModifierTimer = modifierTimer;
}
}
}
}

View File

@@ -0,0 +1,77 @@
using Content.Shared.Chemistry.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Timing;
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Movement.Components;
using static Content.Shared.Chemistry.Components.MovespeedModifierMetabolismComponent;
namespace Content.Shared.Chemistry
{
public class MetabolismMovespeedModifierSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
private readonly List<MovespeedModifierMetabolismComponent> _components = new();
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentHandleState>(OnMovespeedHandleState);
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentStartup>(AddComponent);
}
private void OnMovespeedHandleState(EntityUid uid, MovespeedModifierMetabolismComponent component, ComponentHandleState args)
{
if (args.Current is not MovespeedModifierMetabolismComponentState cast)
return;
if (ComponentManager.TryGetComponent<MovementSpeedModifierComponent>(uid, out var modifier) &&
(!component.WalkSpeedModifier.Equals(cast.WalkSpeedModifier) ||
!component.SprintSpeedModifier.Equals(cast.SprintSpeedModifier)))
{
modifier.RefreshMovementSpeedModifiers();
}
component.WalkSpeedModifier = cast.WalkSpeedModifier;
component.SprintSpeedModifier = cast.SprintSpeedModifier;
component.ModifierTimer = cast.ModifierTimer;
}
private void AddComponent(EntityUid uid, MovespeedModifierMetabolismComponent component, ComponentStartup args)
{
_components.Add(component);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var currentTime = _gameTiming.CurTime;
for (var i = _components.Count - 1; i >= 0; i--)
{
var component = _components[i];
if (component.Deleted)
{
_components.RemoveAt(i);
continue;
}
if (component.ModifierTimer > currentTime) continue;
_components.RemoveAt(i);
ComponentManager.RemoveComponent<MovespeedModifierMetabolismComponent>(component.Owner.Uid);
if (component.Owner.TryGetComponent(out MovementSpeedModifierComponent? modifier))
{
modifier.RefreshMovementSpeedModifiers();
}
}
}
}
}

View File

@@ -1,36 +0,0 @@
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Shared.Chemistry.Metabolizable
{
/// <summary>
/// Default metabolization for reagents. Returns the amount of reagents metabolized without applying effects.
/// Metabolizes reagents at a constant rate, limited by how much is available. Other classes are derived from
/// this class, so that they do not need their own metabolization quantity calculation.
/// </summary>
[DataDefinition]
public class DefaultMetabolizable : IMetabolizable
{
/// <summary>
/// Rate of metabolism in units / second
/// </summary>
[DataField("rate")] public ReagentUnit MetabolismRate { get; set; } = ReagentUnit.New(1);
public virtual ReagentUnit Metabolize(IEntity solutionEntity, string reagentId, float tickTime, ReagentUnit availableReagent)
{
// How much reagent should we metabolize
// The default behaviour is to metabolize at a constant rate, independent of the quantity of reagents.
var amountMetabolized = MetabolismRate * tickTime;
// is that much reagent actually available?
if (availableReagent < amountMetabolized)
{
return availableReagent;
}
return amountMetabolized;
}
}
}

View File

@@ -1,23 +0,0 @@
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.GameObjects;
namespace Content.Shared.Chemistry.Metabolizable
{
/// <summary>
/// Metabolism behavior for a reagent.
/// </summary>
public interface IMetabolizable
{
/// <summary>
/// Metabolize the attached reagent. Return the amount of reagent to be removed from the solution.
/// You shouldn't remove the reagent yourself to avoid invalidating the iterator of the metabolism
/// organ that is processing it's reagents.
/// </summary>
/// <param name="solutionEntity">The entity containing the solution.</param>
/// <param name="reagentId">The reagent id</param>
/// <param name="tickTime">The time since the last metabolism tick in seconds.</param>
/// <param name="availableReagent">Reagent available to be metabolized.</param>
/// <returns>The amount of reagent to be removed. The metabolizing organ should handle removing the reagent.</returns>
ReagentUnit Metabolize(IEntity solutionEntity, string reagentId, float tickTime, ReagentUnit availableReagent);
}
}

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Shared.Chemistry.Reagent
{
/// <summary>
/// Reagent effects describe behavior that occurs when a reagent is ingested and metabolized by some
/// organ. They only trigger when their conditions (<see cref="ReagentEffectCondition"/>
/// </summary>
[ImplicitDataDefinitionForInheritors]
public abstract class ReagentEffect
{
/// <summary>
/// The list of conditions required for the effect to activate. Not required.
/// </summary>
[DataField("conditions")]
public ReagentEffectCondition[]? Conditions;
public abstract void Metabolize(IEntity solutionEntity, Solution.Solution.ReagentQuantity amount);
}
}

View File

@@ -0,0 +1,13 @@
using Content.Shared.Body.Components;
using Content.Shared.Chemistry.Solution;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Shared.Chemistry.Reagent
{
[ImplicitDataDefinitionForInheritors]
public abstract class ReagentEffectCondition
{
public abstract bool Condition(IEntity solutionEntity, Solution.Solution.ReagentQuantity reagent);
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using Content.Shared.Botany;
using Content.Shared.Chemistry.Metabolizable;
using Content.Shared.Chemistry.Reaction;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@@ -16,9 +15,6 @@ namespace Content.Shared.Chemistry.Reagent
[DataDefinition]
public class ReagentPrototype : IPrototype
{
[DataField("metabolism", serverOnly: true)]
private readonly List<IMetabolizable> _metabolism = new() {new DefaultMetabolizable()};
[DataField("tileReactions", serverOnly: true)]
private readonly List<ITileReaction> _tileReactions = new(0);
@@ -60,7 +56,6 @@ namespace Content.Shared.Chemistry.Reagent
public string SpriteReplacementPath { get; } = string.Empty;
//List of metabolism effects this reagent has, should really only be used server-side.
public IReadOnlyList<IMetabolizable> Metabolism => _metabolism;
public IReadOnlyList<ITileReaction> TileReactions => _tileReactions;
public IReadOnlyList<IPlantMetabolizable> PlantMetabolism => _plantMetabolism;

View File

@@ -115,6 +115,27 @@ namespace Content.Shared.Chemistry.Solution
TotalVolume += quantity;
}
/// <summary>
/// Scales the amount of solution.
/// </summary>
/// <param name="scale">The scalar to modify the solution by.</param>
public void ScaleSolution(float scale)
{
if (scale == 1) return;
var tempContents = new List<ReagentQuantity>(_contents);
foreach(ReagentQuantity current in tempContents)
{
if(scale > 1)
{
AddReagent(current.ReagentId, current.Quantity * scale - current.Quantity);
}
else
{
RemoveReagent(current.ReagentId, current.Quantity - current.Quantity * scale);
}
}
}
/// <summary>
/// Returns the amount of a single reagent inside the solution.
/// </summary>