From 034a18b1d006384f86f9a8de711548864ca4f3c0 Mon Sep 17 00:00:00 2001 From: Aviu00 <93730715+Aviu00@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:02:02 +0900 Subject: [PATCH] - add: Time beacon. (#254) --- .../TimeBeacon/TimeBeaconAnchorComponent.cs | 11 ++ .../_White/TimeBeacon/TimeBeaconComponent.cs | 20 ++++ .../_White/TimeBeacon/TimeBeaconSystem.cs | 104 ++++++++++++++++++ .../ru-RU/_white/object/time-beacon.ftl | 10 ++ .../Prototypes/_White/Catalog/uplink.yml | 11 ++ .../Entities/Objects/Misc/time_beacon.yml | 24 ++++ .../door_remote.rsi/door_remotebase_white.png | Bin 0 -> 717 bytes .../Objects/Devices/door_remote.rsi/meta.json | 3 + 8 files changed, 183 insertions(+) create mode 100644 Content.Server/_White/TimeBeacon/TimeBeaconAnchorComponent.cs create mode 100644 Content.Server/_White/TimeBeacon/TimeBeaconComponent.cs create mode 100644 Content.Server/_White/TimeBeacon/TimeBeaconSystem.cs create mode 100644 Resources/Locale/ru-RU/_white/object/time-beacon.ftl create mode 100644 Resources/Prototypes/_White/Entities/Objects/Misc/time_beacon.yml create mode 100644 Resources/Textures/Objects/Devices/door_remote.rsi/door_remotebase_white.png diff --git a/Content.Server/_White/TimeBeacon/TimeBeaconAnchorComponent.cs b/Content.Server/_White/TimeBeacon/TimeBeaconAnchorComponent.cs new file mode 100644 index 0000000000..21de86fa2e --- /dev/null +++ b/Content.Server/_White/TimeBeacon/TimeBeaconAnchorComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Server._White.TimeBeacon; + +[RegisterComponent] +public sealed partial class TimeBeaconAnchorComponent : Component +{ + [ViewVariables] + public EntityUid Entity = EntityUid.Invalid; + + [DataField] + public TimeSpan Duration = TimeSpan.FromSeconds(10); +} diff --git a/Content.Server/_White/TimeBeacon/TimeBeaconComponent.cs b/Content.Server/_White/TimeBeacon/TimeBeaconComponent.cs new file mode 100644 index 0000000000..9448346003 --- /dev/null +++ b/Content.Server/_White/TimeBeacon/TimeBeaconComponent.cs @@ -0,0 +1,20 @@ +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Server._White.TimeBeacon; + +[RegisterComponent] +public sealed partial class TimeBeaconComponent : Component +{ + [ViewVariables] + public TimeSpan NextUse = TimeSpan.Zero; + + [DataField, ViewVariables(VVAccess.ReadWrite)] + public TimeSpan Cooldown = TimeSpan.FromSeconds(20); + + [DataField] + public EntProtoId AnchorEntity = "TimeBeaconAnchor"; + + [DataField] + public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Machines/high_tech_confirm.ogg"); +} diff --git a/Content.Server/_White/TimeBeacon/TimeBeaconSystem.cs b/Content.Server/_White/TimeBeacon/TimeBeaconSystem.cs new file mode 100644 index 0000000000..9467353f89 --- /dev/null +++ b/Content.Server/_White/TimeBeacon/TimeBeaconSystem.cs @@ -0,0 +1,104 @@ +using Content.Server.Popups; +using Content.Server.Pulling; +using Content.Shared.Examine; +using Content.Shared.Interaction.Events; +using Content.Shared.Popups; +using Content.Shared.Pulling.Components; +using Robust.Server.Audio; +using Robust.Server.GameObjects; +using Robust.Shared.Timing; + +namespace Content.Server._White.TimeBeacon; + +public sealed class TimeBeaconSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly TransformSystem _transform = default!; + [Dependency] private readonly PullingSystem _pulling = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUseInHand); + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnMapInit); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + Timer.Spawn(ent.Comp.Duration, () => + { + var entity = ent.Comp.Entity; + + if (entity == EntityUid.Invalid) + return; + + if (EntityManager.Deleted(ent) || EntityManager.Deleted(entity)) + return; + + if (!TryComp(ent, out TransformComponent? xform) || !TryComp(entity, out TransformComponent? entXform)) + return; + + if (xform.MapID != entXform.MapID) + return; + + // break pulls before portal enter so we dont break shit + if (TryComp(entity, out var pullable) && pullable.BeingPulled) + { + _pulling.TryStopPull(pullable); + } + + if (TryComp(entity, out var pulling) + && pulling.Pulling != null && + TryComp(pulling.Pulling.Value, out var subjectPulling)) + { + _pulling.TryStopPull(subjectPulling); + } + + _transform.SetCoordinates(entity, entXform, xform.Coordinates); + QueueDel(ent); + }); + } + + private void OnExamine(Entity ent, ref ExaminedEvent args) + { + if (ent.Comp.NextUse <= _timing.CurTime) + { + args.PushMarkup(Loc.GetString("time-beacon-component-charged")); + return; + } + + var message = Loc.GetString("time-beacon-component-charging", + ("cooldown", (int) (ent.Comp.NextUse - _timing.CurTime).TotalSeconds)); + args.PushMarkup(message); + } + + private void OnUseInHand(Entity ent, ref UseInHandEvent args) + { + var coords = CompOrNull(args.User)?.Coordinates; + + if (coords == null) + return; + + if (ent.Comp.NextUse > _timing.CurTime) + { + var message = Loc.GetString("time-beacon-component-cooldown", + ("cooldown", (int) (ent.Comp.NextUse - _timing.CurTime).TotalSeconds)); + _popup.PopupEntity(message, args.User, args.User); + return; + } + + var anchor = Spawn(ent.Comp.AnchorEntity, coords.Value); + _transform.AttachToGridOrMap(anchor); + var anchorComp = EnsureComp(anchor); + anchorComp.Entity = args.User; + + _popup.PopupEntity(Loc.GetString("time-beacon-component-anchor-set"), args.User, args.User, PopupType.Medium); + _audio.PlayEntity(ent.Comp.Sound, args.User, ent); + + ent.Comp.NextUse = _timing.CurTime + ent.Comp.Cooldown; + } +} diff --git a/Resources/Locale/ru-RU/_white/object/time-beacon.ftl b/Resources/Locale/ru-RU/_white/object/time-beacon.ftl new file mode 100644 index 0000000000..efb631fdf3 --- /dev/null +++ b/Resources/Locale/ru-RU/_white/object/time-beacon.ftl @@ -0,0 +1,10 @@ +ent-TimeBeacon = временной маяк + .desc = Перемотка! + +time-beacon-component-charged = Временной маяк [color=darkgreen]заряжен[/color] +time-beacon-component-charging = Временной маяк зарядится через [color=fuchsia]{ $cooldown }[/color] секунд. +time-beacon-component-cooldown = Временной маяк можно использовать через { $cooldown } секунд. +time-beacon-component-anchor-set = Маяк установлен! + +uplink-time-beacon = Временной маяк +uplink-time-beacon-desc = Устанавливает маяк при активации. Через 10 секунд телепортирует вас к точке маяка. Время перезарядки составляет 20 секунд. diff --git a/Resources/Prototypes/_White/Catalog/uplink.yml b/Resources/Prototypes/_White/Catalog/uplink.yml index 08c2a52f6a..09bdf2e136 100644 --- a/Resources/Prototypes/_White/Catalog/uplink.yml +++ b/Resources/Prototypes/_White/Catalog/uplink.yml @@ -63,6 +63,17 @@ categories: - UplinkAmmo +- type: listing + id: UplinkTimeBeacon + name: uplink-time-beacon + description: uplink-time-beacon-desc + productEntity: TimeBeacon + icon: { sprite: Objects/Devices/door_remote.rsi, state: door_remotebase_white } + cost: + Telecrystal: 2 + categories: + - UplinkUtility + - type: listing id: UplinkSmokeImplanter name: Имплант дыма diff --git a/Resources/Prototypes/_White/Entities/Objects/Misc/time_beacon.yml b/Resources/Prototypes/_White/Entities/Objects/Misc/time_beacon.yml new file mode 100644 index 0000000000..9ce5948401 --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Objects/Misc/time_beacon.yml @@ -0,0 +1,24 @@ +- type: entity + parent: BaseItem + id: TimeBeacon + name: time beacon + description: Rewind! + components: + - type: Sprite + sprite: Objects/Devices/door_remote.rsi + layers: + - state: door_remotebase_white + - state: door_remotelightscolour + color: "#00FFF7" + - state: door_remotescreencolour + color: "#00FFF7" + - type: Item + storedRotation: -90 + - type: TimeBeacon + +- type: entity + id: TimeBeaconAnchor + name: time beacon anchor + description: Fuck! + components: + - type: TimeBeaconAnchor diff --git a/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotebase_white.png b/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotebase_white.png new file mode 100644 index 0000000000000000000000000000000000000000..463071528f63f45af093e2fb8c44c14d07429e9c GIT binary patch literal 717 zcmV;;0y6!HP)EX>4Tx04R}tkv&MmP!xqvTcskE4t5X~$xxjvh>ALD6^c+H)C#RSn7s54nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~=;Wm6A|>9J6k5c1;qgAsyXWxUeSp7SW~$jS2B?~4 zq!Mus&lF3y9 zBgX;cejJx~0i`z~v6m_oPdP6D_nJGm<~dFufHci2c>^3A z0wV>=UiWx+SNq)l?P<>M2d>X@zsACAMF0Q+14%?dR9J=WltIdaFc5`j%72vHz*7Z0 zfZ*1J2N1nM@D85CUC1TI{p+GlG39S!X(|-*L3qZ|na4PWs8A^U5?X8I&Uwk5@M{JD zV6UeeU}oOysRnT8`T7(C0Kj*MZXIA|&SfIm&e-Hn)AaG@_)8TZ$1(QEzvglndl&$K zuIu2O3lso+{F!X$g-_(13ljRhkMD~U5v}Wb*g$d!MFhr};GQvtLl!hz_C0T1)dh!&*y9DYDiE@uq14eWwFawAK)jm&?c7whi>1 z8Ax_uS(aqHs;WR!@9g>LAbLf%bD&Tt6wcrZJrnPNy|<7-00000NkvXXu0mjfxKmEC literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Devices/door_remote.rsi/meta.json b/Resources/Textures/Objects/Devices/door_remote.rsi/meta.json index ffb1be00d3..95de47cd86 100644 --- a/Resources/Textures/Objects/Devices/door_remote.rsi/meta.json +++ b/Resources/Textures/Objects/Devices/door_remote.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "door_remotebase" }, + { + "name": "door_remotebase_white" + }, { "name": "door_remotelightscolour" },