[NEW STATUS SYSTEM] Drunkenness, Stuttering, Slurred Speech, and Bloodloss (#38678)
* The only commit that matters * I had to stop playing with my cat to push this change * Yaml removal * Proper drunk status effect and remove shitcode * Review changes * whoops * Whoops x2 * Update master fix merge conflicts * Fix merge conflicts * Dunk Component kill * MORE RELAYS * Holy fucking breaking changes * Ough * 46 file diff * Fix bad commits * Erm what the test fail? * Fix those last two * Merge conflicts * Me when I fix the merge conflicts --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d737e39a98
commit
6b73d320b9
@@ -198,12 +198,6 @@ public sealed partial class BloodstreamComponent : Component
|
||||
[ViewVariables]
|
||||
public Entity<SolutionComponent>? TemporarySolution;
|
||||
|
||||
/// <summary>
|
||||
/// Variable that stores the amount of status time added by having a low blood level.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan StatusTime;
|
||||
|
||||
/// <summary>
|
||||
/// Alert to show when bleeding.
|
||||
/// </summary>
|
||||
|
||||
@@ -6,7 +6,6 @@ using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Drunk;
|
||||
using Content.Shared.EntityEffects.Effects;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Fluids;
|
||||
@@ -16,7 +15,7 @@ using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Content.Shared.Rejuvenate;
|
||||
using Content.Shared.Speech.EntitySystems;
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -27,17 +26,18 @@ namespace Content.Shared.Body.Systems;
|
||||
|
||||
public abstract class SharedBloodstreamSystem : EntitySystem
|
||||
{
|
||||
public static readonly EntProtoId Bloodloss = "StatusEffectBloodloss";
|
||||
|
||||
[Dependency] protected readonly SharedSolutionContainerSystem SolutionContainer = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedPuddleSystem _puddle = default!;
|
||||
[Dependency] private readonly StatusEffectsSystem _status = default!;
|
||||
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
[Dependency] private readonly SharedDrunkSystem _drunkSystem = default!;
|
||||
[Dependency] private readonly SharedStutteringSystem _stutteringSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -100,15 +100,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem
|
||||
// Apply dizziness as a symptom of bloodloss.
|
||||
// The effect is applied in a way that it will never be cleared without being healthy.
|
||||
// Multiplying by 2 is arbitrary but works for this case, it just prevents the time from running out
|
||||
_drunkSystem.TryApplyDrunkenness(
|
||||
uid,
|
||||
(float)bloodstream.AdjustedUpdateInterval.TotalSeconds * 2,
|
||||
applySlur: false);
|
||||
_stutteringSystem.DoStutter(uid, bloodstream.AdjustedUpdateInterval * 2, refresh: false);
|
||||
|
||||
// storing the drunk and stutter time so we can remove it independently from other effects additions
|
||||
bloodstream.StatusTime += bloodstream.AdjustedUpdateInterval * 2;
|
||||
DirtyField(uid, bloodstream, nameof(BloodstreamComponent.StatusTime));
|
||||
_status.TrySetStatusEffectDuration(uid, Bloodloss);
|
||||
}
|
||||
else if (!_mobStateSystem.IsDead(uid))
|
||||
{
|
||||
@@ -118,12 +110,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem
|
||||
bloodstream.BloodlossHealDamage * bloodPercentage,
|
||||
ignoreResistances: true, interruptsDoAfters: false);
|
||||
|
||||
// Remove the drunk effect when healthy. Should only remove the amount of drunk and stutter added by low blood level
|
||||
_drunkSystem.TryRemoveDrunkenessTime(uid, bloodstream.StatusTime.TotalSeconds);
|
||||
_stutteringSystem.DoRemoveStutterTime(uid, bloodstream.StatusTime.TotalSeconds);
|
||||
// Reset the drunk and stutter time to zero
|
||||
bloodstream.StatusTime = TimeSpan.Zero;
|
||||
DirtyField(uid, bloodstream, nameof(BloodstreamComponent.StatusTime));
|
||||
_status.TryRemoveStatusEffect(uid, Bloodloss);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Drunk;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class DrunkComponent : Component { }
|
||||
11
Content.Shared/Drunk/DrunkStatusEffectComponent.cs
Normal file
11
Content.Shared/Drunk/DrunkStatusEffectComponent.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Drunk;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by a status effect entity to apply the <see cref="DrunkComponent"/> to an entity.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class DrunkStatusEffectComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using Content.Shared.Speech.EntitySystems;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.Traits.Assorted;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Drunk;
|
||||
|
||||
public abstract class SharedDrunkSystem : EntitySystem
|
||||
{
|
||||
public static readonly ProtoId<StatusEffectPrototype> DrunkKey = "Drunk";
|
||||
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
|
||||
[Dependency] private readonly SharedSlurredSystem _slurredSystem = default!;
|
||||
|
||||
public void TryApplyDrunkenness(EntityUid uid, float boozePower, bool applySlur = true,
|
||||
StatusEffectsComponent? status = null)
|
||||
{
|
||||
if (!Resolve(uid, ref status, false))
|
||||
return;
|
||||
|
||||
if (TryComp<LightweightDrunkComponent>(uid, out var trait))
|
||||
boozePower *= trait.BoozeStrengthMultiplier;
|
||||
|
||||
if (applySlur)
|
||||
{
|
||||
_slurredSystem.DoSlur(uid, TimeSpan.FromSeconds(boozePower), status);
|
||||
}
|
||||
|
||||
if (!_statusEffectsSystem.HasStatusEffect(uid, DrunkKey, status))
|
||||
{
|
||||
_statusEffectsSystem.TryAddStatusEffect<DrunkComponent>(uid, DrunkKey, TimeSpan.FromSeconds(boozePower), true, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
_statusEffectsSystem.TryAddTime(uid, DrunkKey, TimeSpan.FromSeconds(boozePower), status);
|
||||
}
|
||||
}
|
||||
|
||||
public void TryRemoveDrunkenness(EntityUid uid)
|
||||
{
|
||||
_statusEffectsSystem.TryRemoveStatusEffect(uid, DrunkKey);
|
||||
}
|
||||
public void TryRemoveDrunkenessTime(EntityUid uid, double timeRemoved)
|
||||
{
|
||||
_statusEffectsSystem.TryRemoveTime(uid, DrunkKey, TimeSpan.FromSeconds(timeRemoved));
|
||||
}
|
||||
|
||||
}
|
||||
50
Content.Shared/Drunk/SharedDrunkSystem.cs
Normal file
50
Content.Shared/Drunk/SharedDrunkSystem.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Content.Shared.Speech.EntitySystems;
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Content.Shared.Traits.Assorted;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Drunk;
|
||||
|
||||
public abstract class SharedDrunkSystem : EntitySystem
|
||||
{
|
||||
public static EntProtoId Drunk = "StatusEffectDrunk";
|
||||
public static EntProtoId Woozy = "StatusEffectWoozy";
|
||||
|
||||
/* I have no clue why this magic number was chosen, I copied it from slur system and needed it for the overlay
|
||||
If you have a more intelligent magic number be my guest to completely explode this value.
|
||||
There were no comments as to why this value was chosen three years ago. */
|
||||
public static float MagicNumber = 1100f;
|
||||
|
||||
[Dependency] protected readonly StatusEffectsSystem Status = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<LightweightDrunkComponent, DrunkEvent>(OnLightweightDrinking);
|
||||
}
|
||||
|
||||
public void TryApplyDrunkenness(EntityUid uid, TimeSpan boozePower)
|
||||
{
|
||||
var ev = new DrunkEvent(boozePower);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
Status.TryAddStatusEffectDuration(uid, Drunk, ev.Duration);
|
||||
}
|
||||
|
||||
public void TryRemoveDrunkenness(EntityUid uid)
|
||||
{
|
||||
Status.TryRemoveStatusEffect(uid, Drunk);
|
||||
}
|
||||
|
||||
public void TryRemoveDrunkennessTime(EntityUid uid, TimeSpan boozePower)
|
||||
{
|
||||
Status.TryAddTime(uid, Drunk, - boozePower);
|
||||
}
|
||||
|
||||
private void OnLightweightDrinking(Entity<LightweightDrunkComponent> entity, ref DrunkEvent args)
|
||||
{
|
||||
args.Duration *= entity.Comp.BoozeStrengthMultiplier;
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct DrunkEvent(TimeSpan Duration);
|
||||
}
|
||||
@@ -9,13 +9,7 @@ public sealed partial class Drunk : EntityEffect
|
||||
/// BoozePower is how long each metabolism cycle will make the drunk effect last for.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float BoozePower = 3f;
|
||||
|
||||
/// <summary>
|
||||
/// Whether speech should be slurred.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool SlurSpeech = true;
|
||||
public TimeSpan BoozePower = TimeSpan.FromSeconds(3f);
|
||||
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
|
||||
=> Loc.GetString("reagent-effect-guidebook-drunk", ("chance", Probability));
|
||||
@@ -24,11 +18,10 @@ public sealed partial class Drunk : EntityEffect
|
||||
{
|
||||
var boozePower = BoozePower;
|
||||
|
||||
if (args is EntityEffectReagentArgs reagentArgs) {
|
||||
if (args is EntityEffectReagentArgs reagentArgs)
|
||||
boozePower *= reagentArgs.Scale.Float();
|
||||
}
|
||||
|
||||
var drunkSys = args.EntityManager.EntitySysManager.GetEntitySystem<SharedDrunkSystem>();
|
||||
drunkSys.TryApplyDrunkenness(args.TargetEntity, boozePower, SlurSpeech);
|
||||
drunkSys.TryApplyDrunkenness(args.TargetEntity, boozePower);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using Content.Shared.StatusEffect;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Speech.EntitySystems;
|
||||
|
||||
public abstract class SharedSlurredSystem : EntitySystem
|
||||
{
|
||||
public static readonly EntProtoId Stutter = "StatusEffectSlurred";
|
||||
|
||||
public virtual void DoSlur(EntityUid uid, TimeSpan time, StatusEffectsComponent? status = null) { }
|
||||
}
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Speech.EntitySystems;
|
||||
|
||||
public abstract class SharedStutteringSystem : EntitySystem
|
||||
{
|
||||
public static readonly ProtoId<StatusEffectPrototype> StutterKey = "Stutter";
|
||||
public static readonly EntProtoId Stuttering = "StatusEffectStutter";
|
||||
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
|
||||
[Dependency] protected readonly StatusEffectsSystem Status = default!;
|
||||
|
||||
// For code in shared... I imagine we ain't getting accent prediction anytime soon so let's not bother.
|
||||
public virtual void DoStutter(EntityUid uid, TimeSpan time, bool refresh, StatusEffectsComponent? status = null)
|
||||
public virtual void DoStutter(EntityUid uid, TimeSpan time, bool refresh)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void DoRemoveStutterTime(EntityUid uid, double timeRemoved)
|
||||
public virtual void DoRemoveStutterTime(EntityUid uid, TimeSpan timeRemoved)
|
||||
{
|
||||
_statusEffectsSystem.TryRemoveTime(uid, StutterKey, TimeSpan.FromSeconds(timeRemoved));
|
||||
}
|
||||
|
||||
public void DoRemoveStutter(EntityUid uid, double timeRemoved)
|
||||
public virtual void DoRemoveStutter(EntityUid uid)
|
||||
{
|
||||
_statusEffectsSystem.TryRemoveStatusEffect(uid, StutterKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Rejuvenate;
|
||||
using Content.Shared.Speech;
|
||||
using Content.Shared.StatusEffectNew.Components;
|
||||
using Content.Shared.Stunnable;
|
||||
using Robust.Shared.Player;
|
||||
@@ -23,6 +24,8 @@ public sealed partial class StatusEffectsSystem
|
||||
|
||||
SubscribeLocalEvent<StatusEffectContainerComponent, StandUpAttemptEvent>(RefRelayStatusEffectEvent);
|
||||
SubscribeLocalEvent<StatusEffectContainerComponent, StunEndAttemptEvent>(RefRelayStatusEffectEvent);
|
||||
|
||||
SubscribeLocalEvent<StatusEffectContainerComponent, AccentGetEvent>(RelayStatusEffectEvent);
|
||||
}
|
||||
|
||||
private void RefRelayStatusEffectEvent<T>(EntityUid uid, StatusEffectContainerComponent component, ref T args) where T : struct
|
||||
|
||||
Reference in New Issue
Block a user