diff --git a/Content.Shared/Frontier/Storage/Components/MaterialReclaimerMagnetPickupComponent.cs b/Content.Shared/Frontier/Storage/Components/MaterialReclaimerMagnetPickupComponent.cs new file mode 100644 index 00000000000..fb55184eb36 --- /dev/null +++ b/Content.Shared/Frontier/Storage/Components/MaterialReclaimerMagnetPickupComponent.cs @@ -0,0 +1,20 @@ +namespace Content.Shared.Frontier.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..f83c81dc9ae --- /dev/null +++ b/Content.Shared/Frontier/Storage/Components/MaterialStorageMagnetPickupComponent.cs @@ -0,0 +1,20 @@ +namespace Content.Shared.Frontier.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..bee489446f2 --- /dev/null +++ b/Content.Shared/Frontier/Storage/EntitySystems/MaterialReclaimerMagnetPickupSystem.cs @@ -0,0 +1,107 @@ +using Content.Shared.Frontier.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.Frontier.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 (!HasComp(args.User) + || !args.CanInteract + || !args.CanAccess) + return; + + AlternativeVerb verb = new() + { + Act = () => + { + component.MagnetEnabled = !component.MagnetEnabled; + }, + 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")))); + } + + 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; + + _storage.TryStartProcessItem(uid, near); + } + } + } +} diff --git a/Content.Shared/Frontier/Storage/EntitySystems/MaterialStorageMagnetPickupSystem.cs b/Content.Shared/Frontier/Storage/EntitySystems/MaterialStorageMagnetPickupSystem.cs new file mode 100644 index 00000000000..0efea1e793d --- /dev/null +++ b/Content.Shared/Frontier/Storage/EntitySystems/MaterialStorageMagnetPickupSystem.cs @@ -0,0 +1,107 @@ +using Content.Shared.Frontier.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.Frontier.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 (!HasComp(args.User) + || !args.CanInteract + || !args.CanAccess) + return; + + AlternativeVerb verb = new() + { + Act = () => + { + component.MagnetEnabled = !component.MagnetEnabled; + }, + 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")))); + } + + 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; + + _storage.TryInsertMaterialEntity(uid, near, uid, storage); + } + } + } +} diff --git a/Resources/Locale/en-US/frontier/storage/components/magnet-pickup-components.ftl b/Resources/Locale/en-US/frontier/storage/components/magnet-pickup-components.ftl new file mode 100644 index 00000000000..0a82347631f --- /dev/null +++ b/Resources/Locale/en-US/frontier/storage/components/magnet-pickup-components.ftl @@ -0,0 +1,4 @@ +magnet-pickup-component-toggle-verb = Toggle magnet +magnet-pickup-component-on-examine-main = The magnet appears to be {$stateText}. +magnet-pickup-component-magnet-on = [color=darkgreen]on[/color] +magnet-pickup-component-magnet-off = [color=darkred]off[/color] diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 02eeca1dd19..53a5dcedbb9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -1180,6 +1180,9 @@ - IngotGold30 - IngotSilver30 - MaterialBananium10 + - type: MaterialStorageMagnetPickup # Delta V - Summary: Adds magnet pull from Frontier + magnetEnabled: True + range: 0.30 # 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..66f16e5de88 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml @@ -103,3 +103,6 @@ solution: output - type: StaticPrice price: 500 + - type: MaterialReclaimerMagnetPickup # Delta V - Summary: Adds magnet pull from Frontier + magnetEnabled: True + range: 0.30 # Delta V - End Magnet Pull