Fix Being Drunk! (#41002)

* Drunk moment

* push

* fix test fails + a smidge of cleanup

* two smidges of cleanup

* Unpredicted so don't need the workaround

---------

Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
This commit is contained in:
Princess Cheeseballs
2025-10-21 13:12:36 -07:00
committed by GitHub
parent 04a2c2e968
commit 4aac3dbc9d
9 changed files with 47 additions and 47 deletions

View File

@@ -27,6 +27,15 @@ public sealed class DrunkOverlay : Overlay
private const float VisualThreshold = 10.0f; private const float VisualThreshold = 10.0f;
private const float PowerDivisor = 250.0f; private const float PowerDivisor = 250.0f;
/// <remarks>
/// This is a magic number based on my person preference of how quickly the bloodloss effect should kick in.
/// It is entirely arbitrary, and you should change it if it sucks.
/// Honestly should be refactored to be based on amount of blood lost but that's out of scope for what I'm doing atm.
/// Also caps all booze visual effects to a max intensity of 100 seconds or 100 booze power.
/// </remarks>
private const float MaxBoozePower = 100f;
private const float BoozePowerScale = 8f;
private float _visualScale = 0; private float _visualScale = 0;
@@ -50,15 +59,9 @@ public sealed class DrunkOverlay : Overlay
var time = status.Item2; var time = status.Item2;
var power = SharedDrunkSystem.MagicNumber; var power = time == null ? MaxBoozePower : (float) Math.Min((time - _timing.CurTime).Value.TotalSeconds, MaxBoozePower);
if (time != null) CurrentBoozePower += BoozePowerScale * (power - CurrentBoozePower) * args.DeltaSeconds / (power+1);
{
var curTime = _timing.CurTime;
power = (float) (time - curTime).Value.TotalSeconds;
}
CurrentBoozePower += 8f * (power * 0.5f - CurrentBoozePower) * args.DeltaSeconds / (power+1);
} }
protected override bool BeforeDraw(in OverlayDrawArgs args) protected override bool BeforeDraw(in OverlayDrawArgs args)

View File

@@ -16,6 +16,7 @@ using Content.Shared.EntityEffects.Effects.Solution;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Random.Helpers;
using Robust.Shared.Collections; using Robust.Shared.Collections;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
@@ -199,6 +200,9 @@ public sealed class MetabolizerSystem : SharedMetabolizerSystem
if (scale < effect.MinScale) if (scale < effect.MinScale)
continue; continue;
if (effect.Probability < 1.0f && !_random.Prob(effect.Probability))
continue;
// See if conditions apply // See if conditions apply
if (effect.Conditions != null && !CanMetabolizeEffect(actualEntity, ent, soln.Value, effect.Conditions)) if (effect.Conditions != null && !CanMetabolizeEffect(actualEntity, ent, soln.Value, effect.Conditions))
continue; continue;

View File

@@ -15,6 +15,16 @@ public sealed class SlurredSystem : SharedSlurredSystem
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IGameTiming _timing = default!;
/// <summary>
/// Divisor applied to total seconds used to get the odds of slurred speech occuring.
/// </summary>
private const float SlurredModifier = 1100f;
/// <summary>
/// Minimum amount of time on the slurred accent for it to start taking effect.
/// </summary>
private const float SlurredThreshold = 80f;
public override void Initialize() public override void Initialize()
{ {
SubscribeLocalEvent<SlurredAccentComponent, AccentGetEvent>(OnAccent); SubscribeLocalEvent<SlurredAccentComponent, AccentGetEvent>(OnAccent);
@@ -32,15 +42,9 @@ public sealed class SlurredSystem : SharedSlurredSystem
return 0; return 0;
// This is a magic number. Why this value? No clue it was made 3 years before I refactored this. // This is a magic number. Why this value? No clue it was made 3 years before I refactored this.
var magic = SharedDrunkSystem.MagicNumber; var magic = time.Item2 == null ? SlurredModifier : (float) (time.Item2 - _timing.CurTime).Value.TotalSeconds - SlurredThreshold;
if (time.Item2 != null) return Math.Clamp(magic / SlurredModifier, 0f, 1f);
{
var curTime = _timing.CurTime;
magic = (float) (time.Item2 - curTime).Value.TotalSeconds - 80f;
}
return Math.Clamp(magic / SharedDrunkSystem.MagicNumber, 0f, 1f);
} }
private void OnAccent(Entity<SlurredAccentComponent> entity, ref AccentGetEvent args) private void OnAccent(Entity<SlurredAccentComponent> entity, ref AccentGetEvent args)

