From f3656287c5c171552afbebe8848911feebd77f4e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 8 Apr 2023 20:35:52 -0700 Subject: [PATCH 1/8] a system --- .../SightFear/SightFearTraitComponent.cs | 61 ++++++++++++ .../Traits/SightFear/SightFearTraitSystem.cs | 93 +++++++++++++++++++ .../SimpleStation14/Traits/disabilities.yml | 19 ++++ 3 files changed, 173 insertions(+) create mode 100644 Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs create mode 100644 Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs new file mode 100644 index 0000000000..0b0ea91a59 --- /dev/null +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs @@ -0,0 +1,61 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.SimpleStation14.Traits.SightFear +{ + [RegisterComponent] + public sealed class SightFearTraitComponent : Component + { + /// + /// The list of prototypes that the entity can be afraid of. + /// + [DataField("prototypes")] + public List PossiblePrototypes { get; set; } = new List(); + + /// + /// What prototypes they are currently afraid of. + /// Defaults can be specified by the DataField. + /// + [DataField("afraidOfPrototypes")] + public List AfraidOfPrototypes { get; set; } = new List(); + + /// + /// The list of tags that the entity can be afraid of. + /// + [DataField("tags")] + public List PossibleTags { get; set; } = new List(); + + /// + /// What tags they are currently afraid of. + /// Defaults can be specified by the DataField. + /// + [DataField("afraidOfTags")] + public List AfraidOfTags { get; set; } = new List(); + + + /// + /// The chance the entity will have multiple fears as a decimal percent (0-1). + /// Whenever a fear is added, it rolls the chance to add another fear until it fails or it's afraid of everything. + /// + [DataField("multipleFearChance")] + public float MultipleFearChance { get; set; } = 0f; + + /// + /// How many fears can be added by the multiple fear chance. + /// + [DataField("maxFears")] + public int MaxFears { get; set; } = 1; + } + + [NetSerializable, Serializable] + public sealed class SightFearTraitComponentState : ComponentState + { + public List AfraidOfPrototypes { get; } + public List AfraidOfTags { get; } + + public SightFearTraitComponentState(List afraidOfPrototypes, List afraidOfTags) + { + AfraidOfPrototypes = afraidOfPrototypes; + AfraidOfTags = afraidOfTags; + } + } +} diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs new file mode 100644 index 0000000000..7f70b5a105 --- /dev/null +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs @@ -0,0 +1,93 @@ +using Content.Shared.SimpleStation14.Traits.SightFear; +using Robust.Shared.GameStates; +using Robust.Shared.Random; + +namespace Content.Shared.SimpleStation14.Traits.SightFear; + +public sealed class SightFearTraitSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly IEntityManager _entity = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnInit); + + SubscribeLocalEvent(OnGetState); + SubscribeLocalEvent(OnHandleState); + } + + private void OnInit(EntityUid entity, SightFearTraitComponent traitComponent, ComponentInit args) + { + // If there are no possible fears, don't bother. + if (traitComponent.PossiblePrototypes.Count <= 0 && traitComponent.PossibleTags.Count <= 0) + return; + + // Randomly pick a fear. + if (_random.Prob(0.5f)) + traitComponent.AfraidOfPrototypes.Add(_random.PickAndTake(traitComponent.PossiblePrototypes)); + else + traitComponent.AfraidOfTags.Add(_random.PickAndTake(traitComponent.PossibleTags)); + + RecursiveRandom(traitComponent.MultipleFearChance, traitComponent); + } + + + private void OnGetState(EntityUid entity, SightFearTraitComponent traitComponent, ref ComponentGetState args) + { + args.State = new SightFearTraitComponentState(traitComponent.AfraidOfPrototypes, traitComponent.AfraidOfTags); + } + + private void OnHandleState(EntityUid entity, SightFearTraitComponent traitComponent, ref ComponentHandleState args) + { + if (args.Current is not SightFearTraitComponentState state) + return; + + traitComponent.AfraidOfPrototypes = state.AfraidOfPrototypes; + traitComponent.AfraidOfTags = state.AfraidOfTags; + } + + + private void RecursiveRandom(float chance, SightFearTraitComponent traitComponent) + { + if (traitComponent.PossiblePrototypes.Count <= 0 && traitComponent.PossibleTags.Count <= 0) + return; + + if (_random.Prob(0.5f) && traitComponent.PossiblePrototypes.Count > 0) + { + if (!_random.Prob(chance)) + return; + + traitComponent.AfraidOfPrototypes.Add(_random.PickAndTake(traitComponent.PossiblePrototypes)); + RecursiveRandom(chance, traitComponent); + return; + } + + if (traitComponent.PossibleTags.Count > 0) + { + if (!_random.Prob(chance)) + return; + + traitComponent.AfraidOfTags.Add(_random.PickAndTake(traitComponent.PossibleTags)); + RecursiveRandom(chance, traitComponent); + return; + } + } + + + // public override void Update(float frameTime) + // { + // base.Update(frameTime); + // + // if (!_timing.IsFirstTimePredicted) + // return; + // + // var player = _player.LocalPlayer?.ControlledEntity; + // if (player == null) + // return; + // + // if (!_entity.TryGetComponent(player, out var fear)) + // return; + // } +} diff --git a/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml index ea6a229933..3713eedcf2 100644 --- a/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml +++ b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml @@ -60,3 +60,22 @@ messagePerceivedByOthers: hugging-success-generic-others soundPerceivedByOthers: false - type: StutteringAccent + +- type: trait + id: SightFear + name: Fear of Sight # placeholder name + description: You are afraid of seeing things, and will run away from them. # + cost: 2 # + category: Negative + components: + - type: SightFearTrait + prototypes: + - MobHuman + - Spoon + - Fork + - SpoonPlastic + - ForkPlastic + tags: + - DoorBumpOpener + multipleFearChance: 0.75 + maxFears: 3 From 817f1c09bd7b473d300526afdc611b2a397d393e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 3 May 2023 20:19:58 -0700 Subject: [PATCH 2/8] fear system, no functionality --- .../SightFear/SightFearTraitComponent.cs | 60 +--------- .../Traits/SightFear/SightFearTraitSystem.cs | 108 +++++++----------- .../Traits/SightFear/SightFearedComponent.cs | 9 ++ .../Prototypes/Entities/Mobs/NPCs/animals.yml | 3 + .../SimpleStation14/Traits/disabilities.yml | 10 -- .../Prototypes/SimpleStation14/random.yml | 30 +++++ 6 files changed, 88 insertions(+), 132 deletions(-) create mode 100644 Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs create mode 100644 Resources/Prototypes/SimpleStation14/random.yml diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs index 0b0ea91a59..ab08ee4ba8 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs @@ -1,61 +1,9 @@ -using Robust.Shared.Serialization; - namespace Content.Shared.SimpleStation14.Traits.SightFear { - [RegisterComponent] - public sealed class SightFearTraitComponent : Component + [RegisterComponent, AutoGenerateComponentState] + public sealed partial class SightFearTraitComponent : Component { - /// - /// The list of prototypes that the entity can be afraid of. - /// - [DataField("prototypes")] - public List PossiblePrototypes { get; set; } = new List(); - - /// - /// What prototypes they are currently afraid of. - /// Defaults can be specified by the DataField. - /// - [DataField("afraidOfPrototypes")] - public List AfraidOfPrototypes { get; set; } = new List(); - - /// - /// The list of tags that the entity can be afraid of. - /// - [DataField("tags")] - public List PossibleTags { get; set; } = new List(); - - /// - /// What tags they are currently afraid of. - /// Defaults can be specified by the DataField. - /// - [DataField("afraidOfTags")] - public List AfraidOfTags { get; set; } = new List(); - - - /// - /// The chance the entity will have multiple fears as a decimal percent (0-1). - /// Whenever a fear is added, it rolls the chance to add another fear until it fails or it's afraid of everything. - /// - [DataField("multipleFearChance")] - public float MultipleFearChance { get; set; } = 0f; - - /// - /// How many fears can be added by the multiple fear chance. - /// - [DataField("maxFears")] - public int MaxFears { get; set; } = 1; - } - - [NetSerializable, Serializable] - public sealed class SightFearTraitComponentState : ComponentState - { - public List AfraidOfPrototypes { get; } - public List AfraidOfTags { get; } - - public SightFearTraitComponentState(List afraidOfPrototypes, List afraidOfTags) - { - AfraidOfPrototypes = afraidOfPrototypes; - AfraidOfTags = afraidOfTags; - } + [DataField("afraidOf"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public string AfraidOf = string.Empty; } } diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs index 7f70b5a105..f7bd91d0b2 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs @@ -1,5 +1,9 @@ -using Content.Shared.SimpleStation14.Traits.SightFear; -using Robust.Shared.GameStates; +using System.Linq; +using Content.Shared.Examine; +using Content.Shared.Interaction.Helpers; +using Content.Shared.Random; +using Content.Shared.Random.Helpers; +using Robust.Shared.Prototypes; using Robust.Shared.Random; namespace Content.Shared.SimpleStation14.Traits.SightFear; @@ -9,85 +13,57 @@ public sealed class SightFearTraitSystem : EntitySystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; public override void Initialize() { - SubscribeLocalEvent(OnInit); + base.Initialize(); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); + SubscribeLocalEvent(OnComponentInit); } - private void OnInit(EntityUid entity, SightFearTraitComponent traitComponent, ComponentInit args) - { - // If there are no possible fears, don't bother. - if (traitComponent.PossiblePrototypes.Count <= 0 && traitComponent.PossibleTags.Count <= 0) - return; - - // Randomly pick a fear. - if (_random.Prob(0.5f)) - traitComponent.AfraidOfPrototypes.Add(_random.PickAndTake(traitComponent.PossiblePrototypes)); - else - traitComponent.AfraidOfTags.Add(_random.PickAndTake(traitComponent.PossibleTags)); - - RecursiveRandom(traitComponent.MultipleFearChance, traitComponent); - } - - private void OnGetState(EntityUid entity, SightFearTraitComponent traitComponent, ref ComponentGetState args) + private void OnComponentInit(EntityUid uid, SightFearTraitComponent component, ComponentInit args) { - args.State = new SightFearTraitComponentState(traitComponent.AfraidOfPrototypes, traitComponent.AfraidOfTags); - } - - private void OnHandleState(EntityUid entity, SightFearTraitComponent traitComponent, ref ComponentHandleState args) - { - if (args.Current is not SightFearTraitComponentState state) + if (!string.IsNullOrEmpty(component.AfraidOf) || + !_prototype.TryIndex("RandomFears", out var randomFears)) return; - traitComponent.AfraidOfPrototypes = state.AfraidOfPrototypes; - traitComponent.AfraidOfTags = state.AfraidOfTags; + component.AfraidOf = randomFears.Pick(_random); + Dirty(component); } - - private void RecursiveRandom(float chance, SightFearTraitComponent traitComponent) + public override void Update(float frameTime) { - if (traitComponent.PossiblePrototypes.Count <= 0 && traitComponent.PossibleTags.Count <= 0) - return; - - if (_random.Prob(0.5f) && traitComponent.PossiblePrototypes.Count > 0) - { - if (!_random.Prob(chance)) - return; - - traitComponent.AfraidOfPrototypes.Add(_random.PickAndTake(traitComponent.PossiblePrototypes)); - RecursiveRandom(chance, traitComponent); - return; - } + base.Update(frameTime); - if (traitComponent.PossibleTags.Count > 0) + var query = EntityQueryEnumerator(); + while(query.MoveNext(out var uid, out var component)) { - if (!_random.Prob(chance)) - return; - - traitComponent.AfraidOfTags.Add(_random.PickAndTake(traitComponent.PossibleTags)); - RecursiveRandom(chance, traitComponent); - return; + var range = 10f; + if (_entity.TryGetComponent(uid, out var eye)) + range *= (eye.Zoom.X + eye.Zoom.Y) / 2; + + var entities = _lookup.GetEntitiesInRange(Transform(uid).Coordinates, range) + .Where(e => _entity.HasComponent(e)); + + foreach (var entity in entities) + { + if (!_entity.TryGetComponent(uid, out var examiner) || + !examiner.InRangeUnOccluded(Transform(entity).Coordinates, range)) + continue; + + var feared = _entity.GetComponent(entity); + if (!feared.Fears.TryGetValue(component.AfraidOf, out var value)) + continue; + + var distance = (Transform(uid).Coordinates.Position - Transform(entity).Coordinates.Position).Length; + var strength = MathHelper.Lerp(0f, value, 1f - (distance / range)); + if (strength <= 0f) + continue; + + Logger.ErrorS("SightFearTraitSystem", $"Entity {uid} is afraid of {entity} ({component.AfraidOf}) at strength {strength}"); + } } } - - - // public override void Update(float frameTime) - // { - // base.Update(frameTime); - // - // if (!_timing.IsFirstTimePredicted) - // return; - // - // var player = _player.LocalPlayer?.ControlledEntity; - // if (player == null) - // return; - // - // if (!_entity.TryGetComponent(player, out var fear)) - // return; - // } } diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs new file mode 100644 index 0000000000..060592636d --- /dev/null +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Shared.SimpleStation14.Traits.SightFear +{ + [RegisterComponent, AutoGenerateComponentState] + public sealed partial class SightFearedComponent : Component + { + [DataField("fears"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public Dictionary Fears = new(); + } +} diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index feca8517a2..b828d49e54 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -1362,6 +1362,9 @@ types: Piercing: 10 - type: RandomBark + - type: SightFeared + fears: + Arachnophobia: 1 - type: entity name: tarantula diff --git a/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml index 4f7a2630b6..76217d4785 100644 --- a/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml +++ b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml @@ -69,13 +69,3 @@ category: Negative components: - type: SightFearTrait - prototypes: - - MobHuman - - Spoon - - Fork - - SpoonPlastic - - ForkPlastic - tags: - - DoorBumpOpener - multipleFearChance: 0.75 - maxFears: 3 diff --git a/Resources/Prototypes/SimpleStation14/random.yml b/Resources/Prototypes/SimpleStation14/random.yml new file mode 100644 index 0000000000..21495449b0 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/random.yml @@ -0,0 +1,30 @@ +- type: weightedRandom + id: RandomFears + weights: # TODO: Weights + Arachnophobia: 1 # Spiders + Coulrophobia: 1 # Clowns + Nyctophobia: 1 # Darkness + Phasmophobia: 1 # Ghosts + Pyrophobia: 1 # Fire + Trypanophobia: 1 # Needles + Xenophobia: 1 # Aliens + Hemophobia: 1 # Blood + Necrophobia: 1 # Corpses + Ophidiophobia: 1 # Snakes + Ornithophobia: 1 # Birds + Thanatophobia: 1 # Death + # Zoophobia: 1 # Animals + Chronophobia: 1 # Time + Monophobia: 1 # Being alone + Pediophobia: 1 # Dolls + Somniphobia: 1 # Sleep + Technophobia: 1 # Technology + Algophobia: 1 # Pain + Anthropophobia: 1 # People + Astraphobia: 1 # Thunder and lightning + Barophobia: 1 # Gravity + Batrachophobia: 1 # Amphibians + Bibliophobia: 1 # Books + Blennophobia: 1 # Slime + Catoptrophobia: 1 # Mirrors + Dendrophobia: 1 # Trees From 0e87968b2d81c978781ca0723f63d3c6a5bafb14 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 3 May 2023 21:08:35 -0700 Subject: [PATCH 3/8] add feared component to most matching things --- .../SightFear/SightFearTraitComponent.cs | 1 + .../Traits/SightFear/SightFearedComponent.cs | 1 + .../Catalog/Fills/Boxes/medical.yml | 5 +- .../Prototypes/Entities/Effects/lightning.yml | 15 ++++++ .../Prototypes/Entities/Effects/puddle.yml | 3 ++ .../Prototypes/Entities/Mobs/NPCs/animals.yml | 12 +++++ .../Prototypes/Entities/Mobs/NPCs/xeno.yml | 3 ++ .../Entities/Mobs/Player/admin_ghost.yml | 3 ++ .../Prototypes/Entities/Mobs/Player/diona.yml | 4 ++ .../Prototypes/Entities/Mobs/Player/dwarf.yml | 3 ++ .../Prototypes/Entities/Mobs/Player/human.yml | 3 ++ .../Entities/Mobs/Player/observer.yml | 3 ++ .../Entities/Mobs/Player/reptilian.yml | 4 ++ .../Entities/Mobs/Player/skeleton.yml | 4 ++ .../Prototypes/Entities/Mobs/Player/slime.yml | 5 ++ .../Entities/Objects/Decoration/flora.yml | 9 ++++ .../Prototypes/Entities/Objects/Fun/toys.yml | 47 +++++++++++++++++++ .../Entities/Objects/Misc/books.yml | 3 ++ .../Entities/Objects/Misc/implanters.yml | 3 ++ .../Entities/Objects/Shields/shields.yml | 3 ++ .../Entities/Structures/Furniture/beds.yml | 9 ++++ .../Structures/Machines/gravity_generator.yml | 7 ++- .../Entities/Structures/Wallmounts/mirror.yml | 3 ++ .../Entities/Mobs/Player/arachne.yml | 5 ++ .../Entities/Mobs/Player/felinid.yml | 4 ++ .../Nyanotrasen/Entities/Mobs/Player/moth.yml | 5 ++ .../Nyanotrasen/Entities/Mobs/Player/oni.yml | 4 ++ .../Entities/Objects/Books/hyperlinks.yml | 3 ++ .../Entities/Objects/Books/guidebooks.yml | 1 - .../Prototypes/SimpleStation14/random.yml | 24 +++++----- 30 files changed, 185 insertions(+), 14 deletions(-) diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs index ab08ee4ba8..8d52e98ee4 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs @@ -3,6 +3,7 @@ namespace Content.Shared.SimpleStation14.Traits.SightFear [RegisterComponent, AutoGenerateComponentState] public sealed partial class SightFearTraitComponent : Component { + // TODO: Check if the ID is valid [DataField("afraidOf"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public string AfraidOf = string.Empty; } diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs index 060592636d..ceb465694e 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs @@ -3,6 +3,7 @@ namespace Content.Shared.SimpleStation14.Traits.SightFear [RegisterComponent, AutoGenerateComponentState] public sealed partial class SightFearedComponent : Component { + // TODO: Check if the IDs are valid [DataField("fears"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public Dictionary Fears = new(); } diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml b/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml index 4a352b4990..6f71553293 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/medical.yml @@ -12,6 +12,9 @@ layers: - state: box - state: syringe + - type: SightFeared + fears: + Trypanophobia: 2 - type: entity name: pill canister box @@ -72,7 +75,7 @@ layers: - state: box - state: latex - + - type: entity name: nitrile gloves box parent: BoxCardboard diff --git a/Resources/Prototypes/Entities/Effects/lightning.yml b/Resources/Prototypes/Entities/Effects/lightning.yml index 0f5ee91264..bd0d78bb7e 100644 --- a/Resources/Prototypes/Entities/Effects/lightning.yml +++ b/Resources/Prototypes/Entities/Effects/lightning.yml @@ -29,6 +29,9 @@ - type: Tag tags: - HideContextMenu + - type: SightFeared + fears: + Astraphobia: 2.5 # Doesn't show very long, make it spooky - type: entity name: lightning @@ -60,6 +63,9 @@ - type: Lightning canArc: false shockDamage: 30 + - type: SightFeared + fears: + Astraphobia: 3.25 # Spookier - type: entity name: charged lightning @@ -78,6 +84,9 @@ - type: Lightning canArc: true lightningPrototype: ChargedLightning + - type: SightFeared + fears: + Astraphobia: 2.75 - type: entity name: supercharged lightning @@ -103,6 +112,9 @@ softness: 1 autoRot: true castShadows: false + - type: SightFeared + fears: + Astraphobia: 3 - type: entity name: hypercharged lightning @@ -128,3 +140,6 @@ softness: 1 autoRot: true castShadows: false + - type: SightFeared + fears: + Astraphobia: 3.25 diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index 7cf62880c4..3aa594ccbe 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -110,6 +110,9 @@ - type: Puddle overflowVolume: 50 opacityModifier: 8 + - type: SightFeared + fears: + Hemophobia: 0.5 - type: entity name: vomit diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index b828d49e54..b68e3e221e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -212,6 +212,9 @@ - type: SentienceTarget flavorKind: station-event-random-sentience-flavor-organic - type: RandomBark + - type: SightFeared + fears: + Ornithophobia: 0.5 - type: entity name: mallard duck #Quack @@ -1111,6 +1114,9 @@ - type: NoSlip - type: HTN rootTask: IdleEvadeCompound + - type: SightFeared + fears: + Ornithophobia: 0.75 # A bit spookier than the other birds - type: entity name: penguin @@ -1174,6 +1180,9 @@ barks: - Wank barkMultiplier: 0.6 + - type: SightFeared + fears: + Ornithophobia: 0.5 - type: entity name: grenade penguin @@ -1298,6 +1307,9 @@ - Hsssssss - Hss - Hsssss + - type: SightFeared + fears: + Ophidiophobia: 1.5 # Code unique spider prototypes or combine them all into one spider and get a # random sprite state when you spawn it. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 4e102dc57c..78b88f4160 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -125,6 +125,9 @@ - type: ActiveRadio channels: - XenoHive + - type: SightFeared + fears: + Xenophobia: 5 # Fucking SPOOKY # NPC versions diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index 994f876adb..c027a7c871 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -127,3 +127,6 @@ - type: SpellbookUser2 - type: Inventory templateId: aghost + - type: SightFeared + fears: + Phasmophobia: 2 # Spooky ghosts are spooky diff --git a/Resources/Prototypes/Entities/Mobs/Player/diona.yml b/Resources/Prototypes/Entities/Mobs/Player/diona.yml index b5b230fc6a..adffe1736e 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/diona.yml @@ -35,3 +35,7 @@ - type: Faction factions: - NanoTrasen + - type: SightFeared + fears: + Anthropophobia: 0.75 + Xenophobia: 0.75 diff --git a/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml b/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml index d0042cff02..515300f65a 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml @@ -28,3 +28,6 @@ - NanoTrasen - type: MailReceiver - type: PotentialPsionic + - type: SightFeared + fears: + Anthropophobia: 0.8 # A bit shorter, so less scary diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 4cfd0a90f7..d616dcb993 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -35,6 +35,9 @@ - NanoTrasen - type: MailReceiver - type: PotentialPsionic + - type: SightFeared + fears: + Anthropophobia: 1 #Syndie - type: entity diff --git a/Resources/Prototypes/Entities/Mobs/Player/observer.yml b/Resources/Prototypes/Entities/Mobs/Player/observer.yml index 0a81c33761..d9e71fce60 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/observer.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/observer.yml @@ -61,3 +61,6 @@ - type: MovementIgnoreGravity - type: Pullable - type: Speech + - type: SightFeared + fears: + Phasmophobia: 1 diff --git a/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml index 2ea1c9ad1a..542251dc5f 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml @@ -34,3 +34,7 @@ damageRecovery: types: Asphyxiation: -1.0 + - type: SightFeared + fears: + Anthropophobia: 0.75 + Xenophobia: 0.7 diff --git a/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml b/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml index b2b1d9bc3a..dc3b9a79eb 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml @@ -25,6 +25,10 @@ - type: Faction factions: - NanoTrasen + - type: SightFeared + fears: + Anthropophobia: 0.25 + Xenophobia: 0.8 - type: entity name: Skeleton Pirate diff --git a/Resources/Prototypes/Entities/Mobs/Player/slime.yml b/Resources/Prototypes/Entities/Mobs/Player/slime.yml index d82a53f1be..ced0712af5 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/slime.yml @@ -27,3 +27,8 @@ - NanoTrasen - type: MailReceiver - type: PotentialPsionic + - type: SightFeared + fears: + Anthropophobia: 0.75 + Xenophobia: 0.9 + Blennophobia: 1.25 diff --git a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml index 21f2255146..bf2863b7bb 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml @@ -89,6 +89,9 @@ Log: min: 2 max: 8 + - type: SightFeared + fears: + Dendrophobia: 0.75 - type: entity parent: BaseTree @@ -106,6 +109,9 @@ density: 4000 layer: - WallLayer + - type: SightFeared + fears: + Dendrophobia: 0.7 - type: entity parent: BaseTree @@ -123,6 +129,9 @@ density: 2000 layer: - WallLayer + - type: SightFeared + fears: + Dendrophobia: 1 - type: entity parent: BaseTree diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 3ba5a0addd..eb5897311e 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -32,6 +32,9 @@ damage: types: Blunt: 0 + - type: SightFeared + fears: + Pediophobia: 0.75 - type: entity parent: BasePlushie @@ -61,6 +64,9 @@ energy: 2 - type: RgbLightController layers: [ 0 ] + - type: SightFeared + fears: + Pediophobia: 1 - type: entity parent: BasePlushie @@ -70,6 +76,9 @@ components: - type: Sprite state: plushie_nuke + - type: SightFeared + fears: + Pediophobia: 1.5 - type: entity parent: BasePlushie @@ -79,6 +88,9 @@ components: - type: Sprite state: plushie_rouny + - type: SightFeared + fears: + Pediophobia: 1 - type: entity parent: BasePlushie @@ -92,6 +104,9 @@ netsync: false radius: 1.5 energy: 2 + - type: SightFeared + fears: + Pediophobia: 0.25 - type: entity parent: BasePlushie @@ -140,6 +155,9 @@ - type: MeleeWeapon soundHit: path: /Audio/Items/Toys/muffled_weh.ogg + - type: SightFeared + fears: + Pediophobia: 0.5 - type: entity parent: BasePlushie @@ -152,6 +170,9 @@ state: blue - type: Item heldPrefix: blue + - type: SightFeared + fears: + Pediophobia: 1 - type: entity parent: PlushieSharkBlue @@ -185,6 +206,9 @@ components: - type: Sprite state: plushie_ratvar + - type: SightFeared + fears: + Pediophobia: 1.5 - type: entity parent: BasePlushie @@ -194,6 +218,9 @@ components: - type: Sprite state: narplush + - type: SightFeared + fears: + Pediophobia: 1.5 - type: entity @@ -225,6 +252,9 @@ - type: Tag tags: - PlushieCarp + - type: SightFeared + fears: + Pediophobia: 1 - type: entity parent: BasePlushie @@ -234,6 +264,9 @@ components: - type: Sprite state: plushie_slime + - type: SightFeared + fears: + Pediophobia: 0.5 - type: entity parent: BasePlushie @@ -252,6 +285,10 @@ - type: MeleeWeapon soundHit: path: /Audio/Items/Toys/rattle.ogg + - type: SightFeared + fears: + Pediophobia: 1 + Ophidiophobia: 0.75 - type: entity parent: BasePlushie @@ -323,6 +360,10 @@ - type: EmitSoundOnTrigger sound: path: /Audio/Items/Toys/quack.ogg + - type: SightFeared + fears: + Pediophobia: 0.75 + Ornithophobia: 0.5 - type: entity parent: BasePlushie @@ -400,6 +441,9 @@ - type: ItemCooldown - type: UseDelay delay: 15 + - type: SightFeared + fears: + Pediophobia: 1.5 - type: entity parent: BaseItem @@ -875,6 +919,9 @@ base: Sixteen - type: DynamicPrice price: 3 + - type: SightFeared + fears: + Pediophobia: 1 - type: entity parent: BaseItem diff --git a/Resources/Prototypes/Entities/Objects/Misc/books.yml b/Resources/Prototypes/Entities/Objects/Misc/books.yml index d34024d7bb..1a334ef945 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/books.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/books.yml @@ -32,6 +32,9 @@ sound: /Audio/SimpleStation14/Items/Handling/book_drop.ogg - type: EmitSoundOnLand sound: /Audio/SimpleStation14/Items/Handling/book_drop.ogg + - type: SightFeared + fears: + Bibliophobia: 0.75 - type: entity parent: BookBase diff --git a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml index c240be2b51..77f905345d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml @@ -44,6 +44,9 @@ implantOnly: True: {state: broken} False: {state: syringe_base0} + - type: SightFeared + fears: + Trypanophobia: 1 - type: entity id: Implanter diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index eccc1c5c90..c417c45f89 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -217,3 +217,6 @@ SheetGlass: min: 5 max: 5 + - type: SightFeared + fears: + Bibliophobia: 1.5 diff --git a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml index 707ce31db9..0e1813af51 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml @@ -58,6 +58,9 @@ noRot: true - type: Anchorable - type: Pullable + - type: SightFeared + fears: + Somniphobia: 1 - type: entity @@ -78,6 +81,9 @@ - type: Construction graph: bed node: medicalbed + - type: SightFeared + fears: + Somniphobia: 0.7 - type: entity parent: Bed @@ -111,3 +117,6 @@ MaterialWoodPlank: min: 1 max: 5 + - type: SightFeared + fears: + Somniphobia: 0.5 diff --git a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml index 673afa6601..847864c52a 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml @@ -12,7 +12,6 @@ range: 7 sound: path: /Audio/Ambience/Objects/gravity_gen_hum.ogg - - type: Sprite netsync: false sprite: Structures/Machines/gravity_generator.rsi @@ -74,6 +73,9 @@ color: "#a8ffd9" - type: DynamicPrice price: 5000 + - type: SightFeared + fears: + Barophobia: 2.5 # Big scary machine - type: entity id: GravityGeneratorMini @@ -113,3 +115,6 @@ lightRadiusMax: 2.5 - type: DynamicPrice price: 2000 + - type: SightFeared + fears: + Barophobia: 1.75 # Smaller, less scary diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/mirror.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/mirror.yml index b524f099bf..6e0c58e5e4 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/mirror.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/mirror.yml @@ -18,3 +18,6 @@ interfaces: - key: enum.MagicMirrorUiKey.Key type: MagicMirrorBoundUserInterface + - type: SightFeared + fears: + Catoptrophobia: 1.25 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/arachne.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/arachne.yml index 4a2490f438..662e6eb40b 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/arachne.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/arachne.yml @@ -35,3 +35,8 @@ - NanoTrasen - type: MailReceiver - type: PotentialPsionic + - type: SightFeared + fears: + Anthropophobia: 0.9 + Xenophobia: 0.8 + Arachnophobia: 0.9 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/felinid.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/felinid.yml index ce1a761047..af9b0a6cfe 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/felinid.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/felinid.yml @@ -42,3 +42,7 @@ interactSuccessSound: /Audio/Effects/thudswoosh.ogg messagePerceivedByOthers: hugging-success-generic-others - type: PotentialPsionic + - type: SightFeared + fears: + Anthropophobia: 0.9 + Xenophobia: 0.25 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/moth.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/moth.yml index ab0b552a16..b34618165e 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/moth.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/moth.yml @@ -41,3 +41,8 @@ - NanoTrasen - type: MailReceiver - type: PotentialPsionic + - type: SightFeared + fears: + Anthropophobia: 0.5 + Xenophobia: 0.7 + Arachnophobia: 0.2 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/oni.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/oni.yml index d86fcaf1c4..b7da98757e 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/oni.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/oni.yml @@ -36,3 +36,7 @@ interactSuccessSound: /Audio/Effects/thudswoosh.ogg messagePerceivedByOthers: hugging-success-generic-others - type: PotentialPsionic + - type: SightFeared + fears: + Anthropophobia: 0.9 + Xenophobia: 0.75 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Books/hyperlinks.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Books/hyperlinks.yml index 62d22c9e9a..e1ccf614cd 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Books/hyperlinks.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Books/hyperlinks.yml @@ -14,6 +14,9 @@ sound: /Audio/SimpleStation14/Items/Handling/book_drop.ogg - type: EmitSoundOnLand sound: /Audio/SimpleStation14/Items/Handling/book_drop.ogg + - type: SightFeared + fears: + Bibliophobia: 1 # Spooky book that teaches you - type: entity parent: BaseHyperlinkBook diff --git a/Resources/Prototypes/SimpleStation14/Entities/Objects/Books/guidebooks.yml b/Resources/Prototypes/SimpleStation14/Entities/Objects/Books/guidebooks.yml index 099773d5a1..0c3e8215d4 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Objects/Books/guidebooks.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Objects/Books/guidebooks.yml @@ -14,4 +14,3 @@ guides: - AnomalousResearch - Xenoarchaeology - diff --git a/Resources/Prototypes/SimpleStation14/random.yml b/Resources/Prototypes/SimpleStation14/random.yml index 21495449b0..4113fe595d 100644 --- a/Resources/Prototypes/SimpleStation14/random.yml +++ b/Resources/Prototypes/SimpleStation14/random.yml @@ -1,29 +1,31 @@ - type: weightedRandom id: RandomFears - weights: # TODO: Weights + weights: + # TODO: Real weight values + # TODO: Every comment with an ! needs to be implemented somehow or removed Arachnophobia: 1 # Spiders Coulrophobia: 1 # Clowns - Nyctophobia: 1 # Darkness + # Nyctophobia: 1 # Darkness Phasmophobia: 1 # Ghosts - Pyrophobia: 1 # Fire + # Pyrophobia: 1 # Fire Trypanophobia: 1 # Needles Xenophobia: 1 # Aliens Hemophobia: 1 # Blood - Necrophobia: 1 # Corpses + Necrophobia: 1 # !Corpses Ophidiophobia: 1 # Snakes Ornithophobia: 1 # Birds - Thanatophobia: 1 # Death + Thanatophobia: 1 # !Death # Zoophobia: 1 # Animals - Chronophobia: 1 # Time - Monophobia: 1 # Being alone - Pediophobia: 1 # Dolls + Chronophobia: 1 # !Time + # Monophobia: 1 # Being alone + Pediophobia: 1 # Plushies Somniphobia: 1 # Sleep - Technophobia: 1 # Technology - Algophobia: 1 # Pain + Technophobia: 1 # !Technology + Algophobia: 1 # !Pain Anthropophobia: 1 # People Astraphobia: 1 # Thunder and lightning Barophobia: 1 # Gravity - Batrachophobia: 1 # Amphibians + # Batrachophobia: 1 # Amphibians Bibliophobia: 1 # Books Blennophobia: 1 # Slime Catoptrophobia: 1 # Mirrors From 2fb15a6a37d1d40402788e4c20252cdefe7113c9 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 3 May 2023 21:43:49 -0700 Subject: [PATCH 4/8] check if fears are valid on component init --- .../SightFear/SightFearTraitComponent.cs | 29 +++++++++++++++++-- .../Traits/SightFear/SightFearTraitSystem.cs | 29 +++++++++++++++++++ .../Traits/SightFear/SightFearedComponent.cs | 5 ++-- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs index 8d52e98ee4..3c69672c15 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs @@ -1,10 +1,35 @@ +using Content.Shared.FixedPoint; + namespace Content.Shared.SimpleStation14.Traits.SightFear { [RegisterComponent, AutoGenerateComponentState] public sealed partial class SightFearTraitComponent : Component { - // TODO: Check if the ID is valid - [DataField("afraidOf"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + /// + /// The ID of the fear this entity has. + /// Matches this to fearable entities with the same ID and adds to . + /// If empty, a random fear will be picked from the weighted random prototype "RandomFears". + /// + [DataField("afraidOf")] + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] public string AfraidOf = string.Empty; + + /// + /// How much fear this entity has. + /// Goes up to before the effects of fear start to kick in. + /// + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 Fear = 0; + + /// + /// How much fear this entity can have before the effects of fear start to kick in. + /// + [DataField("maxFear")] + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] + public FixedPoint2 MaxFear = 20; + + public float Accumulator = 0.84f; } } diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs index f7bd91d0b2..05bd799575 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs @@ -20,6 +20,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(CheckFeared); } @@ -33,6 +34,26 @@ private void OnComponentInit(EntityUid uid, SightFearTraitComponent component, C Dirty(component); } + private void CheckFeared(EntityUid uid, SightFearedComponent component, ComponentInit args) + { + if (component.Fears.Count == 0) + { + Logger.WarningS("SightFearTraitSystem", $"Entity {uid} has SightFearedComponent without any defined fears."); + return; + } + + if (!_prototype.TryIndex("RandomFears", out var randomFears)) + { + Logger.ErrorS("SightFearTraitSystem", $"Prototype RandomFears could not be found."); + return; + } + + foreach (var fear in component.Fears.Keys.Where(fear => !randomFears.Weights.ContainsKey(fear))) + { + Logger.ErrorS("SightFearTraitSystem", $"Prototype RandomFears does not contain fear {fear} from SightFearedComponent on entity {uid}."); + } + } + public override void Update(float frameTime) { base.Update(frameTime); @@ -40,6 +61,14 @@ public override void Update(float frameTime) var query = EntityQueryEnumerator(); while(query.MoveNext(out var uid, out var component)) { + if (component.Accumulator > 0f) + { + component.Accumulator -= frameTime; + continue; + } + + component.Accumulator = 0.84f; + var range = 10f; if (_entity.TryGetComponent(uid, out var eye)) range *= (eye.Zoom.X + eye.Zoom.Y) / 2; diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs index ceb465694e..a3fedda6a5 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs @@ -3,8 +3,9 @@ namespace Content.Shared.SimpleStation14.Traits.SightFear [RegisterComponent, AutoGenerateComponentState] public sealed partial class SightFearedComponent : Component { - // TODO: Check if the IDs are valid - [DataField("fears"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField("fears")] + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] public Dictionary Fears = new(); } } From 7c72656713dbc77083590ac9bfc20dad730afcd6 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 3 May 2023 22:46:47 -0700 Subject: [PATCH 5/8] alphabetize the fear list --- .../Prototypes/SimpleStation14/random.yml | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Resources/Prototypes/SimpleStation14/random.yml b/Resources/Prototypes/SimpleStation14/random.yml index 4113fe595d..daddddad03 100644 --- a/Resources/Prototypes/SimpleStation14/random.yml +++ b/Resources/Prototypes/SimpleStation14/random.yml @@ -3,30 +3,31 @@ weights: # TODO: Real weight values # TODO: Every comment with an ! needs to be implemented somehow or removed - Arachnophobia: 1 # Spiders - Coulrophobia: 1 # Clowns - # Nyctophobia: 1 # Darkness - Phasmophobia: 1 # Ghosts - # Pyrophobia: 1 # Fire - Trypanophobia: 1 # Needles - Xenophobia: 1 # Aliens - Hemophobia: 1 # Blood - Necrophobia: 1 # !Corpses - Ophidiophobia: 1 # Snakes - Ornithophobia: 1 # Birds - Thanatophobia: 1 # !Death - # Zoophobia: 1 # Animals - Chronophobia: 1 # !Time - # Monophobia: 1 # Being alone - Pediophobia: 1 # Plushies - Somniphobia: 1 # Sleep - Technophobia: 1 # !Technology - Algophobia: 1 # !Pain + #! Alphabetical Order Anthropophobia: 1 # People + ## Algophobia: 1 #! Pain + Arachnophobia: 1 # Spiders Astraphobia: 1 # Thunder and lightning Barophobia: 1 # Gravity # Batrachophobia: 1 # Amphibians Bibliophobia: 1 # Books Blennophobia: 1 # Slime Catoptrophobia: 1 # Mirrors + ## Chronophobia: 1 #! Time + Coulrophobia: 1 # Clowns Dendrophobia: 1 # Trees + Hemophobia: 1 # Blood + # Monophobia: 1 # Being alone + ## Necrophobia: 1 #! Corpses + # Nyctophobia: 1 # Darkness + Ophidiophobia: 1 # Snakes + Ornithophobia: 1 # Birds + Pediophobia: 1 # Plushies + Phasmophobia: 1 # Ghosts + # Pyrophobia: 1 # Fire + Somniphobia: 1 # Sleep + ## Technophobia: 1 #! Technology + ## Thanatophobia: 1 #! Death + Trypanophobia: 1 # Needles + Xenophobia: 1 # Aliens + # Zoophobia: 1 # Animals From 05eddeb7d5f39d7acbc3417986c94a95755343a1 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 3 May 2023 22:47:22 -0700 Subject: [PATCH 6/8] comments and calming --- .../SightFear/SightFearTraitComponent.cs | 30 +++++++++---- .../Traits/SightFear/SightFearTraitSystem.cs | 44 +++++++++++++++++-- .../Traits/SightFear/SightFearedComponent.cs | 3 ++ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs index 3c69672c15..79e726c3b2 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs @@ -6,9 +6,9 @@ namespace Content.Shared.SimpleStation14.Traits.SightFear public sealed partial class SightFearTraitComponent : Component { /// - /// The ID of the fear this entity has. - /// Matches this to fearable entities with the same ID and adds to . - /// If empty, a random fear will be picked from the weighted random prototype "RandomFears". + /// The ID of the fear this entity has + /// Matches this to fearable entities with the same ID and adds to + /// If empty, a random fear will be picked from the weighted random prototype "RandomFears" /// [DataField("afraidOf")] [ViewVariables(VVAccess.ReadWrite)] @@ -17,19 +17,33 @@ public sealed partial class SightFearTraitComponent : Component /// /// How much fear this entity has. - /// Goes up to before the effects of fear start to kick in. + /// Goes up to before the effects of fear start to kick in /// [ViewVariables(VVAccess.ReadWrite)] - public FixedPoint2 Fear = 0; + public double Fear = 0; /// - /// How much fear this entity can have before the effects of fear start to kick in. + /// How much fear this entity can have before the effects of fear start to kick in /// [DataField("maxFear")] [ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] - public FixedPoint2 MaxFear = 20; + public double MaxFear = 20; - public float Accumulator = 0.84f; + /// + /// If this entity is currently afraid + /// + [ViewVariables(VVAccess.ReadWrite)] + public bool Afraid = false; + + /// + /// How fast the entity's fear goes down + /// + [DataField("calmRate")] + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] + public float CalmRate = 1.5f; + + public float Accumulator = 0.084f; } } diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs index 05bd799575..55cef93977 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs @@ -1,5 +1,6 @@ using System.Linq; using Content.Shared.Examine; +using Content.Shared.FixedPoint; using Content.Shared.Interaction.Helpers; using Content.Shared.Random; using Content.Shared.Random.Helpers; @@ -26,28 +27,36 @@ public override void Initialize() private void OnComponentInit(EntityUid uid, SightFearTraitComponent component, ComponentInit args) { + // If the entity already has a fear, don't overwrite it + // Check for RandomFears prototype if (!string.IsNullOrEmpty(component.AfraidOf) || !_prototype.TryIndex("RandomFears", out var randomFears)) return; + // Pick a random fear and use it component.AfraidOf = randomFears.Pick(_random); + + // Mark the component as dirty so it gets synced to the client Dirty(component); } private void CheckFeared(EntityUid uid, SightFearedComponent component, ComponentInit args) { + // Check if the entity has any fears defined if (component.Fears.Count == 0) { Logger.WarningS("SightFearTraitSystem", $"Entity {uid} has SightFearedComponent without any defined fears."); return; } + // Check if the RandomFears prototype exists if (!_prototype.TryIndex("RandomFears", out var randomFears)) { Logger.ErrorS("SightFearTraitSystem", $"Prototype RandomFears could not be found."); return; } + // Check if the fears defined on the entity are in the RandomFears prototype foreach (var fear in component.Fears.Keys.Where(fear => !randomFears.Weights.ContainsKey(fear))) { Logger.ErrorS("SightFearTraitSystem", $"Prototype RandomFears does not contain fear {fear} from SightFearedComponent on entity {uid}."); @@ -58,41 +67,70 @@ public override void Update(float frameTime) { base.Update(frameTime); + // Loop through all entities with SightFearTraitComponent var query = EntityQueryEnumerator(); while(query.MoveNext(out var uid, out var component)) { + // Await the accumulator if (component.Accumulator > 0f) { component.Accumulator -= frameTime; continue; } - component.Accumulator = 0.84f; + // Reset the accumulator + component.Accumulator = 0.084f; + // Get the range the entity can see based on their eye component var range = 10f; if (_entity.TryGetComponent(uid, out var eye)) range *= (eye.Zoom.X + eye.Zoom.Y) / 2; + // Get all entities in range that have a SightFearedComponent var entities = _lookup.GetEntitiesInRange(Transform(uid).Coordinates, range) .Where(e => _entity.HasComponent(e)); + var afraid = false; + + // Loop through all fear inflicters foreach (var entity in entities) { + // Check if the fear inflicter is in range and unoccluded (visible) if (!_entity.TryGetComponent(uid, out var examiner) || !examiner.InRangeUnOccluded(Transform(entity).Coordinates, range)) continue; + // Check if the afraid should be afraid of the fear inflicter var feared = _entity.GetComponent(entity); if (!feared.Fears.TryGetValue(component.AfraidOf, out var value)) continue; + // Calculate the strength of the fear var distance = (Transform(uid).Coordinates.Position - Transform(entity).Coordinates.Position).Length; - var strength = MathHelper.Lerp(0f, value, 1f - (distance / range)); + var strength = MathHelper.Lerp(0f, value, 1f - distance / range); + if (strength <= 0f) continue; - Logger.ErrorS("SightFearTraitSystem", $"Entity {uid} is afraid of {entity} ({component.AfraidOf}) at strength {strength}"); + // Increase the level of fear + afraid = true; + component.Fear += strength; + + // TODO: Do something when afraid + Logger.ErrorS("SightFearTraitSystem", $"Entity {uid} is afraid of {entity} ({component.AfraidOf}) at strength {strength}, now at a fear level of {component.Fear}/{component.MaxFear}."); + } + + component.Afraid = afraid; + + // Decrease the fear level if not afraid this frame + if (!afraid) + { + component.Fear -= frameTime * 1.19047619 * component.CalmRate; // Don't ask about the number. + Logger.ErrorS("SightFearTraitSystem", $"Entity {uid} is not afraid, decreasing fear level to {component.Fear}/{component.MaxFear}."); } + + // Clamp the fear level + component.Fear = Math.Clamp(component.Fear, 0, component.MaxFear * 2); } } } diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs index a3fedda6a5..229dcc1394 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs +++ b/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs @@ -3,6 +3,9 @@ namespace Content.Shared.SimpleStation14.Traits.SightFear [RegisterComponent, AutoGenerateComponentState] public sealed partial class SightFearedComponent : Component { + /// + /// The fears this entity inflicts, and their power + /// [DataField("fears")] [ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] From 768229f51ddebe0b6cb71eb42389eb01560553ec Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 3 May 2023 22:59:45 -0700 Subject: [PATCH 7/8] move to server --- .../Traits/SightFear/SightFearTraitComponent.cs | 11 +++-------- .../Traits/SightFear/SightFearTraitSystem.cs | 9 ++++----- .../Traits/SightFear/SightFearedComponent.cs | 7 +++---- 3 files changed, 10 insertions(+), 17 deletions(-) rename {Content.Shared => Content.Server}/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs (82%) rename {Content.Shared => Content.Server}/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs (96%) rename {Content.Shared => Content.Server}/SimpleStation14/Traits/SightFear/SightFearedComponent.cs (55%) diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs similarity index 82% rename from Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs rename to Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs index 79e726c3b2..f8803b747a 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs +++ b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs @@ -1,9 +1,7 @@ -using Content.Shared.FixedPoint; - -namespace Content.Shared.SimpleStation14.Traits.SightFear +namespace Content.Server.SimpleStation14.Traits.SightFear { - [RegisterComponent, AutoGenerateComponentState] - public sealed partial class SightFearTraitComponent : Component + [RegisterComponent] + public sealed class SightFearTraitComponent : Component { /// /// The ID of the fear this entity has @@ -12,7 +10,6 @@ public sealed partial class SightFearTraitComponent : Component /// [DataField("afraidOf")] [ViewVariables(VVAccess.ReadWrite)] - [AutoNetworkedField] public string AfraidOf = string.Empty; /// @@ -27,7 +24,6 @@ public sealed partial class SightFearTraitComponent : Component /// [DataField("maxFear")] [ViewVariables(VVAccess.ReadWrite)] - [AutoNetworkedField] public double MaxFear = 20; /// @@ -41,7 +37,6 @@ public sealed partial class SightFearTraitComponent : Component /// [DataField("calmRate")] [ViewVariables(VVAccess.ReadWrite)] - [AutoNetworkedField] public float CalmRate = 1.5f; public float Accumulator = 0.084f; diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs similarity index 96% rename from Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs rename to Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs index 55cef93977..36a1a0882c 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs +++ b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs @@ -1,13 +1,12 @@ using System.Linq; using Content.Shared.Examine; -using Content.Shared.FixedPoint; using Content.Shared.Interaction.Helpers; using Content.Shared.Random; using Content.Shared.Random.Helpers; using Robust.Shared.Prototypes; using Robust.Shared.Random; -namespace Content.Shared.SimpleStation14.Traits.SightFear; +namespace Content.Server.SimpleStation14.Traits.SightFear; public sealed class SightFearTraitSystem : EntitySystem { @@ -108,8 +107,8 @@ public override void Update(float frameTime) // Calculate the strength of the fear var distance = (Transform(uid).Coordinates.Position - Transform(entity).Coordinates.Position).Length; var strength = MathHelper.Lerp(0f, value, 1f - distance / range); - - if (strength <= 0f) + + if (strength <= 0f || component.Fear >= component.MaxFear * 2) continue; // Increase the level of fear @@ -123,7 +122,7 @@ public override void Update(float frameTime) component.Afraid = afraid; // Decrease the fear level if not afraid this frame - if (!afraid) + if (!afraid && component.Fear > 0f) { component.Fear -= frameTime * 1.19047619 * component.CalmRate; // Don't ask about the number. Logger.ErrorS("SightFearTraitSystem", $"Entity {uid} is not afraid, decreasing fear level to {component.Fear}/{component.MaxFear}."); diff --git a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs b/Content.Server/SimpleStation14/Traits/SightFear/SightFearedComponent.cs similarity index 55% rename from Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs rename to Content.Server/SimpleStation14/Traits/SightFear/SightFearedComponent.cs index 229dcc1394..7ba4ae5f29 100644 --- a/Content.Shared/SimpleStation14/Traits/SightFear/SightFearedComponent.cs +++ b/Content.Server/SimpleStation14/Traits/SightFear/SightFearedComponent.cs @@ -1,14 +1,13 @@ -namespace Content.Shared.SimpleStation14.Traits.SightFear +namespace Content.Server.SimpleStation14.Traits.SightFear { - [RegisterComponent, AutoGenerateComponentState] - public sealed partial class SightFearedComponent : Component + [RegisterComponent] + public sealed class SightFearedComponent : Component { /// /// The fears this entity inflicts, and their power /// [DataField("fears")] [ViewVariables(VVAccess.ReadWrite)] - [AutoNetworkedField] public Dictionary Fears = new(); } } From 4d8a48096ccc4c89faaa5ee3fa99b4e78aa2731e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Thu, 4 May 2023 20:40:35 -0700 Subject: [PATCH 8/8] heart beat I guess --- .../SightFear/SightFearTraitComponent.cs | 6 ++++- .../Traits/SightFear/SightFearTraitSystem.cs | 25 +++++++++++++++++- .../SimpleStation14/Effects/fastbeat.ogg | Bin 0 -> 5914 bytes .../SimpleStation14/Effects/slowbeat.ogg | Bin 0 -> 7486 bytes 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 Resources/Audio/SimpleStation14/Effects/fastbeat.ogg create mode 100644 Resources/Audio/SimpleStation14/Effects/slowbeat.ogg diff --git a/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs index f8803b747a..255461e40a 100644 --- a/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs +++ b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitComponent.cs @@ -1,3 +1,5 @@ +using Robust.Shared.Audio; + namespace Content.Server.SimpleStation14.Traits.SightFear { [RegisterComponent] @@ -37,7 +39,9 @@ public sealed class SightFearTraitComponent : Component /// [DataField("calmRate")] [ViewVariables(VVAccess.ReadWrite)] - public float CalmRate = 1.5f; + public float CalmRate = 2.25f; + + public IPlayingAudioStream? Stream; public float Accumulator = 0.084f; } diff --git a/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs index 36a1a0882c..b6f901dadd 100644 --- a/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs +++ b/Content.Server/SimpleStation14/Traits/SightFear/SightFearTraitSystem.cs @@ -1,8 +1,14 @@ using System.Linq; +using Content.Server.Power.EntitySystems; +using Content.Shared.Audio; +using Content.Shared.Chemistry.Reagent; using Content.Shared.Examine; using Content.Shared.Interaction.Helpers; using Content.Shared.Random; using Content.Shared.Random.Helpers; +using Robust.Server.GameObjects; +using Robust.Shared.Audio; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -14,6 +20,7 @@ public sealed class SightFearTraitSystem : EntitySystem [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly IEntityManager _entity = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly AudioSystem _audio = default!; public override void Initialize() { @@ -108,7 +115,7 @@ public override void Update(float frameTime) var distance = (Transform(uid).Coordinates.Position - Transform(entity).Coordinates.Position).Length; var strength = MathHelper.Lerp(0f, value, 1f - distance / range); - if (strength <= 0f || component.Fear >= component.MaxFear * 2) + if (strength <= 0f) continue; // Increase the level of fear @@ -119,8 +126,24 @@ public override void Update(float frameTime) Logger.ErrorS("SightFearTraitSystem", $"Entity {uid} is afraid of {entity} ({component.AfraidOf}) at strength {strength}, now at a fear level of {component.Fear}/{component.MaxFear}."); } + // Set the afraid state for other systems to use component.Afraid = afraid; + // Spook + if (component.Fear >= component.MaxFear * 2 && component.Stream == null) + { + component.Stream = _audio.PlayGlobal(new SoundPathSpecifier("/Audio/SimpleStation14/Effects/fastbeat.ogg"), uid, AudioParams.Default.WithLoop(true).WithVariation(0.125f)); + } + else if (component.Fear >= component.MaxFear && component.Stream == null) + { + component.Stream = _audio.PlayGlobal(new SoundPathSpecifier("/Audio/SimpleStation14/Effects/slowbeat.ogg"), uid, AudioParams.Default.WithLoop(true).WithVariation(0.125f)); + } + else if (component.Fear < component.MaxFear && component.Stream != null) + { + component.Stream?.Stop(); + component.Stream = null; + } + // Decrease the fear level if not afraid this frame if (!afraid && component.Fear > 0f) { diff --git a/Resources/Audio/SimpleStation14/Effects/fastbeat.ogg b/Resources/Audio/SimpleStation14/Effects/fastbeat.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5b3d4a92ab622230a69d34317d99eb1d273f0e81 GIT binary patch literal 5914 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 F{U5potw#U= literal 0 HcmV?d00001 diff --git a/Resources/Audio/SimpleStation14/Effects/slowbeat.ogg b/Resources/Audio/SimpleStation14/Effects/slowbeat.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8989fb04f482849472187061c4cfe2143771d203 GIT binary patch literal 7486 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