]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
New Traits (#13763)
authorScribbles0 <91828755+Scribbles0@users.noreply.github.com>
Sun, 5 Mar 2023 03:44:13 +0000 (19:44 -0800)
committerGitHub <noreply@github.com>
Sun, 5 Mar 2023 03:44:13 +0000 (23:44 -0400)
Content.Client/Traits/ParacusiaSystem.cs [new file with mode: 0644]
Content.Server/Chemistry/ReagentEffects/Drunk.cs
Content.Server/Traits/Assorted/ParacusiaSystem.cs [new file with mode: 0644]
Content.Shared/Drunk/DrunkSystem.cs
Content.Shared/Traits/Assorted/LightweightDrunkComponent.cs [new file with mode: 0644]
Content.Shared/Traits/Assorted/ParacusiaComponent.cs [new file with mode: 0644]
Content.Shared/Traits/Assorted/SharedParacusiaSystem.cs [new file with mode: 0644]
Resources/Locale/en-US/traits/traits.ftl
Resources/Prototypes/SoundCollections/traits.yml [new file with mode: 0644]
Resources/Prototypes/Traits/disabilities.yml
Resources/Prototypes/Traits/inconveniences.yml

diff --git a/Content.Client/Traits/ParacusiaSystem.cs b/Content.Client/Traits/ParacusiaSystem.cs
new file mode 100644 (file)
index 0000000..c55c123
--- /dev/null
@@ -0,0 +1,74 @@
+using Content.Shared.Traits.Assorted;
+using Content.Client.Camera;
+using Robust.Shared.Random;
+using Robust.Client.GameObjects;
+using Robust.Client.Player;
+using Robust.Shared.Timing;
+
+namespace Content.Client.Traits;
+
+public sealed class ParacusiaSystem : SharedParacusiaSystem
+{
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly IPlayerManager _player = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly SharedAudioSystem _audio = default!;
+    [Dependency] private readonly CameraRecoilSystem _camera = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<ParacusiaComponent, ComponentStartup>(OnComponentStartup);
+        SubscribeLocalEvent<ParacusiaComponent, PlayerDetachedEvent>(OnPlayerDetach);
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        if (!_timing.IsFirstTimePredicted)
+            return;
+
+        if (_player.LocalPlayer?.ControlledEntity is not EntityUid localPlayer)
+            return;
+
+        PlayParacusiaSounds(localPlayer);
+    }
+
+    private void OnComponentStartup(EntityUid uid, ParacusiaComponent component, ComponentStartup args)
+    {
+        component.NextIncidentTime = _timing.CurTime + TimeSpan.FromSeconds(_random.NextFloat(component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents));
+    }
+
+    private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, PlayerDetachedEvent args)
+    {
+        component.Stream?.Stop();
+    }
+
+    private void PlayParacusiaSounds(EntityUid uid)
+    {
+        if (!TryComp<ParacusiaComponent>(uid, out var paracusia))
+            return;
+
+        if (_timing.CurTime <= paracusia.NextIncidentTime)
+            return;
+
+        // Set the new time.
+        var timeInterval = _random.NextFloat(paracusia.MinTimeBetweenIncidents, paracusia.MaxTimeBetweenIncidents);
+        paracusia.NextIncidentTime += TimeSpan.FromSeconds(timeInterval);
+
+        // Offset position where the sound is played
+        var randomOffset =
+            new Vector2
+            (
+                _random.NextFloat(-paracusia.MaxSoundDistance, paracusia.MaxSoundDistance),
+                _random.NextFloat(-paracusia.MaxSoundDistance, paracusia.MaxSoundDistance)
+            );
+
+        var newCoords = Transform(uid).Coordinates.Offset(randomOffset);
+
+        // Play the sound
+        paracusia.Stream = _audio.PlayStatic(paracusia.Sounds, uid, newCoords);
+    }
+
+}
index d844d43d2e8e1a3c3ea80f971df23715e3f95e11..c5d24e362d6b15b067839a5ef76ea919da700f13 100644 (file)
@@ -9,7 +9,7 @@ public sealed class Drunk : ReagentEffect
     ///     BoozePower is how long each metabolism cycle will make the drunk effect last for.
     /// </summary>
     [DataField("boozePower")]
-    public float BoozePower = 2f;
+    public float BoozePower = 3f;
 
     /// <summary>
     ///     Whether speech should be slurred.
