From a411d144615d0e2840134cea128d126155050e34 Mon Sep 17 00:00:00 2001 From: Aviu00 <93730715+Aviu00@users.noreply.github.com> Date: Sat, 24 Feb 2024 01:06:24 +0900 Subject: [PATCH] Revenant stuff (#110) * - add: Chaplain cult shield immune. * - add: Revenant stuff. --- Content.Server/Bed/Sleep/SleepingSystem.cs | 7 +- Content.Server/Bible/BibleSystem.cs | 16 +++ .../Revenant/Components/BlightComponent.cs | 26 +++++ .../Revenant/EntitySystems/BlightSystem.cs | 97 +++++++++++++++++++ .../EntitySystems/RevenantSystem.Abilities.cs | 39 ++++++++ .../Revenant/EntitySystems/RevenantSystem.cs | 15 +++ .../Items/Systems/ReturnItemOnThrowSystem.cs | 8 +- Resources/Locale/ru-RU/chapel/blight.ftl | 2 + Resources/Prototypes/Actions/revenant.yml | 20 ++-- .../Prototypes/Catalog/revenant_catalog.yml | 24 ++--- 10 files changed, 225 insertions(+), 29 deletions(-) create mode 100644 Content.Server/Revenant/Components/BlightComponent.cs create mode 100644 Content.Server/Revenant/EntitySystems/BlightSystem.cs create mode 100644 Resources/Locale/ru-RU/chapel/blight.ftl diff --git a/Content.Server/Bed/Sleep/SleepingSystem.cs b/Content.Server/Bed/Sleep/SleepingSystem.cs index 5d1def7cec..ca7274bc52 100644 --- a/Content.Server/Bed/Sleep/SleepingSystem.cs +++ b/Content.Server/Bed/Sleep/SleepingSystem.cs @@ -1,4 +1,5 @@ using Content.Server.Popups; +using Content.Server.Revenant.Components; using Content.Server.Sound.Components; using Content.Shared.Actions; using Content.Shared.Audio; @@ -93,12 +94,14 @@ namespace Content.Server.Bed.Sleep private void OnSleepAction(EntityUid uid, MobStateComponent component, SleepActionEvent args) { - TrySleeping(uid); + if (TrySleeping(uid) && TryComp(uid, out BlightComponent? blight)) // WD EDIT + blight.BedSleep = true; } private void OnBedSleepAction(EntityUid uid, ActionsContainerComponent component, SleepActionEvent args) { - TrySleeping(args.Performer); + if (TrySleeping(args.Performer) && TryComp(args.Performer, out BlightComponent? blight)) // WD EDIT + blight.BedSleep = true; } private void OnWakeAction(EntityUid uid, MobStateComponent component, WakeActionEvent args) diff --git a/Content.Server/Bible/BibleSystem.cs b/Content.Server/Bible/BibleSystem.cs index 8432fff664..3e6e8b6b92 100644 --- a/Content.Server/Bible/BibleSystem.cs +++ b/Content.Server/Bible/BibleSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Ghost.Roles.Events; using Content.Server.Popups; using Content.Server._White.Other.CustomFluffSystems.merkka; +using Content.Server.Revenant.Components; using Content.Shared.ActionBlocker; using Content.Shared.Actions; using Content.Shared.Bible; @@ -117,6 +118,21 @@ namespace Content.Server.Bible return; } + // WD START + if (HasComp(args.Target.Value)) + { + var othersMessage = Loc.GetString(component.LocPrefix + "-blight-success-others", ("user", Identity.Entity(args.User, EntityManager)), ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); + _popupSystem.PopupEntity(othersMessage, args.User, Filter.PvsExcept(args.User), true, PopupType.Medium); + + var selfMessage = Loc.GetString(component.LocPrefix + "-blight-success-self", ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); + _popupSystem.PopupEntity(selfMessage, args.User, args.User, PopupType.Large); + _audio.PlayPvs(component.HealSoundPath, args.User); + _delay.TryResetDelay((uid, useDelay)); + RemCompDeferred(args.Target.Value); + return; + } + // WD END + // This only has a chance to fail if the target is not wearing anything on their head and is not a familiar. if (!_invSystem.TryGetSlotEntity(args.Target.Value, "head", out var _) && !HasComp(args.Target.Value)) { diff --git a/Content.Server/Revenant/Components/BlightComponent.cs b/Content.Server/Revenant/Components/BlightComponent.cs new file mode 100644 index 0000000000..d03fab1dc2 --- /dev/null +++ b/Content.Server/Revenant/Components/BlightComponent.cs @@ -0,0 +1,26 @@ +namespace Content.Server.Revenant.Components; + +[RegisterComponent] +public sealed partial class BlightComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite)] + public TimeSpan MaxDuration; + + [ViewVariables(VVAccess.ReadWrite)] + public float Duration; + + [ViewVariables(VVAccess.ReadWrite)] + public TimeSpan MaxDelay; + + [ViewVariables(VVAccess.ReadWrite)] + public float Delay; + + [ViewVariables(VVAccess.ReadWrite)] + public TimeSpan SleepingCureTime = TimeSpan.FromSeconds(25); + + [ViewVariables(VVAccess.ReadWrite)] + public float SleepDelay; + + [ViewVariables] + public bool BedSleep; +} diff --git a/Content.Server/Revenant/EntitySystems/BlightSystem.cs b/Content.Server/Revenant/EntitySystems/BlightSystem.cs new file mode 100644 index 0000000000..e86249b9c0 --- /dev/null +++ b/Content.Server/Revenant/EntitySystems/BlightSystem.cs @@ -0,0 +1,97 @@ +using Content.Server.Bed.Sleep; +using Content.Server.Popups; +using Content.Server.Revenant.Components; +using Content.Shared.Bed.Sleep; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Systems; +using Robust.Shared.Random; + +namespace Content.Server.Revenant.EntitySystems; + +public sealed class BlightSystem : EntitySystem +{ + [Dependency] private readonly SleepingSystem _sleeping = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMobStateChanged); + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnShutdown); + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + if (!Deleted(ent) && !EntityManager.IsQueuedForDeletion(ent) && _mobState.IsAlive(ent)) + _popup.PopupEntity("Вы вновь чувствуете себя здоровым.", ent, ent); + } + + private void OnStartup(Entity ent, ref ComponentStartup args) + { + SetDelay(ent.Comp); + SetDuration(ent.Comp); + } + + private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) + { + RemCompDeferred(ent); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + var sleepingQuery = GetEntityQuery(); + + while (query.MoveNext(out var ent, out var blight)) + { + blight.Duration += frameTime; + + if (blight.Duration >= blight.MaxDuration.TotalSeconds) + { + RemCompDeferred(ent); + continue; + } + + if (sleepingQuery.HasComponent(ent)) + { + if (blight.BedSleep) + { + blight.SleepDelay += frameTime; + if (blight.SleepDelay >= blight.SleepingCureTime.TotalSeconds) + RemCompDeferred(ent); + } + + continue; + } + + blight.BedSleep = false; + blight.SleepDelay = 0f; + + blight.Delay += frameTime; + + if (blight.Delay < blight.MaxDelay.TotalSeconds) + continue; + + _sleeping.TrySleeping(ent); + + blight.Delay = 0f; + SetDelay(blight); + } + } + + private void SetDuration(BlightComponent comp) + { + comp.MaxDuration = TimeSpan.FromSeconds(_random.Next(300, 420)); + } + + private void SetDelay(BlightComponent comp) + { + comp.MaxDelay = TimeSpan.FromSeconds(_random.Next(10, 30)); + } +} diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs index eb6eb5a426..6622ff858d 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs @@ -15,6 +15,7 @@ using Content.Shared.Item; using Content.Shared.Bed.Sleep; using System.Linq; using System.Numerics; +using Content.Server.Bible.Components; using Content.Server.Maps; using Content.Server.Revenant.Components; using Content.Shared.DoAfter; @@ -25,6 +26,7 @@ using Content.Shared.Maps; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; +using Content.Shared.Physics; using Content.Shared.Revenant.Components; using Robust.Shared.Physics.Components; using Robust.Shared.Utility; @@ -52,8 +54,19 @@ public sealed partial class RevenantSystem SubscribeLocalEvent(OnOverloadLightsAction); SubscribeLocalEvent(OnBlightAction); SubscribeLocalEvent(OnMalfunctionAction); + + SubscribeLocalEvent>(OnHarvestAttempt); // WD } + // WD START + private void OnHarvestAttempt(Entity ent, ref DoAfterAttemptEvent args) + { + var target = args.DoAfter.Args.Target; + if (target != null && _mobState.IsAlive(target.Value) && !HasComp(target.Value)) + args.Cancel(); + } + // WD END + private void OnInteract(EntityUid uid, RevenantComponent component, InteractNoHandEvent args) { if (args.Target == args.User || args.Target == null) @@ -137,12 +150,25 @@ public sealed partial class RevenantSystem return; } + // WD START + var tileref = Transform(uid).Coordinates.GetTileRef(); + if (tileref != null) + { + if(_physics.GetEntitiesIntersectingBody(uid, (int) CollisionGroup.Impassable).Count > 0) + { + _popup.PopupEntity(Loc.GetString("revenant-in-solid"), uid, uid); + return; + } + } + // WD END + var doAfter = new DoAfterArgs(EntityManager, uid, revenant.HarvestDebuffs.X, new HarvestEvent(), uid, target: target) { DistanceThreshold = 2, BreakOnUserMove = true, BreakOnDamage = true, RequireCanInteract = false, // stuns itself + AttemptFrequency = AttemptFrequency.EveryTick // WD EDIT }; if (!_doAfter.TryStartDoAfter(doAfter)) @@ -306,6 +332,19 @@ public sealed partial class RevenantSystem return; args.Handled = true; + + // WD START + var query = GetEntityQuery(); + foreach (var e in _lookup.GetEntitiesInRange(uid, component.BlightRadius)) + { + if (!_mobState.IsAlive(e) || query.HasComponent(e)) + continue; + + var blight = EnsureComp(e); + blight.Duration = 0f; + } + // WD END + // TODO: When disease refactor is in. } diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs index b26cc4a320..febb346793 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Actions; using Content.Server.GameTicking; using Content.Server.Store.Components; using Content.Server.Store.Systems; +using Content.Shared._White.Chaplain; using Content.Shared.Alert; using Content.Shared.Damage; using Content.Shared.DoAfter; @@ -19,6 +20,8 @@ using Content.Shared.Revenant.Components; using Content.Shared.StatusEffect; using Content.Shared.Stunnable; using Content.Shared.Tag; +using Content.Shared.Weapons.Melee; +using Content.Shared.Weapons.Melee.Events; using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -62,9 +65,21 @@ public sealed partial class RevenantSystem : EntitySystem SubscribeLocalEvent(OnStatusEnded); SubscribeLocalEvent(_ => MakeVisible(true)); + SubscribeLocalEvent(OnAttacked); // WD EDIT + InitializeAbilities(); } + // WD START + private void OnAttacked(Entity ent, ref AttackedEvent args) + { + if (!HasComp(args.Used) || !TryComp(args.Used, out MeleeWeaponComponent? weapon)) + return; + + args.BonusDamage = weapon.Damage; + } + // WD END + private void OnStartup(EntityUid uid, RevenantComponent component, ComponentStartup args) { //update the icon diff --git a/Content.Server/_White/Cult/Items/Systems/ReturnItemOnThrowSystem.cs b/Content.Server/_White/Cult/Items/Systems/ReturnItemOnThrowSystem.cs index 12bf61e5d4..bd1988ab62 100644 --- a/Content.Server/_White/Cult/Items/Systems/ReturnItemOnThrowSystem.cs +++ b/Content.Server/_White/Cult/Items/Systems/ReturnItemOnThrowSystem.cs @@ -1,6 +1,7 @@ using Content.Server.Hands.Systems; using Content.Server.Stunnable; using Content.Server._White.Cult.Items.Components; +using Content.Shared._White.Chaplain; using Content.Shared.Mobs.Components; using Content.Shared.Throwing; using Content.Shared._White.Cult; @@ -30,12 +31,9 @@ public sealed class ReturnItemOnThrowSystem : EntitySystem if (!HasComp(args.Target)) return; - if (!_stun.IsParalyzed(args.Target)) + if (!_stun.IsParalyzed(args.Target) && !isCultist && !HasComp(args.Target)) { - if (!isCultist) - { - _stun.TryParalyze(args.Target, TimeSpan.FromSeconds(component.StunTime), true); - } + _stun.TryParalyze(args.Target, TimeSpan.FromSeconds(component.StunTime), true); } _hands.PickupOrDrop(thrower, uid); diff --git a/Resources/Locale/ru-RU/chapel/blight.ftl b/Resources/Locale/ru-RU/chapel/blight.ftl new file mode 100644 index 0000000000..9beb1979e7 --- /dev/null +++ b/Resources/Locale/ru-RU/chapel/blight.ftl @@ -0,0 +1,2 @@ +bible-blight-success-self = Вы ударяете { $target } с помощью { $bible }, и его недуг рассеивается во вспышке святого света! +bible-blight-success-others = { CAPITALIZE($user) } ударяет { $target } с помощью { $bible }, и его недуг рассеивается во вспышке святого света! diff --git a/Resources/Prototypes/Actions/revenant.yml b/Resources/Prototypes/Actions/revenant.yml index da7b4ba56f..fdb14708fa 100644 --- a/Resources/Prototypes/Actions/revenant.yml +++ b/Resources/Prototypes/Actions/revenant.yml @@ -30,16 +30,16 @@ event: !type:RevenantOverloadLightsActionEvent useDelay: 20 -#- type: entity -# id: ActionRevenantBlight -# name: Blight -# description: Costs 50 Essence. -# noSpawn: true -# components: -# - type: InstantAction -# icon: Interface/Actions/blight.png -# event: !type:RevenantBlightActionEvent -# useDelay: 20 +- type: entity + id: ActionRevenantBlight + name: Blight + description: Costs 50 Essence. + noSpawn: true + components: + - type: InstantAction + icon: Interface/Actions/blight.png + event: !type:RevenantBlightActionEvent + useDelay: 20 - type: entity id: ActionRevenantMalfunction diff --git a/Resources/Prototypes/Catalog/revenant_catalog.yml b/Resources/Prototypes/Catalog/revenant_catalog.yml index 84f45d1607..1dbb111431 100644 --- a/Resources/Prototypes/Catalog/revenant_catalog.yml +++ b/Resources/Prototypes/Catalog/revenant_catalog.yml @@ -24,18 +24,18 @@ - !type:ListingLimitedStockCondition stock: 1 -#- type: listing -# id: RevenantBlight -# name: Blight -# description: Infects all nearby organisms with an infectious disease that causes toxic buildup and tiredness. Using it leaves you vulnerable to attacks for a medium period of time. -# productAction: ActionRevenantBlight -# cost: -# StolenEssence: 75 -# categories: -# - RevenantAbilities -# conditions: -# - !type:ListingLimitedStockCondition -# stock: 1 +- type: listing + id: RevenantBlight + name: Blight + description: Infects all nearby organisms with an infectious disease that causes toxic buildup and tiredness. Using it leaves you vulnerable to attacks for a medium period of time. + productAction: ActionRevenantBlight + cost: + StolenEssence: 75 + categories: + - RevenantAbilities + conditions: + - !type:ListingLimitedStockCondition + stock: 1 - type: listing id: RevenantMalfunction