View File

@@ -1,4 +1,3 @@
using Content.Shared.Speech.EntitySystems;
using Content.Shared.StatusEffectNew; using Content.Shared.StatusEffectNew;
using Content.Shared.Traits.Assorted; using Content.Shared.Traits.Assorted;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -8,12 +7,6 @@ namespace Content.Shared.Drunk;
public abstract class SharedDrunkSystem : EntitySystem public abstract class SharedDrunkSystem : EntitySystem
{ {
public static EntProtoId Drunk = "StatusEffectDrunk"; 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!; [Dependency] protected readonly StatusEffectsSystem Status = default!;

View File

@@ -1,5 +1,4 @@
using Content.Shared.StatusEffectNew; using Content.Shared.StatusEffectNew;
using Content.Shared.StatusEffectNew.Components;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -10,12 +9,12 @@ namespace Content.Shared.EntityEffects.Effects.StatusEffects;
/// Duration is modified by scale. /// Duration is modified by scale.
/// </summary> /// </summary>
/// <inheritdoc cref="EntityEffectSystem{T,TEffect}"/> /// <inheritdoc cref="EntityEffectSystem{T,TEffect}"/>
public sealed partial class ModifyParalysisEntityEffectSystem : EntityEffectSystem<StatusEffectContainerComponent, ModifyParalysis> public sealed partial class ModifyParalysisEntityEffectSystem : EntityEffectSystem<MetaDataComponent, ModifyParalysis>
{ {
[Dependency] private readonly StatusEffectsSystem _status = default!; [Dependency] private readonly StatusEffectsSystem _status = default!;
[Dependency] private readonly SharedStunSystem _stun = default!; [Dependency] private readonly SharedStunSystem _stun = default!;
protected override void Effect(Entity<StatusEffectContainerComponent> entity, ref EntityEffectEvent<ModifyParalysis> args) protected override void Effect(Entity<MetaDataComponent> entity, ref EntityEffectEvent<ModifyParalysis> args)
{ {
var time = args.Effect.Time * args.Scale; var time = args.Effect.Time * args.Scale;

View File

@@ -1,5 +1,4 @@
using Content.Shared.StatusEffectNew; using Content.Shared.StatusEffectNew;
using Content.Shared.StatusEffectNew.Components;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Shared.EntityEffects.Effects.StatusEffects; namespace Content.Shared.EntityEffects.Effects.StatusEffects;
@@ -9,11 +8,11 @@ namespace Content.Shared.EntityEffects.Effects.StatusEffects;
/// Duration is modified by scale. /// Duration is modified by scale.
/// </summary> /// </summary>
/// <inheritdoc cref="EntityEffectSystem{T,TEffect}"/> /// <inheritdoc cref="EntityEffectSystem{T,TEffect}"/>
public sealed partial class ModifyStatusEffectEntityEffectSystem : EntityEffectSystem<StatusEffectContainerComponent, ModifyStatusEffect> public sealed partial class ModifyStatusEffectEntityEffectSystem : EntityEffectSystem<MetaDataComponent, ModifyStatusEffect>
{ {
[Dependency] private readonly StatusEffectsSystem _status = default!; [Dependency] private readonly StatusEffectsSystem _status = default!;
protected override void Effect(Entity<StatusEffectContainerComponent> entity, ref EntityEffectEvent<ModifyStatusEffect> args) protected override void Effect(Entity<MetaDataComponent> entity, ref EntityEffectEvent<ModifyStatusEffect> args)
{ {
var time = args.Effect.Time * args.Scale; var time = args.Effect.Time * args.Scale;
var delay = args.Effect.Delay; var delay = args.Effect.Delay;

View File

@@ -35,7 +35,8 @@ public sealed partial class StatusEffectComponent : Component
/// <summary> /// <summary>
/// If true, this status effect has been applied. Used to ensure that <see cref="StatusEffectAppliedEvent"/> only fires once. /// If true, this status effect has been applied. Used to ensure that <see cref="StatusEffectAppliedEvent"/> only fires once.
/// </summary> /// </summary>
[DataField, AutoNetworkedField] /// We actually don't want to network this, that way client can apply an effect it's receiving properly!
[DataField]
public bool Applied; public bool Applied;
/// <summary> /// <summary>

View File

@@ -51,7 +51,7 @@ public sealed partial class StatusEffectsSystem : EntitySystem
if (effect.EndEffectTime is null) if (effect.EndEffectTime is null)
continue; continue;
if (!(_timing.CurTime >= effect.EndEffectTime)) if (_timing.CurTime < effect.EndEffectTime)
continue; continue;
if (effect.AppliedTo is null) if (effect.AppliedTo is null)
@@ -81,14 +81,14 @@ public sealed partial class StatusEffectsSystem : EntitySystem
if (args.Container.ID != StatusEffectContainerComponent.ContainerId) if (args.Container.ID != StatusEffectContainerComponent.ContainerId)
return; return;
if (!TryComp<StatusEffectComponent>(args.Entity, out var statusComp)) if (!_effectQuery.TryComp(args.Entity, out var statusComp))
return; return;
// Make sure AppliedTo is set correctly so events can rely on it // Make sure AppliedTo is set correctly so events can rely on it
if (statusComp.AppliedTo != ent) if (statusComp.AppliedTo != ent)
{ {
statusComp.AppliedTo = ent; statusComp.AppliedTo = ent;
Dirty(args.Entity, statusComp); DirtyField(args.Entity, statusComp, nameof(StatusEffectComponent.AppliedTo));
} }
} }
@@ -97,7 +97,7 @@ public sealed partial class StatusEffectsSystem : EntitySystem
if (args.Container.ID != StatusEffectContainerComponent.ContainerId) if (args.Container.ID != StatusEffectContainerComponent.ContainerId)
return; return;
if (!TryComp<StatusEffectComponent>(args.Entity, out var statusComp)) if (!_effectQuery.TryComp(args.Entity, out var statusComp))
return; return;
var ev = new StatusEffectRemovedEvent(ent); var ev = new StatusEffectRemovedEvent(ent);
@@ -127,20 +127,17 @@ public sealed partial class StatusEffectsSystem : EntitySystem
/// <returns>Returns true if the effect is applied.</returns> /// <returns>Returns true if the effect is applied.</returns>
private bool TryApplyStatusEffect(Entity<StatusEffectComponent> statusEffectEnt) private bool TryApplyStatusEffect(Entity<StatusEffectComponent> statusEffectEnt)
{ {
if (!statusEffectEnt.Comp.Applied && if (statusEffectEnt.Comp.Applied ||
statusEffectEnt.Comp.AppliedTo != null && statusEffectEnt.Comp.AppliedTo == null ||
_timing.CurTime >= statusEffectEnt.Comp.StartEffectTime) _timing.CurTime < statusEffectEnt.Comp.StartEffectTime)
{ return false;
var ev = new StatusEffectAppliedEvent(statusEffectEnt.Comp.AppliedTo.Value);
RaiseLocalEvent(statusEffectEnt, ref ev);
statusEffectEnt.Comp.Applied = true; var ev = new StatusEffectAppliedEvent(statusEffectEnt.Comp.AppliedTo.Value);
RaiseLocalEvent(statusEffectEnt, ref ev);
DirtyField(statusEffectEnt, statusEffectEnt.Comp, nameof(StatusEffectComponent.StartEffectTime)); statusEffectEnt.Comp.Applied = true;
return true;
}
return false; return true;
} }
public bool CanAddStatusEffect(EntityUid uid, EntProtoId effectProto) public bool CanAddStatusEffect(EntityUid uid, EntProtoId effectProto)
@@ -207,7 +204,7 @@ public sealed partial class StatusEffectsSystem : EntitySystem
var startTime = delay == null ? TimeSpan.Zero : _timing.CurTime + delay.Value; var startTime = delay == null ? TimeSpan.Zero : _timing.CurTime + delay.Value;
SetStatusEffectStartTime(effect.Value, startTime); SetStatusEffectStartTime(effect.Value, startTime);
TryApplyStatusEffect((effect.Value, effectComp)); TryApplyStatusEffect((statusEffect.Value, effectComp));
return true; return true;
} }

View File

@@ -206,7 +206,7 @@
type: [ Dwarf ] type: [ Dwarf ]
inverted: true inverted: true
- !type:Drunk - !type:Drunk
boozePower: 2 boozePower: 20
- type: reagent - type: reagent
id: Gin id: Gin