diff --git a/Content.Server/Traits/Assorted/ParacusiaSystem.cs b/Content.Server/Traits/Assorted/ParacusiaSystem.cs
new file mode 100644 (file)
index 0000000..2008d17
--- /dev/null
@@ -0,0 +1,8 @@
+using Content.Shared.Traits.Assorted;
+
+namespace Content.Server.Traits.Assorted;
+
+public sealed class ParacusiaSystem : SharedParacusiaSystem
+{
+
+}
index ee9cc34fd0024e845a0ea3fe54d4aa4945a29ce1..f09f260817b18d574e45816d0a12a7b0dcfc959a 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Shared.Speech.EntitySystems;
 using Content.Shared.StatusEffect;
+using Content.Shared.Traits.Assorted;
 
 namespace Content.Shared.Drunk;
 
@@ -19,6 +20,9 @@ public abstract class SharedDrunkSystem : EntitySystem
         if (applySlur)
             _slurredSystem.DoSlur(uid, TimeSpan.FromSeconds(boozePower), status);
 
+        if (TryComp<LightweightDrunkComponent>(uid, out var trait))
+            boozePower *= trait.BoozeStrengthMultiplier;
+
         if (!_statusEffectsSystem.HasStatusEffect(uid, DrunkKey, status))
         {
             _statusEffectsSystem.TryAddStatusEffect<DrunkComponent>(uid, DrunkKey, TimeSpan.FromSeconds(boozePower), true, status);
diff --git a/Content.Shared/Traits/Assorted/LightweightDrunkComponent.cs b/Content.Shared/Traits/Assorted/LightweightDrunkComponent.cs
new file mode 100644 (file)
index 0000000..fda1e3d
--- /dev/null
@@ -0,0 +1,15 @@
+using Robust.Shared.GameStates;
+using Content.Shared.Drunk;
+
+namespace Content.Shared.Traits.Assorted;
+
+/// <summary>
+/// Used for the lightweight trait. DrunkSystem will check for this component and modify the boozePower accordingly if it finds it.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+[Access(typeof(SharedDrunkSystem))]
+public sealed class LightweightDrunkComponent : Component
+{
+    [DataField("boozeStrengthMultiplier"), ViewVariables(VVAccess.ReadWrite)]
+    public float BoozeStrengthMultiplier = 4f;
+}
diff --git a/Content.Shared/Traits/Assorted/ParacusiaComponent.cs b/Content.Shared/Traits/Assorted/ParacusiaComponent.cs
new file mode 100644 (file)
index 0000000..ef86169
--- /dev/null
@@ -0,0 +1,61 @@
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using System;
+using Robust.Shared.Serialization;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Shared.Traits.Assorted;
+
+/// <summary>
+/// This component is used for paracusia, which causes auditory hallucinations.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+[Access(typeof(SharedParacusiaSystem))]
+public sealed class ParacusiaComponent : Component
+{
+    /// <summary>
+    /// The maximum time between incidents in seconds
+    /// </summary>
+    [DataField("maxTimeBetweenIncidents", required: true), ViewVariables(VVAccess.ReadWrite)]
+    public float MaxTimeBetweenIncidents = 30f;
+
+    /// <summary>
+    /// The minimum time between incidents in seconds
+    /// </summary>
+    [DataField("minTimeBetweenIncidents", required: true), ViewVariables(VVAccess.ReadWrite)]
+    public float MinTimeBetweenIncidents = 60f;
+
+    /// <summary>
+    /// How far away at most can the sound be?
+    /// </summary>
+    [DataField("maxSoundDistance", required: true), ViewVariables(VVAccess.ReadWrite)]
+    public float MaxSoundDistance;
+
+    /// <summary>
+    /// The sounds to choose from
+    /// </summary>
+    [DataField("sounds", required: true)]
+    public SoundSpecifier Sounds = default!;
+
+    [DataField("timeBetweenIncidents", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
+    public TimeSpan NextIncidentTime;
+
+    public IPlayingAudioStream? Stream;
+}
+
+[Serializable, NetSerializable]
+public sealed class ParacusiaComponentState : ComponentState
+{
+    public readonly float MaxTimeBetweenIncidents;
+    public readonly float MinTimeBetweenIncidents;
+    public readonly float MaxSoundDistance;
+    public readonly SoundSpecifier Sounds = default!;
+
+    public ParacusiaComponentState(float maxTimeBetweenIncidents, float minTimeBetweenIncidents, float maxSoundDistance, SoundSpecifier sounds)
+    {
+        MaxTimeBetweenIncidents = maxTimeBetweenIncidents;
+        MinTimeBetweenIncidents = minTimeBetweenIncidents;
+        MaxSoundDistance = maxSoundDistance;
+        Sounds = sounds;
+    }
+}
diff --git a/Content.Shared/Traits/Assorted/SharedParacusiaSystem.cs b/Content.Shared/Traits/Assorted/SharedParacusiaSystem.cs
new file mode 100644 (file)
index 0000000..6eb0f6b
--- /dev/null
@@ -0,0 +1,30 @@
+using Content.Shared.GameTicking;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Traits.Assorted;
+
+public abstract class SharedParacusiaSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<ParacusiaComponent, ComponentGetState>(GetCompState);
+        SubscribeLocalEvent<ParacusiaComponent, ComponentHandleState>(HandleCompState);
+    }
+
+    private void GetCompState(EntityUid uid, ParacusiaComponent component, ref ComponentGetState args)
+    {
+        args.State = new ParacusiaComponentState(component.MaxTimeBetweenIncidents, component.MinTimeBetweenIncidents, component.MaxSoundDistance, component.Sounds);
+    }
+
+    private void HandleCompState(EntityUid uid, ParacusiaComponent component, ref ComponentHandleState args)
+    {
+        if (args.Current is not ParacusiaComponentState state)
+            return;
+
+        component.MaxTimeBetweenIncidents = state.MaxTimeBetweenIncidents;
+        component.MinTimeBetweenIncidents = state.MinTimeBetweenIncidents;
+        component.MaxSoundDistance = state.MaxSoundDistance;
+        component.Sounds = state.Sounds;
+    }
+}
index 0700969aaf14f25c57dbdf9ba5b9e76eb3fd8b97..b9ac930021f252c3acd423702eaf39ca46ced9c0 100644 (file)
@@ -10,3 +10,12 @@ trait-sneezing-name = Runny nose
 trait-sneezing-desc = You sneeze and cough uncontrollably
 
 permanent-blindness-trait-examined = [color=lightblue]{CAPITALIZE(POSS-ADJ($target))} eyes are glassy and unfocused. It doesn't seem like {SUBJECT($target)} can see you.[/color]
+
+trait-lightweight-name = Lightweight Drunk
+trait-lightweight-desc = Alcohol has a stronger effect on you
+
+trait-muted-name = Muted
+trait-muted-desc = You can't speak
+
+trait-paracusia-name = Paracusia
+trait-paracusia-desc = You hear sounds that aren't really there
diff --git a/Resources/Prototypes/SoundCollections/traits.yml b/Resources/Prototypes/SoundCollections/traits.yml
new file mode 100644 (file)
index 0000000..5b14054
--- /dev/null
@@ -0,0 +1,76 @@
+- type: soundCollection
+  id: Paracusia
+  files:
+  #- /Audio/Effects/adminhelp.ogg
+  #- /Audio/Machines/Nuke/nuke_alarm.ogg
+  #- /Audio/Misc/emergency_meeting.ogg
+  - /Audio/Effects/countdown.ogg
+  - /Audio/Effects/explosion1.ogg
+  - /Audio/Effects/explosion2.ogg
+  - /Audio/Effects/explosion3.ogg
+  - /Audio/Effects/explosion4.ogg
+  - /Audio/Effects/explosion5.ogg
+  - /Audio/Effects/explosion6.ogg
+  - /Audio/Effects/glass_break1.ogg
+  - /Audio/Effects/glass_break2.ogg
+  - /Audio/Effects/glass_break3.ogg
+  - /Audio/Effects/bodyfall1.ogg
+  - /Audio/Effects/bodyfall2.ogg
+  - /Audio/Effects/bodyfall3.ogg
+  - /Audio/Effects/bodyfall4.ogg
+  - /Audio/Effects/demon_dies.ogg
+  - /Audio/Effects/demon_attack1.ogg
+  - /Audio/Effects/bang.ogg
+  - /Audio/Effects/clang.ogg
+  - /Audio/Effects/metalbreak.ogg
+  - /Audio/Effects/minibombcountdown.ogg
+  - /Audio/Effects/sadtrombone.ogg
+  - /Audio/Effects/sparks1.ogg
+  - /Audio/Effects/sparks2.ogg
+  - /Audio/Effects/sparks3.ogg
+  - /Audio/Effects/sparks4.ogg
+  - /Audio/Effects/radpulse1.ogg
+  - /Audio/Effects/radpulse5.ogg
+  - /Audio/Effects/radpulse9.ogg
+  - /Audio/Effects/Chemistry/bubbles.ogg
+  - /Audio/Machines/airlock_close.ogg
+  - /Audio/Machines/airlock_deny.ogg
+  - /Audio/Machines/airlock_open.ogg
+  - /Audio/Machines/airlock_ext_open.ogg
+  - /Audio/Machines/anomaly_generate.ogg
+  - /Audio/Machines/phasein.ogg
+  - /Audio/Machines/vending_restock_start.ogg
+  - /Audio/Machines/vending_restock_done.ogg
+  - /Audio/Magic/disintegrate.ogg
+  - /Audio/Magic/staff_animation.ogg
+  - /Audio/Weapons/ebladeon.ogg
+  - /Audio/Weapons/smash.ogg
+  - /Audio/Weapons/bladeslice.ogg
+  - /Audio/Weapons/punch1.ogg
+  - /Audio/Weapons/punch2.ogg
+  - /Audio/Weapons/punch3.ogg
+  - /Audio/Weapons/punch4.ogg
+  - /Audio/Weapons/genhit1.ogg
+  - /Audio/Weapons/Guns/Hits/bullet_hit.ogg
+  - /Audio/Weapons/Guns/Hits/snap.ogg
+  - /Audio/Weapons/Guns/Gunshots/atreides.ogg
+  - /Audio/Weapons/Guns/Gunshots/c-20r.ogg
+  - /Audio/Weapons/Guns/Gunshots/pistol.ogg
+  - /Audio/Items/bikehorn.ogg
+  - /Audio/Items/Toys/weh.ogg
+  - /Audio/Items/Toys/toysqueak1.ogg
+  - /Audio/Items/Toys/toysqueak2.ogg
+  - /Audio/Items/Toys/toysqueak3.ogg
+  - /Audio/Voice/Talk/lizard.ogg
+  - /Audio/Voice/Talk/pai.ogg
+  - /Audio/Voice/Talk/speak_1.ogg
+  - /Audio/Voice/Talk/speak_2_ask.ogg
+  - /Audio/Voice/Talk/speak_3_exclaim.ogg
+  - /Audio/Voice/Human/malescream_1.ogg
+  - /Audio/Voice/Human/malescream_6.ogg
+  - /Audio/Voice/Human/femalescream_2.ogg
+  - /Audio/Voice/Human/femalescream_4.ogg
+  - /Audio/Voice/Zombie/zombie-1.ogg
+  - /Audio/Voice/Zombie/zombie-2.ogg
+  - /Audio/Voice/Zombie/zombie-3.ogg
+  - /Audio/Voice/Vox/shriek1.ogg
index c5ed02c94616e703b5b86c22a2aba17f1606396d..c6deeff61f2723958263f6cdd6abdeec180811aa 100644 (file)
   name: trait-pacifist-name
   components:
     - type: Pacifist
+
+- type: trait
+  id: Paracusia
+  name: trait-paracusia-name
+  description: trait-paracusia-desc
+  components:
+    - type: Paracusia
+      minTimeBetweenIncidents: 0.1
+      maxTimeBetweenIncidents: 300
+      maxSoundDistance: 7
+      sounds:
+        collection: Paracusia
+
+- type: trait
+  id: Muted
+  name: trait-muted-name
+  description: trait-muted-desc
+  components:
+    - type: Muted
index de25174c4308d0847b9cd9ffdcd165a55cc5cce4..54fbd252ccf4581de7305bf8ae67ef32991c9033 100644 (file)
         params:
           variation: 0.2
       timeBetweenIncidents: 0.3, 300
+
+- type: trait
+  id: LightweightDrunk
+  name: trait-lightweight-name
+  description: trait-lightweight-desc
+  components:
+    - type: LightweightDrunk
+      boozeStrengthMultiplier: 2