From d6f3e1be8fc8395c3b7add4cb89dcc09816095da Mon Sep 17 00:00:00 2001 From: Velcroboy <> Date: Sun, 10 Mar 2024 15:11:35 -0500 Subject: [PATCH] Add magnet pickup system from Frontier --- .../MaterialReclaimerMagnetPickupComponent.cs | 20 +++ .../MaterialStorageMagnetPickupComponent.cs | 20 +++ .../MaterialReclaimerMagnetPickupSystem.cs | 118 ++++++++++++++++++ .../MaterialStorageMagnetPickupSystem.cs | 118 ++++++++++++++++++ .../Entities/Structures/Machines/lathe.yml | 5 + .../Machines/material_reclaimer.yml | 16 +++ 6 files changed, 297 insertions(+) create mode 100644 Content.Shared/Frontier/Storage/Components/MaterialReclaimerMagnetPickupComponent.cs create mode 100644 Content.Shared/Frontier/Storage/Components/MaterialStorageMagnetPickupComponent.cs create mode 100644 Content.Shared/Frontier/Storage/EntitySystems/MaterialReclaimerMagnetPickupSystem.cs create mode 100644 Content.Shared/Frontier/Storage/EntitySystems/MaterialStorageMagnetPickupSystem.cs diff --git a/Content.Shared/Frontier/Storage/Components/MaterialReclaimerMagnetPickupComponent.cs b/Content.Shared/Frontier/Storage/Components/MaterialReclaimerMagnetPickupComponent.cs new file mode 100644 index 00000000000..e5096d00a26 --- /dev/null +++ b/Content.Shared/Frontier/Storage/Components/MaterialReclaimerMagnetPickupComponent.cs @@ -0,0 +1,20 @@ +namespace Content.Server.Storage.Components; + +/// +/// Applies an ongoing pickup area around the attached entity. +/// +[RegisterComponent] +public sealed partial class MaterialReclaimerMagnetPickupComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("nextScan")] + public TimeSpan NextScan = TimeSpan.Zero; + + [ViewVariables(VVAccess.ReadWrite), DataField("range")] + public float Range = 1f; + + /// + /// Frontier - Is the magnet currently enabled? + /// + [ViewVariables(VVAccess.ReadWrite), DataField("magnetEnabled")] + public bool MagnetEnabled = false; +} diff --git a/Content.Shared/Frontier/Storage/Components/MaterialStorageMagnetPickupComponent.cs b/Content.Shared/Frontier/Storage/Components/MaterialStorageMagnetPickupComponent.cs new file mode 100644 index 00000000000..999c96c1945 --- /dev/null +++ b/Content.Shared/Frontier/Storage/Components/MaterialStorageMagnetPickupComponent.cs @@ -0,0 +1,20 @@ +namespace Content.Server.Storage.Components; + +/// +/// Applies an ongoing pickup area around the attached entity. +/// +[RegisterComponent] +public sealed partial class MaterialStorageMagnetPickupComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("nextScan")] + public TimeSpan NextScan = TimeSpan.Zero; + + [ViewVariables(VVAccess.ReadWrite), DataField("range")] + public float Range = 1f; + + /// + /// Frontier - Is the magnet currently enabled? + /// + [ViewVariables(VVAccess.ReadWrite), DataField("magnetEnabled")] + public bool MagnetEnabled = false; +} diff --git a/Content.Shared/Frontier/Storage/EntitySystems/MaterialReclaimerMagnetPickupSystem.cs b/Content.Shared/Frontier/Storage/EntitySystems/MaterialReclaimerMagnetPickupSystem.cs new file mode 100644 index 00000000000..e7221f72347 --- /dev/null +++ b/Content.Shared/Frontier/Storage/EntitySystems/MaterialReclaimerMagnetPickupSystem.cs @@ -0,0 +1,118 @@ +using Content.Server.Storage.Components; +using Content.Shared.Materials; +using Robust.Shared.Physics.Components; +using Robust.Shared.Timing; +using Content.Shared.Examine; // Frontier +using Content.Shared.Hands.Components; // Frontier +using Content.Shared.Verbs; // Frontier +using Robust.Shared.Utility; // Frontier + +namespace Content.Shared.Storage.EntitySystems; + +/// +/// +/// +public sealed class MaterialReclaimerMagnetPickupSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly SharedMaterialReclaimerSystem _storage = default!; + + private static readonly TimeSpan ScanDelay = TimeSpan.FromSeconds(1); + + private EntityQuery _physicsQuery; + + public override void Initialize() + { + base.Initialize(); + _physicsQuery = GetEntityQuery(); + SubscribeLocalEvent(OnMagnetMapInit); + SubscribeLocalEvent(OnMagnetUnpaused); + SubscribeLocalEvent(OnExamined); // Frontier + SubscribeLocalEvent>(AddToggleMagnetVerb); // Frontier + } + + private void OnMagnetUnpaused(EntityUid uid, MaterialReclaimerMagnetPickupComponent component, ref EntityUnpausedEvent args) + { + component.NextScan += args.PausedTime; + } + + private void OnMagnetMapInit(EntityUid uid, MaterialReclaimerMagnetPickupComponent component, MapInitEvent args) + { + component.NextScan = _timing.CurTime + TimeSpan.FromSeconds(1); // Need to add 1 sec to fix a weird time bug with it that make it never start the magnet + } + + // Frontier, used to add the magnet toggle to the context menu + private void AddToggleMagnetVerb(EntityUid uid, MaterialReclaimerMagnetPickupComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + if (!HasComp(args.User)) + return; + + AlternativeVerb verb = new() + { + Act = () => + { + ToggleMagnet(uid, component); + }, + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png")), + Text = Loc.GetString("magnet-pickup-component-toggle-verb"), + Priority = 3 + }; + + args.Verbs.Add(verb); + } + + // Frontier, used to show the magnet state on examination + private void OnExamined(EntityUid uid, MaterialReclaimerMagnetPickupComponent component, ExaminedEvent args) + { + args.PushMarkup(Loc.GetString("magnet-pickup-component-on-examine-main", + ("stateText", Loc.GetString(component.MagnetEnabled + ? "magnet-pickup-component-magnet-on" + : "magnet-pickup-component-magnet-off")))); + } + + // Frontier, used to toggle the magnet on the ore bag/box + public bool ToggleMagnet(EntityUid uid, MaterialReclaimerMagnetPickupComponent comp) + { + var query = EntityQueryEnumerator(); + comp.MagnetEnabled = !comp.MagnetEnabled; + + return comp.MagnetEnabled; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + var query = EntityQueryEnumerator(); + var currentTime = _timing.CurTime; + + while (query.MoveNext(out var uid, out var comp, out var storage, out var xform)) + { + if (comp.NextScan < currentTime) + continue; + + comp.NextScan += ScanDelay; + + // Frontier - magnet disabled + if (!comp.MagnetEnabled) + continue; + + var parentUid = xform.ParentUid; + + foreach (var near in _lookup.GetEntitiesInRange(uid, comp.Range, LookupFlags.Dynamic | LookupFlags.Sundries)) + { + if (!_physicsQuery.TryGetComponent(near, out var physics) || physics.BodyStatus != BodyStatus.OnGround) + continue; + + if (near == parentUid) + continue; + + if (!_storage.TryStartProcessItem(uid, near)) + continue; + } + } + } +} diff --git a/Content.Shared/Frontier/Storage/EntitySystems/MaterialStorageMagnetPickupSystem.cs b/Content.Shared/Frontier/Storage/EntitySystems/MaterialStorageMagnetPickupSystem.cs new file mode 100644 index 00000000000..9978d4a1a75 --- /dev/null +++ b/Content.Shared/Frontier/Storage/EntitySystems/MaterialStorageMagnetPickupSystem.cs @@ -0,0 +1,118 @@ +using Content.Server.Storage.Components; +using Content.Shared.Materials; +using Robust.Shared.Physics.Components; +using Robust.Shared.Timing; +using Content.Shared.Examine; // Frontier +using Content.Shared.Hands.Components; // Frontier +using Content.Shared.Verbs; // Frontier +using Robust.Shared.Utility; // Frontier + +namespace Content.Shared.Storage.EntitySystems; + +/// +/// +/// +public sealed class MaterialStorageMagnetPickupSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly SharedMaterialStorageSystem _storage = default!; + + private static readonly TimeSpan ScanDelay = TimeSpan.FromSeconds(1); + + private EntityQuery _physicsQuery; + + public override void Initialize() + { + base.Initialize(); + _physicsQuery = GetEntityQuery(); + SubscribeLocalEvent(OnMagnetMapInit); + SubscribeLocalEvent(OnMagnetUnpaused); + SubscribeLocalEvent(OnExamined); // Frontier + SubscribeLocalEvent>(AddToggleMagnetVerb); // Frontier + } + + private void OnMagnetUnpaused(EntityUid uid, MaterialStorageMagnetPickupComponent component, ref EntityUnpausedEvent args) + { + component.NextScan += args.PausedTime; + } + + private void OnMagnetMapInit(EntityUid uid, MaterialStorageMagnetPickupComponent component, MapInitEvent args) + { + component.NextScan = _timing.CurTime + TimeSpan.FromSeconds(1); // Need to add 1 sec to fix a weird time bug with it that make it never start the magnet + } + + // Frontier, used to add the magnet toggle to the context menu + private void AddToggleMagnetVerb(EntityUid uid, MaterialStorageMagnetPickupComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + if (!HasComp(args.User)) + return; + + AlternativeVerb verb = new() + { + Act = () => + { + ToggleMagnet(uid, component); + }, + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png")), + Text = Loc.GetString("magnet-pickup-component-toggle-verb"), + Priority = 3 + }; + + args.Verbs.Add(verb); + } + + // Frontier, used to show the magnet state on examination + private void OnExamined(EntityUid uid, MaterialStorageMagnetPickupComponent component, ExaminedEvent args) + { + args.PushMarkup(Loc.GetString("magnet-pickup-component-on-examine-main", + ("stateText", Loc.GetString(component.MagnetEnabled + ? "magnet-pickup-component-magnet-on" + : "magnet-pickup-component-magnet-off")))); + } + + // Frontier, used to toggle the magnet on the ore bag/box + public bool ToggleMagnet(EntityUid uid, MaterialStorageMagnetPickupComponent comp) + { + var query = EntityQueryEnumerator(); + comp.MagnetEnabled = !comp.MagnetEnabled; + + return comp.MagnetEnabled; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + var query = EntityQueryEnumerator(); + var currentTime = _timing.CurTime; + + while (query.MoveNext(out var uid, out var comp, out var storage, out var xform)) + { + if (comp.NextScan < currentTime) + continue; + + comp.NextScan += ScanDelay; + + // Frontier - magnet disabled + if (!comp.MagnetEnabled) + continue; + + var parentUid = xform.ParentUid; + + foreach (var near in _lookup.GetEntitiesInRange(uid, comp.Range, LookupFlags.Dynamic | LookupFlags.Sundries)) + { + if (!_physicsQuery.TryGetComponent(near, out var physics) || physics.BodyStatus != BodyStatus.OnGround) + continue; + + if (near == parentUid) + continue; + + if (!_storage.TryInsertMaterialEntity(uid, near, uid, storage)) + continue; + } + } + } +} diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 02eeca1dd19..93fdfd79dcc 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -1180,6 +1180,11 @@ - IngotGold30 - IngotSilver30 - MaterialBananium10 + - type: MaterialStorageMagnetPickup # Delta V - Summary: Adds magnet pull from Frontier + range: 0.30 + whitelist: + tags: + - Ore # Delta V - End Magnet Pull - type: entity parent: OreProcessor diff --git a/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml b/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml index 829525439ed..f179c639465 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml @@ -103,3 +103,19 @@ solution: output - type: StaticPrice price: 500 + - type: MaterialReclaimerMagnetPickup # Delta V - Summary: Adds magnet pull from Frontier + range: 0.30 + whitelist: + components: + - PhysicalComposition + - SpaceGarbage + tags: + - Trash + - Recyclable + blacklist: + components: + - Material + - Pda + - IdCard + tags: + - HighRiskItem # Delta V - End Magnet Pull