diff --git a/Content.Client/ADT/Quirks/QuirksSystem.cs b/Content.Client/ADT/Quirks/QuirksSystem.cs new file mode 100644 index 0000000000..4a8f77b4fc --- /dev/null +++ b/Content.Client/ADT/Quirks/QuirksSystem.cs @@ -0,0 +1,46 @@ +using Content.Shared.ADT.Traits; +using Content.Client.Storage.Components; +using Content.Shared.Storage.EntitySystems; +using Content.Shared.Verbs; +using Content.Shared.Tools.Components; +using Content.Shared.Whitelist; +using Content.Shared.Lock; + +namespace Content.Client.ADT.Traits; + +public sealed class QuirksSystem : SharedQuirksSystem +{ + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(OnGetHideVerbs); + + } + + private void OnGetHideVerbs(EntityUid uid, EntityStorageComponent comp, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + if (!HasComp(args.User)) + return; + if (TryComp(uid, out var weldable) && weldable.IsWelded) + return; + if (_whitelist.IsWhitelistFail(comp.Whitelist, args.User)) + return; + if (TryComp(uid, out var lockComponent) && lockComponent.Locked) + return; + + AlternativeVerb verb = new() + { + Act = () => TryHide(args.User, uid), + Text = Loc.GetString("quirk-fast-locker-hide-verb"), + }; + args.Verbs.Add(verb); + + } + +} diff --git a/Content.Server/ADT/Quirks/QuirksSystem.cs b/Content.Server/ADT/Quirks/QuirksSystem.cs new file mode 100644 index 0000000000..821e048deb --- /dev/null +++ b/Content.Server/ADT/Quirks/QuirksSystem.cs @@ -0,0 +1,46 @@ +using Content.Shared.ADT.Traits; +using Content.Server.Storage.Components; +using Content.Shared.Storage.EntitySystems; +using Content.Shared.Verbs; +using Content.Shared.Tools.Components; +using Content.Shared.Whitelist; +using Content.Shared.Lock; + +namespace Content.Server.ADT.Traits; + +public sealed class QuirksSystem : SharedQuirksSystem +{ + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(OnGetHideVerbs); + + } + + private void OnGetHideVerbs(EntityUid uid, EntityStorageComponent comp, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + if (!HasComp(args.User)) + return; + if (TryComp(uid, out var weldable) && weldable.IsWelded) + return; + + if (_whitelist.IsWhitelistFail(comp.Whitelist, args.User)) + return; + if (TryComp(uid, out var lockComponent) && lockComponent.Locked) + return; + + AlternativeVerb verb = new() + { + Act = () => TryHide(args.User, uid), + Text = Loc.GetString("quirk-fast-locker-hide-verb"), + }; + args.Verbs.Add(verb); + + } + +} diff --git a/Content.Shared/ADT/Quirks/Components/FastLockersComponent.cs b/Content.Shared/ADT/Quirks/Components/FastLockersComponent.cs new file mode 100644 index 0000000000..84b25d99bc --- /dev/null +++ b/Content.Shared/ADT/Quirks/Components/FastLockersComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.ADT.Traits; + +[RegisterComponent] +[NetworkedComponent] +public sealed partial class FastLockersComponent : Component +{ +} diff --git a/Content.Shared/ADT/Quirks/Components/FreerunningComponent.cs b/Content.Shared/ADT/Quirks/Components/FreerunningComponent.cs new file mode 100644 index 0000000000..ddd49f5a75 --- /dev/null +++ b/Content.Shared/ADT/Quirks/Components/FreerunningComponent.cs @@ -0,0 +1,13 @@ +using Content.Shared.Tag; +using Robust.Shared.Prototypes; +using Robust.Shared.GameStates; + +namespace Content.Shared.ADT.Traits; + +[RegisterComponent] +[NetworkedComponent] +public sealed partial class FreerunningComponent : Component +{ + [DataField] + public float Modifier = 0.6f; +} diff --git a/Content.Shared/ADT/Quirks/Components/HardThrowerComponent.cs b/Content.Shared/ADT/Quirks/Components/HardThrowerComponent.cs new file mode 100644 index 0000000000..561b53d737 --- /dev/null +++ b/Content.Shared/ADT/Quirks/Components/HardThrowerComponent.cs @@ -0,0 +1,13 @@ +using Content.Shared.Tag; +using Robust.Shared.Prototypes; +using Robust.Shared.GameStates; + +namespace Content.Shared.ADT.Traits; + +[RegisterComponent] +[NetworkedComponent] +public sealed partial class HardThrowerComponent : Component +{ + [DataField] + public float Modifier = 0.8f; +} diff --git a/Content.Shared/ADT/Quirks/Components/SoftWalkComponent.cs b/Content.Shared/ADT/Quirks/Components/SoftWalkComponent.cs new file mode 100644 index 0000000000..b02f0a9c39 --- /dev/null +++ b/Content.Shared/ADT/Quirks/Components/SoftWalkComponent.cs @@ -0,0 +1,12 @@ +using Content.Shared.Tag; +using Robust.Shared.Prototypes; +using Robust.Shared.GameStates; + +namespace Content.Shared.ADT.Traits; + +[RegisterComponent] +[NetworkedComponent] +public sealed partial class SoftWalkComponent : Component +{ + public ProtoId Tag = "ShoesRequiredStepTriggerImmune"; +} diff --git a/Content.Shared/ADT/Quirks/Components/SprinterComponent.cs b/Content.Shared/ADT/Quirks/Components/SprinterComponent.cs new file mode 100644 index 0000000000..2999b57f0c --- /dev/null +++ b/Content.Shared/ADT/Quirks/Components/SprinterComponent.cs @@ -0,0 +1,12 @@ +using Content.Shared.Tag; +using Robust.Shared.Prototypes; +using Robust.Shared.GameStates; + +namespace Content.Shared.ADT.Traits; + +[RegisterComponent] +[NetworkedComponent] +public sealed partial class SprinterComponent : Component +{ + public float Modifier = 1.1f; +} diff --git a/Content.Shared/ADT/Quirks/EntitySystems/SharedQuirksSystem.cs b/Content.Shared/ADT/Quirks/EntitySystems/SharedQuirksSystem.cs new file mode 100644 index 0000000000..eeac04ec23 --- /dev/null +++ b/Content.Shared/ADT/Quirks/EntitySystems/SharedQuirksSystem.cs @@ -0,0 +1,101 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Content.Shared.Climbing.Events; +using Robust.Shared.Network; +using Content.Shared.Throwing; +using Content.Shared.Verbs; +using Content.Shared.Tools.Components; +using Content.Shared.Storage.Components; +using Content.Shared.Storage.EntitySystems; +using Content.Shared.Popups; +using Content.Shared.Tag; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; + +namespace Content.Shared.ADT.Traits; + +public abstract class SharedQuirksSystem : EntitySystem +{ + [Dependency] private readonly SharedEntityStorageSystem _storage = default!; + [Dependency] protected readonly IRobustRandom _random = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly INetManager _netMan = default!; + [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly TagSystem _tag = default!; + + public override void Initialize() + { + //SubscribeLocalEvent>(OnGetHideVerbs); + + SubscribeLocalEvent(OnSoftWalkMapInit); + + SubscribeLocalEvent(OnFreerunningClimbTimeModify); + + SubscribeLocalEvent(OnSprinterMapInit); + SubscribeLocalEvent(OnRefreshMovespeed); + + SubscribeLocalEvent(OnThrowerRangeModify); + } + + //private void OnGetHideVerbs(EntityUid uid, SharedEntityStorageComponent comp, GetVerbsEvent args) + //{ + // if (!args.CanAccess || !args.CanInteract) + // return; + + // if (!HasComp(args.User)) + // return; + // if (TryComp(uid, out var weldable) && weldable.IsWelded) + // return; + // if (!comp.ItemCanStoreMobs) + // return; + + // AlternativeVerb verb = new() + // { + // Act = () => TryHide(args.User, uid), + // Text = Loc.GetString("quirk-fast-locker-hide-verb"), + // }; + // args.Verbs.Add(verb); + + //} + + public void TryHide(EntityUid uid, EntityUid closet) + { + if (_storage.Insert(uid, closet)) + _popup.PopupClient(Loc.GetString("quirk-fast-locker-hide-success"), uid); + else + _popup.PopupCursor(Loc.GetString("quirk-fast-locker-hide-fail"), uid); + } + + private void OnSoftWalkMapInit(EntityUid uid, SoftWalkComponent comp, MapInitEvent args) + { + if (_tag.HasTag(uid, comp.Tag)) + RemComp(uid); + else + _tag.AddTag(uid, comp.Tag); + } + + private void OnFreerunningClimbTimeModify(EntityUid uid, FreerunningComponent comp, ref CheckClimbSpeedModifiersEvent args) + { + if (args.User == args.Climber) + args.Time *= comp.Modifier; + } + + private void OnSprinterMapInit(EntityUid uid, SprinterComponent comp, MapInitEvent args) + { + if (!TryComp(uid, out var move)) + return; + _movementSpeed.RefreshMovementSpeedModifiers(uid, move); + } + private void OnRefreshMovespeed(EntityUid uid, SprinterComponent component, RefreshMovementSpeedModifiersEvent args) + { + args.ModifySpeed(1f, component.Modifier); + } + + private void OnThrowerRangeModify(EntityUid uid, HardThrowerComponent component, ref CheckThrowRangeModifiersEvent args) + { + args.SpeedMod = component.Modifier; + args.VectorMod = component.Modifier; + } + +} diff --git a/Content.Shared/Climbing/Events/CheckClimbSpeedModifiers.cs b/Content.Shared/Climbing/Events/CheckClimbSpeedModifiers.cs new file mode 100644 index 0000000000..a3ef747760 --- /dev/null +++ b/Content.Shared/Climbing/Events/CheckClimbSpeedModifiers.cs @@ -0,0 +1,6 @@ +namespace Content.Shared.Climbing.Events; + +[ByRefEvent] +public record struct CheckClimbSpeedModifiersEvent(EntityUid User, EntityUid Climber, EntityUid Climbable, float Time) +{ +} diff --git a/Content.Shared/Climbing/Systems/ClimbSystem.cs b/Content.Shared/Climbing/Systems/ClimbSystem.cs index 726cdc2468..864fe7ace9 100644 --- a/Content.Shared/Climbing/Systems/ClimbSystem.cs +++ b/Content.Shared/Climbing/Systems/ClimbSystem.cs @@ -215,8 +215,11 @@ public bool TryClimb( RaiseLocalEvent(climbable, ref ev); if (ev.Cancelled) return false; + var speedEv = new CheckClimbSpeedModifiersEvent(user, entityToMove, climbable, comp.ClimbDelay); + RaiseLocalEvent(entityToMove, ref speedEv); + var delay = speedEv.Time; - var args = new DoAfterArgs(EntityManager, user, comp.ClimbDelay, new ClimbDoAfterEvent(), + var args = new DoAfterArgs(EntityManager, user, delay, new ClimbDoAfterEvent(), entityToMove, target: climbable, used: entityToMove) diff --git a/Content.Shared/Throwing/CheckThrowRangeModifiersEvent.cs b/Content.Shared/Throwing/CheckThrowRangeModifiersEvent.cs new file mode 100644 index 0000000000..05ae629491 --- /dev/null +++ b/Content.Shared/Throwing/CheckThrowRangeModifiersEvent.cs @@ -0,0 +1,9 @@ +using System.Numerics; + +namespace Content.Shared.Throwing; + +/// +/// Raised on thrown entity. +/// +[ByRefEvent] +public record struct CheckThrowRangeModifiersEvent(EntityUid? User, float VectorMod = 1f, float SpeedMod = 1f); diff --git a/Content.Shared/Throwing/ThrowingSystem.cs b/Content.Shared/Throwing/ThrowingSystem.cs index 549473278e..9800e1ced6 100644 --- a/Content.Shared/Throwing/ThrowingSystem.cs +++ b/Content.Shared/Throwing/ThrowingSystem.cs @@ -198,6 +198,11 @@ public void TryThrow(EntityUid uid, // If someone changes how tile friction works at some point, this will have to be adjusted. var throwSpeed = compensateFriction ? direction.Length() / (flyTime + 1 / tileFriction) : baseThrowSpeed; var impulseVector = direction.Normalized() * throwSpeed * physics.Mass; + var modifiersEv = new CheckThrowRangeModifiersEvent(user); + RaiseLocalEvent(user ?? EntityUid.Invalid, ref modifiersEv); + throwSpeed *= modifiersEv.SpeedMod; + impulseVector *= modifiersEv.VectorMod; + _physics.ApplyLinearImpulse(uid, impulseVector, body: physics); if (comp.LandTime == null || comp.LandTime <= TimeSpan.Zero) diff --git a/Resources/Locale/ru-RU/ADT/traits/categories.ftl b/Resources/Locale/ru-RU/ADT/traits/categories.ftl new file mode 100644 index 0000000000..d52f1dbe8f --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/traits/categories.ftl @@ -0,0 +1 @@ +trait-category-quirks = Особенности diff --git a/Resources/Locale/ru-RU/ADT/traits/positive.ftl b/Resources/Locale/ru-RU/ADT/traits/positive.ftl new file mode 100644 index 0000000000..9c9ba595a8 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/traits/positive.ftl @@ -0,0 +1,14 @@ +trait-soft-walk-name = Осторожный шаг +trait-soft-walk-desc = Вы достаточно осторожны, чтобы не наступать на опасные точки даже без обуви. + +trait-freerunning-name = Паркурщик +trait-freerunning-desc = Вы гораздо быстрее забираетесь на столы. + +trait-sprinter-name = Спринтер +trait-sprinter-desc = Вы бегаете чуть быстрее остальных представителей своего вида. + +trait-fast-lockers-name = Ловкий +trait-fast-lockers-desc = Вы можете моментально и максимально незаметно забраться внутрь шкафа, или ящика. + +trait-hard-thrower-name = Сильный бросок +trait-hard-thrower-desc = Вы бросаетесь вещами сильнее остальных. diff --git a/Resources/Prototypes/ADT/Traits/categories.yml b/Resources/Prototypes/ADT/Traits/categories.yml new file mode 100644 index 0000000000..af7b502fb4 --- /dev/null +++ b/Resources/Prototypes/ADT/Traits/categories.yml @@ -0,0 +1,4 @@ +- type: traitCategory + id: Quirks + name: trait-category-quirks + maxTraitPoints: 0 diff --git a/Resources/Prototypes/ADT/Traits/disabilities.yml b/Resources/Prototypes/ADT/Traits/disabilities.yml index fc43fc11af..1323ec2375 100644 --- a/Resources/Prototypes/ADT/Traits/disabilities.yml +++ b/Resources/Prototypes/ADT/Traits/disabilities.yml @@ -1,18 +1,18 @@ -- type: trait - id: ADTHemophilia - name: trait-hemophilia-name - description: trait-hemophilia-desc - category: Disabilities - components: - - type: Hemophilia - modifier: 0.01 +# - type: trait +# id: ADTHemophilia +# name: trait-hemophilia-name +# description: trait-hemophilia-desc +# category: Disabilities +# components: +# - type: Hemophilia +# modifier: 0.01 -# Simple Station +# # Simple Station -- type: trait - id: ColorBlindnessMonochrome - name: trait-monochromacy-name - description: trait-monochromacy-description - category: Disabilities - components: - - type: Monochromacy +# - type: trait +# id: ColorBlindnessMonochrome +# name: trait-monochromacy-name +# description: trait-monochromacy-description +# category: Disabilities +# components: +# - type: Monochromacy diff --git a/Resources/Prototypes/ADT/Traits/quirks.yml b/Resources/Prototypes/ADT/Traits/quirks.yml new file mode 100644 index 0000000000..e35a3c342f --- /dev/null +++ b/Resources/Prototypes/ADT/Traits/quirks.yml @@ -0,0 +1,170 @@ +- type: trait + id: Blindness + name: trait-blindness-name + description: trait-blindness-desc + traitGear: WhiteCane + category: Quirks + whitelist: + components: + - Blindable + components: + - type: PermanentBlindness + cost: -3 + +- type: trait + id: PoorVision + name: trait-poor-vision-name + description: trait-poor-vision-desc + traitGear: ClothingEyesGlasses + category: Quirks + whitelist: + components: + - Blindable + components: + - type: PermanentBlindness + blindness: 4 + cost: -2 + +- type: trait + id: Narcolepsy + name: trait-narcolepsy-name + description: trait-narcolepsy-desc + category: Quirks + components: + - type: Narcolepsy + timeBetweenIncidents: 300, 600 + durationOfIncident: 10, 30 + cost: -2 + +- type: trait + id: Pacifist + name: trait-pacifist-name + description: trait-pacifist-desc + category: Quirks + components: + - type: Pacified + cost: -2 + +- type: trait + id: Unrevivable + name: trait-unrevivable-name + description: trait-unrevivable-desc + category: Quirks + components: + - type: Unrevivable + cost: -1 + +- type: trait + id: Muted + name: trait-muted-name + description: trait-muted-desc + category: Quirks + blacklist: + components: + - BorgChassis + components: + - type: Muted + cost: -2 + +- type: trait + id: LightweightDrunk + name: trait-lightweight-name + description: trait-lightweight-desc + category: Quirks + components: + - type: LightweightDrunk + boozeStrengthMultiplier: 2 + cost: -1 + +- type: trait + id: Paracusia + name: trait-paracusia-name + description: trait-paracusia-desc + category: Quirks + components: + - type: Paracusia + minTimeBetweenIncidents: 0.1 + maxTimeBetweenIncidents: 300 + maxSoundDistance: 7 + sounds: + collection: Paracusia + cost: -1 + +- type: trait + id: Snoring + name: trait-snoring-name + description: trait-snoring-desc + category: Quirks + components: + - type: Snoring + cost: -1 + +# ADT + +- type: trait + id: ADTHemophilia + name: trait-hemophilia-name + description: trait-hemophilia-desc + category: Quirks + components: + - type: Hemophilia + modifier: 0.01 + cost: -2 + +- type: trait + id: ADTSoftWalk + name: trait-soft-walk-name + description: trait-soft-walk-desc + category: Quirks + components: + - type: SoftWalk + cost: 2 + +- type: trait + id: ADTFreerunning + name: trait-freerunning-name + description: trait-freerunning-desc + category: Quirks + components: + - type: Freerunning + cost: 1 + +- type: trait + id: ADTSprinter + name: trait-sprinter-name + description: trait-sprinter-desc + category: Quirks + components: + - type: Sprinter + modifier: 1.1 + cost: 2 + +- type: trait + id: ADTFastLockers + name: trait-fast-lockers-name + description: trait-fast-lockers-desc + category: Quirks + components: + - type: FastLockers + cost: 2 + +- type: trait + id: ADTHardThrower + name: trait-hard-thrower-name + description: trait-hard-thrower-desc + category: Quirks + components: + - type: HardThrower + modifier: 1.3 + cost: 2 + +# Simple Station + +- type: trait + id: ColorBlindnessMonochrome + name: trait-monochromacy-name + description: trait-monochromacy-description + category: Quirks + components: + - type: Monochromacy + cost: -1 diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index 6e0026e44e..2971b47209 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -1,91 +1,91 @@ -- type: trait - id: Blindness - name: trait-blindness-name - description: trait-blindness-desc - traitGear: WhiteCane - category: Disabilities - whitelist: - components: - - Blindable - components: - - type: PermanentBlindness +# - type: trait +# id: Blindness +# name: trait-blindness-name +# description: trait-blindness-desc +# traitGear: WhiteCane +# category: Disabilities +# whitelist: +# components: +# - Blindable +# components: +# - type: PermanentBlindness -- type: trait - id: PoorVision - name: trait-poor-vision-name - description: trait-poor-vision-desc - traitGear: ClothingEyesGlasses - category: Disabilities - whitelist: - components: - - Blindable - components: - - type: PermanentBlindness - blindness: 4 +# - type: trait +# id: PoorVision +# name: trait-poor-vision-name +# description: trait-poor-vision-desc +# traitGear: ClothingEyesGlasses +# category: Disabilities +# whitelist: +# components: +# - Blindable +# components: +# - type: PermanentBlindness +# blindness: 4 -- type: trait - id: Narcolepsy - name: trait-narcolepsy-name - description: trait-narcolepsy-desc - category: Disabilities - components: - - type: Narcolepsy - timeBetweenIncidents: 300, 600 - durationOfIncident: 10, 30 +# - type: trait +# id: Narcolepsy +# name: trait-narcolepsy-name +# description: trait-narcolepsy-desc +# category: Disabilities +# components: +# - type: Narcolepsy +# timeBetweenIncidents: 300, 600 +# durationOfIncident: 10, 30 -- type: trait - id: Pacifist - name: trait-pacifist-name - description: trait-pacifist-desc - category: Disabilities - components: - - type: Pacified +# - type: trait +# id: Pacifist +# name: trait-pacifist-name +# description: trait-pacifist-desc +# category: Disabilities +# components: +# - type: Pacified -- type: trait - id: Unrevivable - name: trait-unrevivable-name - description: trait-unrevivable-desc - category: Disabilities - components: - - type: Unrevivable +# - type: trait +# id: Unrevivable +# name: trait-unrevivable-name +# description: trait-unrevivable-desc +# category: Disabilities +# components: +# - type: Unrevivable -- type: trait - id: Muted - name: trait-muted-name - description: trait-muted-desc - category: Disabilities - blacklist: - components: - - BorgChassis - components: - - type: Muted +# - type: trait +# id: Muted +# name: trait-muted-name +# description: trait-muted-desc +# category: Disabilities +# blacklist: +# components: +# - BorgChassis +# components: +# - type: Muted -- type: trait - id: LightweightDrunk - name: trait-lightweight-name - description: trait-lightweight-desc - category: Disabilities - components: - - type: LightweightDrunk - boozeStrengthMultiplier: 2 +# - type: trait +# id: LightweightDrunk +# name: trait-lightweight-name +# description: trait-lightweight-desc +# category: Disabilities +# components: +# - type: LightweightDrunk +# boozeStrengthMultiplier: 2 -- type: trait - id: Paracusia - name: trait-paracusia-name - description: trait-paracusia-desc - category: Disabilities - components: - - type: Paracusia - minTimeBetweenIncidents: 0.1 - maxTimeBetweenIncidents: 300 - maxSoundDistance: 7 - sounds: - collection: Paracusia +# - type: trait +# id: Paracusia +# name: trait-paracusia-name +# description: trait-paracusia-desc +# category: Disabilities +# components: +# - type: Paracusia +# minTimeBetweenIncidents: 0.1 +# maxTimeBetweenIncidents: 300 +# maxSoundDistance: 7 +# sounds: +# collection: Paracusia -- type: trait - id: Snoring - name: trait-snoring-name - description: trait-snoring-desc - category: Disabilities - components: - - type: Snoring +# - type: trait +# id: Snoring +# name: trait-snoring-name +# description: trait-snoring-desc +# category: Disabilities +# components: +# - type: Snoring