diff --git a/Content.Server/FloofStation/Abilities/Psionics/Abilities/PsionicHypnoSystem.cs b/Content.Server/FloofStation/Abilities/Psionics/Abilities/PsionicHypnoSystem.cs index ffc2a9b6b0c..82c9538f8c5 100644 --- a/Content.Server/FloofStation/Abilities/Psionics/Abilities/PsionicHypnoSystem.cs +++ b/Content.Server/FloofStation/Abilities/Psionics/Abilities/PsionicHypnoSystem.cs @@ -17,7 +17,6 @@ using Content.Shared.Mobs.Components; using Content.Shared.Psionics; using Content.Server.Consent; -using Content.Shared.Mind.Components; namespace Content.Server.Abilities.Psionics @@ -176,15 +175,12 @@ private void OnDoAfter(EntityUid uid, PsionicHypnoComponent component, PsionicHy { _popups.PopupEntity(Loc.GetString("hypno-success", ("target", uid)), uid, uid, PopupType.LargeCaution); - Hypnotize(uid, args.Target.Value, component); + Hypnotize(uid, args.Target.Value); } } - public void Hypnotize(EntityUid uid, EntityUid target, PsionicHypnoComponent? component = null) + public void Hypnotize(EntityUid uid, EntityUid target) { - if (!Resolve(uid, ref component)) - return; - EnsureComp(target, out var hypnotized); hypnotized.Master = uid; diff --git a/Content.Server/FloofStation/HypnoClothing/HypnoClothingComponent.cs b/Content.Server/FloofStation/HypnoClothing/HypnoClothingComponent.cs new file mode 100644 index 00000000000..a39688cfd5d --- /dev/null +++ b/Content.Server/FloofStation/HypnoClothing/HypnoClothingComponent.cs @@ -0,0 +1,13 @@ +using Robust.Shared.Audio; + +namespace Content.Server.FloofStation; + +[RegisterComponent] +public sealed partial class HypnoClothingComponent : Component +{ + [DataField] + public EntityUid? Master; + + [DataField] + public SoundSpecifier LinkSound = new SoundPathSpecifier("/Audio/Machines/terminal_insert_disc.ogg"); +} diff --git a/Content.Server/FloofStation/HypnoClothing/HypnoClothingSystem.cs b/Content.Server/FloofStation/HypnoClothing/HypnoClothingSystem.cs new file mode 100644 index 00000000000..2577b1fbfcf --- /dev/null +++ b/Content.Server/FloofStation/HypnoClothing/HypnoClothingSystem.cs @@ -0,0 +1,62 @@ +using Content.Shared.Inventory.Events; +using Content.Shared.Clothing.Components; +using Content.Shared.Floofstation.Hypno; +using Content.Shared.Verbs; +using Robust.Shared.Utility; +using Content.Server.Consent; +using Content.Server.Labels; +using Robust.Shared.Audio.Systems; +using Content.Server.Abilities.Psionics; +using Content.Shared.Labels.Components; + + +namespace Content.Server.FloofStation; +public sealed class HypnoClothingsystem : EntitySystem +{ + [Dependency] private readonly ConsentSystem _consent = default!; + [Dependency] private readonly LabelSystem _labelSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly PsionicHypnoSystem _psionichypnosystem = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent>(HypnoLinkVerb); + } + + private void HypnoLinkVerb(EntityUid uid, HypnoClothingComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + Verb verbHypnoLink = new() + { + Act = () => HypnoLink(uid, component, args.User), + Text = Loc.GetString("hypno-link"), + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Floof/Interface/Actions/hypno.png")), + Priority = 1 + }; + args.Verbs.Add(verbHypnoLink); + } + + private void OnEquipped(EntityUid uid, HypnoClothingComponent component, GotEquippedEvent args) + { + if (!TryComp(uid, out var clothing) + || !clothing.Slots.HasFlag(args.SlotFlags)) + return; + + if (component.Master == null || !_consent.HasConsent(args.Equipee, "Hypno")) + return; + + _psionichypnosystem.Hypnotize(component.Master.Value, args.Equipee); + } + + public void HypnoLink(EntityUid uid, HypnoClothingComponent component, EntityUid master) + { + EnsureComp(master); + _labelSystem.Label(uid, Loc.GetString("hypno-link-master", ("entity", master))); + _audio.PlayPvs(component.LinkSound, uid); + + component.Master = master; + } +} diff --git a/Resources/Locale/en-US/Floof/hypno.ftl b/Resources/Locale/en-US/Floof/hypno.ftl index 905b8d7e78e..cf029ccb204 100644 --- a/Resources/Locale/en-US/Floof/hypno.ftl +++ b/Resources/Locale/en-US/Floof/hypno.ftl @@ -38,3 +38,7 @@ trait-name-HypnoticGaze = Hypnotic Gaze trait-description-HypnoticGaze = Within your eyes lies the ability to place others under your control. You are capable of placing others in a trance, regardless of whether or not you possess any other notable psychic powers. + +# Hypno Visor +hypno-link = Set Mind Link +hypno-link-master = Master: {CAPITALIZE($entity)} diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 93ee662ff7c..e1977dfcccb 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -198,6 +198,7 @@ - ClothingHeadHatWelding - ShockCollar # FloofStation - LeashBasic # FloofStation + - ClothingEyesHypnoVisor # FloofStation - StationAnchorCircuitboard - type: EmagLatheRecipes emagStaticRecipes: diff --git a/Resources/Prototypes/Floof/Catalog/Fills/Crates/lewd.yml b/Resources/Prototypes/Floof/Catalog/Fills/Crates/lewd.yml index 17a63112c01..91530f95497 100644 --- a/Resources/Prototypes/Floof/Catalog/Fills/Crates/lewd.yml +++ b/Resources/Prototypes/Floof/Catalog/Fills/Crates/lewd.yml @@ -66,3 +66,5 @@ - !type:EntSelector id: LeashBasic amount: !type:ConstantNumberSelector { value: 2 } + - !type:EntSelector + id: ClothingEyesHypnoVisor diff --git a/Resources/Prototypes/Floof/CharacterItemGroups/funGroup.yml b/Resources/Prototypes/Floof/CharacterItemGroups/funGroup.yml index 9bcedff2c23..b1f27350e6b 100644 --- a/Resources/Prototypes/Floof/CharacterItemGroups/funGroup.yml +++ b/Resources/Prototypes/Floof/CharacterItemGroups/funGroup.yml @@ -5,6 +5,8 @@ id: LoadoutItemLeashBasic - type: loadout id: LoadoutItemLeashShort + - type: loadout + id: LoadoutItemHypnoVisor # If you are ever going to add more: open regex101; in list mode, find "id: (.+)", replace with "- type: loadout\n id: $1\n", paste the result here - type: characterItemGroup diff --git a/Resources/Prototypes/Floof/Entities/Clothing/Eyes/specific.yml b/Resources/Prototypes/Floof/Entities/Clothing/Eyes/specific.yml new file mode 100644 index 00000000000..618902d9b30 --- /dev/null +++ b/Resources/Prototypes/Floof/Entities/Clothing/Eyes/specific.yml @@ -0,0 +1,11 @@ +- type: entity + parent: [ClothingEyesBase] + id: ClothingEyesHypnoVisor + name: Hypno Visor + description: Pre-programmed with a variety of visual and auditory options, this visor will work to induce a trance in its wearer, no psionics or hypnotist training required. + components: + - type: Sprite + sprite: Clothing/Eyes/Hud/syndagent.rsi + - type: Clothing + sprite: Clothing/Eyes/Hud/syndagent.rsi + - type: HypnoClothing diff --git a/Resources/Prototypes/Floof/Loadouts/items.yml b/Resources/Prototypes/Floof/Loadouts/items.yml index fa562950689..354beaa1ea5 100644 --- a/Resources/Prototypes/Floof/Loadouts/items.yml +++ b/Resources/Prototypes/Floof/Loadouts/items.yml @@ -30,3 +30,14 @@ requirements: - !type:CharacterItemGroupRequirement group: LoadoutFun + +- type: loadout + id: LoadoutItemHypnoVisor + category: Items + cost: 2 + exclusive: true + items: + - ClothingEyesHypnoVisor + requirements: + - !type:CharacterItemGroupRequirement + group: LoadoutFun diff --git a/Resources/Prototypes/Floof/Recipes/Lathes/tools.yml b/Resources/Prototypes/Floof/Recipes/Lathes/tools.yml index 2492871df64..dd6a3bb17fb 100644 --- a/Resources/Prototypes/Floof/Recipes/Lathes/tools.yml +++ b/Resources/Prototypes/Floof/Recipes/Lathes/tools.yml @@ -6,3 +6,11 @@ Cloth: 50 Plastic: 500 Steel: 75 + +- type: latheRecipe + id: ClothingEyesHypnoVisor + result: ClothingEyesHypnoVisor + completetime: 3.5 + materials: + Glass: 100 + Steel: 75