From 83d95e0b210927a5ca354ee5dfd0aed9e824df8f Mon Sep 17 00:00:00 2001 From: keronshb <54602815+keronshb@users.noreply.github.com> Date: Mon, 28 Apr 2025 20:42:24 +0300 Subject: [PATCH] Wizard Teleport Scroll (Teleport Location ECS) (#36424) (cherry picked from commit 0a394d4af5b3b5320a011ae2bbe0542f41fe22dc) --- Content.Benchmarks/PvsBenchmark.cs | 1 + .../Teleportation/TeleportLocationsSystem.cs | 11 +++ .../Ui/TeleportLocationsBoundUserInterface.cs | 36 +++++++++ .../Teleportation/Ui/TeleportMenu.xaml | 10 +++ .../Teleportation/Ui/TeleportMenu.xaml.cs | 74 +++++++++++++++++++ .../Administration/Commands/WarpCommand.cs | 1 + Content.Server/Ghost/GhostSystem.cs | 1 + .../Systems/NinjaConditionsSystem.cs | 1 + Content.Server/Pinpointer/NavMapSystem.cs | 1 + .../Teleportation/TeleportLocationsSystem.cs | 71 ++++++++++++++++++ Content.Server/Warps/WarpPointComponent.cs | 18 ----- Content.Server/Warps/WarpPointSystem.cs | 1 + .../Components/TeleportLocationsComponent.cs | 66 +++++++++++++++++ .../Systems/SharedTeleportLocationsSystem.cs | 59 +++++++++++++++ .../Teleportation/TeleportLocationsUi.cs | 19 +++++ Content.Shared/Warps/WarpPointComponent.cs | 27 +++++++ .../teleportation/teleportation-menu-gui.ftl | 6 ++ .../Entities/Markers/warp_point.yml | 22 ++++++ .../Entities/Mobs/Player/narsie.yml | 6 ++ .../Entities/Mobs/Player/ratvar.yml | 6 ++ .../Entities/Mobs/Player/silicon.yml | 18 +++++ .../Objects/Devices/station_beacon.yml | 47 ++++++++++++ .../Entities/Objects/Fun/immovable_rod.yml | 3 + .../Entities/Objects/Misc/dat_fukken_disk.yml | 4 + .../Entities/Objects/Power/powersink.yml | 6 ++ .../Entities/Structures/Machines/nuke.yml | 6 ++ .../Generation/Singularity/singularity.yml | 6 ++ .../Power/Generation/Tesla/energyball.yml | 6 ++ .../Prototypes/Magic/teleport_scroll.yml | 26 +++++++ .../Roles/Jobs/Fun/wizard_startinggear.yml | 8 +- Resources/Prototypes/tags.yml | 4 + 31 files changed, 546 insertions(+), 25 deletions(-) create mode 100644 Content.Client/Teleportation/TeleportLocationsSystem.cs create mode 100644 Content.Client/Teleportation/Ui/TeleportLocationsBoundUserInterface.cs create mode 100644 Content.Client/Teleportation/Ui/TeleportMenu.xaml create mode 100644 Content.Client/Teleportation/Ui/TeleportMenu.xaml.cs create mode 100644 Content.Server/Teleportation/TeleportLocationsSystem.cs delete mode 100644 Content.Server/Warps/WarpPointComponent.cs create mode 100644 Content.Shared/Teleportation/Components/TeleportLocationsComponent.cs create mode 100644 Content.Shared/Teleportation/Systems/SharedTeleportLocationsSystem.cs create mode 100644 Content.Shared/Teleportation/TeleportLocationsUi.cs create mode 100644 Content.Shared/Warps/WarpPointComponent.cs create mode 100644 Resources/Locale/en-US/teleportation/teleportation-menu-gui.ftl create mode 100644 Resources/Prototypes/Magic/teleport_scroll.yml diff --git a/Content.Benchmarks/PvsBenchmark.cs b/Content.Benchmarks/PvsBenchmark.cs index 2f87545426..1edbcb6448 100644 --- a/Content.Benchmarks/PvsBenchmark.cs +++ b/Content.Benchmarks/PvsBenchmark.cs @@ -7,6 +7,7 @@ using Content.IntegrationTests; using Content.IntegrationTests.Pair; using Content.Server.Mind; using Content.Server.Warps; +using Content.Shared.Warps; using Robust.Shared; using Robust.Shared.Analyzers; using Robust.Shared.EntitySerialization; diff --git a/Content.Client/Teleportation/TeleportLocationsSystem.cs b/Content.Client/Teleportation/TeleportLocationsSystem.cs new file mode 100644 index 0000000000..d191b8d385 --- /dev/null +++ b/Content.Client/Teleportation/TeleportLocationsSystem.cs @@ -0,0 +1,11 @@ +using Content.Shared.Teleportation.Systems; + +namespace Content.Client.Teleportation; + +/// +/// +/// +public sealed partial class TeleportLocationsSystem : SharedTeleportLocationsSystem +{ + +} diff --git a/Content.Client/Teleportation/Ui/TeleportLocationsBoundUserInterface.cs b/Content.Client/Teleportation/Ui/TeleportLocationsBoundUserInterface.cs new file mode 100644 index 0000000000..80b4f30094 --- /dev/null +++ b/Content.Client/Teleportation/Ui/TeleportLocationsBoundUserInterface.cs @@ -0,0 +1,36 @@ +using Content.Shared.Teleportation; +using Content.Shared.Teleportation.Components; +using JetBrains.Annotations; +using Robust.Client.UserInterface; + +namespace Content.Client.Teleportation.Ui; + +[UsedImplicitly] +public sealed class TeleportLocationsBoundUserInterface : BoundUserInterface +{ + [ViewVariables] + private TeleportMenu? _menu; + + public TeleportLocationsBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + base.Open(); + + _menu = this.CreateWindow(); + + if (!EntMan.TryGetComponent(Owner, out var teleComp)) + return; + + _menu.Title = Loc.GetString(teleComp.Name); + _menu.Warps = teleComp.AvailableWarps; + _menu.AddTeleportButtons(); + + _menu.TeleportClicked += (netEnt, pointName) => + { + SendPredictedMessage(new TeleportLocationDestinationMessage(netEnt, pointName)); + }; + } +} diff --git a/Content.Client/Teleportation/Ui/TeleportMenu.xaml b/Content.Client/Teleportation/Ui/TeleportMenu.xaml new file mode 100644 index 0000000000..50a77bbbcc --- /dev/null +++ b/Content.Client/Teleportation/Ui/TeleportMenu.xaml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Content.Client/Teleportation/Ui/TeleportMenu.xaml.cs b/Content.Client/Teleportation/Ui/TeleportMenu.xaml.cs new file mode 100644 index 0000000000..1a730bf747 --- /dev/null +++ b/Content.Client/Teleportation/Ui/TeleportMenu.xaml.cs @@ -0,0 +1,74 @@ +using System.Numerics; +using Content.Shared.Teleportation.Components; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Client.UserInterface.Controls; + +namespace Content.Client.Teleportation.Ui; + +[GenerateTypedNameReferences] +public sealed partial class TeleportMenu : DefaultWindow +{ + public string SearchText = ""; + + public HashSet Warps = new(); + + public event Action? TeleportClicked; + + public TeleportMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + SearchBar.OnTextChanged += OnSearchTextChanged; + } + + public void AddTeleportButtons() + { + foreach (var points in Warps) + { + var name = points.Location; + var teleportPoint = points.TelePoint; + + var currentButtonRef = new Button + { + Text = name, + TextAlign = Label.AlignMode.Right, + HorizontalAlignment = HAlignment.Center, + VerticalAlignment = VAlignment.Center, + SizeFlagsStretchRatio = 1, + MinSize = new Vector2(340, 20), + ClipText = true, + }; + + currentButtonRef.OnPressed += _ => TeleportClicked?.Invoke(teleportPoint, name); + currentButtonRef.Visible = ButtonIsVisible(currentButtonRef); + + TeleportButtonContainer.AddChild(currentButtonRef); + } + } + + private bool ButtonIsVisible(Button button) + { + return string.IsNullOrEmpty(SearchText) || button.Text == null || + button.Text.Contains(SearchText, StringComparison.OrdinalIgnoreCase); + } + + private void UpdateVisibleButtons() + { + foreach (var child in TeleportButtonContainer.Children) + { + if (child is Button button) + button.Visible = ButtonIsVisible(button); + } + } + + public void OnSearchTextChanged(LineEdit.LineEditEventArgs args) + { + SearchText = args.Text; + UpdateVisibleButtons(); + // Very funny it's called TeleportScroll + TeleportScroll.SetScrollValue(Vector2.Zero); + } +} diff --git a/Content.Server/Administration/Commands/WarpCommand.cs b/Content.Server/Administration/Commands/WarpCommand.cs index 0d6da0d993..8a2c133e44 100644 --- a/Content.Server/Administration/Commands/WarpCommand.cs +++ b/Content.Server/Administration/Commands/WarpCommand.cs @@ -4,6 +4,7 @@ using Content.Server.Warps; using Content.Shared.Administration; using Content.Shared.Follower; using Content.Shared.Ghost; +using Content.Shared.Warps; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Map; diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index accc0a9c86..a843d9e4cb 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -30,6 +30,7 @@ using Content.Shared.Movement.Systems; using Content.Shared.Popups; using Content.Shared.Storage.Components; using Content.Shared.Tag; +using Content.Shared.Warps; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Configuration; diff --git a/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs b/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs index ee99658f66..808829f6d9 100644 --- a/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs +++ b/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Warps; using Content.Shared.Objectives.Components; using Content.Shared.Ninja.Components; using Content.Shared.Roles; +using Content.Shared.Warps; using Robust.Shared.Random; namespace Content.Server.Objectives.Systems; diff --git a/Content.Server/Pinpointer/NavMapSystem.cs b/Content.Server/Pinpointer/NavMapSystem.cs index 547ac47f23..dcedeb15cc 100644 --- a/Content.Server/Pinpointer/NavMapSystem.cs +++ b/Content.Server/Pinpointer/NavMapSystem.cs @@ -13,6 +13,7 @@ using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Timing; using System.Diagnostics.CodeAnalysis; +using Content.Shared.Warps; namespace Content.Server.Pinpointer; diff --git a/Content.Server/Teleportation/TeleportLocationsSystem.cs b/Content.Server/Teleportation/TeleportLocationsSystem.cs new file mode 100644 index 0000000000..14211d9672 --- /dev/null +++ b/Content.Server/Teleportation/TeleportLocationsSystem.cs @@ -0,0 +1,71 @@ +using Content.Server.Chat.Systems; +using Content.Shared.Teleportation; +using Content.Shared.Teleportation.Components; +using Content.Shared.Teleportation.Systems; +using Content.Shared.UserInterface; +using Content.Shared.Warps; +using Content.Shared.Whitelist; + +namespace Content.Server.Teleportation; + +/// +/// +/// +public sealed partial class TeleportLocationsSystem : SharedTeleportLocationsSystem +{ + [Dependency] private readonly ChatSystem _chat = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnBeforeUiOpen); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + UpdateTeleportPoints(ent); + } + + private void OnBeforeUiOpen(Entity ent, ref BeforeActivatableUIOpenEvent args) + { + UpdateTeleportPoints(ent); + } + + protected override void OnTeleportToLocationRequest(Entity ent, ref TeleportLocationDestinationMessage args) + { + if (Delay.IsDelayed(ent.Owner, TeleportDelay)) + return; + + if (!string.IsNullOrWhiteSpace(ent.Comp.Speech)) + { + var msg = Loc.GetString(ent.Comp.Speech, ("location", args.PointName)); + _chat.TrySendInGameICMessage(args.Actor, msg, InGameICChatType.Speak, ChatTransmitRange.Normal); + } + + base.OnTeleportToLocationRequest(ent, ref args); + } + + // If it's in shared this doesn't populate the points on the UI + /// + /// Gets the teleport points to send to the BUI + /// + private void UpdateTeleportPoints(Entity ent) + { + ent.Comp.AvailableWarps.Clear(); + + var allEnts = AllEntityQuery(); + + while (allEnts.MoveNext(out var warpEnt, out var warpPointComp)) + { + if (_whitelist.IsBlacklistPass(warpPointComp.Blacklist, warpEnt) || string.IsNullOrWhiteSpace(warpPointComp.Location)) + continue; + + ent.Comp.AvailableWarps.Add(new TeleportPoint(warpPointComp.Location, GetNetEntity(warpEnt))); + } + + Dirty(ent); + } +} diff --git a/Content.Server/Warps/WarpPointComponent.cs b/Content.Server/Warps/WarpPointComponent.cs deleted file mode 100644 index ce169f2e19..0000000000 --- a/Content.Server/Warps/WarpPointComponent.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Content.Server.Warps -{ - /// - /// Allows ghosts etc to warp to this entity by name. - /// - [RegisterComponent] - public sealed partial class WarpPointComponent : Component - { - [ViewVariables(VVAccess.ReadWrite), DataField] - public string? Location; - - /// - /// If true, ghosts warping to this entity will begin following it. - /// - [DataField] - public bool Follow; - } -} diff --git a/Content.Server/Warps/WarpPointSystem.cs b/Content.Server/Warps/WarpPointSystem.cs index d3b978a147..2e2264a81a 100644 --- a/Content.Server/Warps/WarpPointSystem.cs +++ b/Content.Server/Warps/WarpPointSystem.cs @@ -1,5 +1,6 @@ using Content.Shared.Examine; using Content.Shared.Ghost; +using Content.Shared.Warps; namespace Content.Server.Warps; diff --git a/Content.Shared/Teleportation/Components/TeleportLocationsComponent.cs b/Content.Shared/Teleportation/Components/TeleportLocationsComponent.cs new file mode 100644 index 0000000000..ef5d6c5b2c --- /dev/null +++ b/Content.Shared/Teleportation/Components/TeleportLocationsComponent.cs @@ -0,0 +1,66 @@ +using Content.Shared.Teleportation.Systems; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared.Teleportation.Components; + +// TODO: In the future assimilate ghost UI to use this. +/// +/// Used where you want an entity to display a list of player-safe teleport locations +/// They teleport to the location clicked +/// Looks for non Ghost-Only WarpPointComponents +/// +[RegisterComponent, NetworkedComponent, Access(typeof(SharedTeleportLocationsSystem)), AutoGenerateComponentState] +public sealed partial class TeleportLocationsComponent : Component +{ + /// + /// List of available warp points + /// + [DataField, AutoNetworkedField] + public HashSet AvailableWarps = new(); + + /// + /// What should spawn as an effect when the user teleports? + /// + [DataField] + public EntProtoId? TeleportEffect; + + /// + /// Should this close the BUI after teleport? + /// + [DataField] + public bool CloseAfterTeleport; + + /// + /// Name of the Teleport Location menu + /// + [DataField] + public LocId Name; + + /// + /// Should the user have some speech if they teleport? + /// If enabled it will be prepended to the location name. + /// So something like "I am going to" would become "I am going to (Bridge)" + /// + [DataField] + public LocId? Speech; +} + +/// +/// A teleport point, which has a location (the destination) and the entity that it represents. +/// +[Serializable, NetSerializable, DataDefinition] +public partial record struct TeleportPoint +{ + [DataField] + public string Location; + [DataField] + public NetEntity TelePoint; + + public TeleportPoint(string Location, NetEntity TelePoint) + { + this.Location = Location; + this.TelePoint = TelePoint; + } +} diff --git a/Content.Shared/Teleportation/Systems/SharedTeleportLocationsSystem.cs b/Content.Shared/Teleportation/Systems/SharedTeleportLocationsSystem.cs new file mode 100644 index 0000000000..eb4be36ced --- /dev/null +++ b/Content.Shared/Teleportation/Systems/SharedTeleportLocationsSystem.cs @@ -0,0 +1,59 @@ +using Content.Shared.Teleportation.Components; +using Content.Shared.Timing; +using Content.Shared.UserInterface; +using Content.Shared.Warps; + +namespace Content.Shared.Teleportation.Systems; + +/// +/// +/// +public abstract partial class SharedTeleportLocationsSystem : EntitySystem +{ + [Dependency] protected readonly UseDelaySystem Delay = default!; + + [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; + [Dependency] private readonly SharedTransformSystem _xform = default!; + + protected const string TeleportDelay = "TeleportDelay"; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUiOpenAttempt); + SubscribeLocalEvent(OnTeleportToLocationRequest); + } + + private void OnUiOpenAttempt(Entity ent, ref ActivatableUIOpenAttemptEvent args) + { + if (!Delay.IsDelayed(ent.Owner, TeleportDelay)) + return; + + args.Cancel(); + } + + protected virtual void OnTeleportToLocationRequest(Entity ent, ref TeleportLocationDestinationMessage args) + { + if (!TryGetEntity(args.NetEnt, out var telePointEnt) || TerminatingOrDeleted(telePointEnt) || !HasComp(telePointEnt) || Delay.IsDelayed(ent.Owner, TeleportDelay)) + return; + + var comp = ent.Comp; + var originEnt = args.Actor; + var telePointXForm = Transform(telePointEnt.Value); + + SpawnAtPosition(comp.TeleportEffect, Transform(originEnt).Coordinates); + + _xform.SetMapCoordinates(originEnt, _xform.GetMapCoordinates(telePointEnt.Value, telePointXForm)); + + SpawnAtPosition(comp.TeleportEffect, telePointXForm.Coordinates); + + Delay.TryResetDelay(ent.Owner, true, id: TeleportDelay); + + if (!ent.Comp.CloseAfterTeleport) + return; + + // Teleport's done, now tell the BUI to close if needed. + _ui.CloseUi(ent.Owner, TeleportLocationUiKey.Key); + } +} diff --git a/Content.Shared/Teleportation/TeleportLocationsUi.cs b/Content.Shared/Teleportation/TeleportLocationsUi.cs new file mode 100644 index 0000000000..f4ca97584a --- /dev/null +++ b/Content.Shared/Teleportation/TeleportLocationsUi.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Teleportation; + +[Serializable, NetSerializable] +public enum TeleportLocationUiKey : byte +{ + Key +} + +/// +/// Sends message to request that the clicker teleports to the requested location +/// +[Serializable, NetSerializable] +public sealed class TeleportLocationDestinationMessage(NetEntity netEnt, string pointName) : BoundUserInterfaceMessage +{ + public NetEntity NetEnt = netEnt; + public string PointName = pointName; +} diff --git a/Content.Shared/Warps/WarpPointComponent.cs b/Content.Shared/Warps/WarpPointComponent.cs new file mode 100644 index 0000000000..61e84a660c --- /dev/null +++ b/Content.Shared/Warps/WarpPointComponent.cs @@ -0,0 +1,27 @@ +using Content.Shared.Whitelist; +using Robust.Shared.GameStates; + +namespace Content.Shared.Warps; + +/// +/// Allows ghosts etc to warp to this entity by name. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class WarpPointComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField] + public string? Location; + + /// + /// If true, ghosts warping to this entity will begin following it. + /// + [DataField] + public bool Follow; + + /// + /// What points should be excluded? + /// Useful where you want things like a ghost to reach only like CentComm + /// + [DataField] + public EntityWhitelist? Blacklist; +} diff --git a/Resources/Locale/en-US/teleportation/teleportation-menu-gui.ftl b/Resources/Locale/en-US/teleportation/teleportation-menu-gui.ftl new file mode 100644 index 0000000000..847f2cbc54 --- /dev/null +++ b/Resources/Locale/en-US/teleportation/teleportation-menu-gui.ftl @@ -0,0 +1,6 @@ +## Default +teleportation-menu-default-window-title = Teleportation Menu + +## Wizard +teleportation-scroll-window-title = Teleportation Scroll +teleportation-scroll-speech-wizard = EY TCHEL TORT TU {$location} diff --git a/Resources/Prototypes/Entities/Markers/warp_point.yml b/Resources/Prototypes/Entities/Markers/warp_point.yml index 2536fde474..675938c09b 100644 --- a/Resources/Prototypes/Entities/Markers/warp_point.yml +++ b/Resources/Prototypes/Entities/Markers/warp_point.yml @@ -16,6 +16,22 @@ - type: WarpPoint location: beacon +# Use for areas like CC +- type: entity + id: GhostWarpPoint + parent: MarkerBase + name: ghost only warp point + components: + - type: Tag + tags: + - GhostOnlyWarp + - type: WarpPoint + blacklist: + tags: + - GhostOnlyWarp + - type: Sprite + state: pink + - type: entity parent: WarpPoint id: WarpPointBombing @@ -23,8 +39,14 @@ suffix: ninja bombing target components: - type: BombingTarget + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint location: bombing target + blacklist: + tags: + - GhostOnlyWarp - type: Sprite layers: - state: pink diff --git a/Resources/Prototypes/Entities/Mobs/Player/narsie.yml b/Resources/Prototypes/Entities/Mobs/Player/narsie.yml index 84fd15959b..4f4976106d 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/narsie.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/narsie.yml @@ -87,6 +87,12 @@ bodyType: Dynamic bodyStatus: InAir - type: CanMoveInAir + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint follow: true location: Nar'Sie + blacklist: + tags: + - GhostOnlyWarp diff --git a/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml b/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml index 530f5e1037..658f14a6d4 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml @@ -89,6 +89,12 @@ - type: GravityWell baseRadialAcceleration: 6 maxRange: 8 + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint follow: true location: Ratvar + blacklist: + tags: + - GhostOnlyWarp diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index 35c11dd208..cfca68d5eb 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -169,6 +169,9 @@ description: Handles AI interactions across holocards + AI cores components: - type: ItemSlots + - type: Tag + tags: + - GhostOnlyWarp - type: StationAiHolder slot: name: station-ai-mind-slot @@ -735,6 +738,9 @@ components: - type: IonStormTarget - type: WarpPoint + blacklist: + tags: + - GhostOnlyWarp - type: ContainerComp proto: AiHeld container: station_ai_mind_slot @@ -848,8 +854,14 @@ categories: [ HideSpawnMenu, DoNotMap ] components: - type: NoFTL + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint follow: true + blacklist: + tags: + - GhostOnlyWarp - type: Eye pvsScale: 1.5 - type: Visibility @@ -888,8 +900,14 @@ components: - type: Transform anchored: true + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint follow: true + blacklist: + tags: + - GhostOnlyWarp - type: Eye - type: ContentEye - type: Examiner diff --git a/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml b/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml index 1f56a0e1c2..a4c2e30481 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml @@ -661,3 +661,50 @@ components: - type: NavMapBeacon defaultText: station-beacon-vox + +# Ghost Only Beacons +- type: entity + parent: DefaultStationBeacon + id: DefaultStationBeaconGhost + suffix: Boo + components: + - type: Tag + tags: + - GhostOnlyWarp + - type: WarpPoint + blacklist: + tags: + - GhostOnlyWarp + +# CentComm Beacons +- type: entity + parent: DefaultStationBeaconGhost + id: DefaultStationBeaconCentComm + suffix: CentComm + components: + - type: NavMapBeacon + text: CentComm + +- type: entity + parent: DefaultStationBeaconGhost + id: DefaultStationBeaconCentCommAfterhours + suffix: CentComm Afterhours + components: + - type: NavMapBeacon + text: Afterhours + +- type: entity + parent: DefaultStationBeaconGhost + id: DefaultStationBeaconCentCommThunderdome + suffix: CentComm Thunder Dome + components: + - type: NavMapBeacon + text: Thunderdome + +- type: entity + parent: DefaultStationBeaconGhost + id: DefaultStationBeaconCentCommERT + suffix: CentComm ERT + components: + - type: NavMapBeacon + text: ERT diff --git a/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml b/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml index 318ca667fe..420cc759a7 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml @@ -32,6 +32,9 @@ - type: WarpPoint follow: true location: immovable rod + blacklist: + tags: + - GhostOnlyWarp - type: entity id: ImmovableRodDespawn diff --git a/Resources/Prototypes/Entities/Objects/Misc/dat_fukken_disk.yml b/Resources/Prototypes/Entities/Objects/Misc/dat_fukken_disk.yml index ca575b3e89..1d57742a81 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/dat_fukken_disk.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/dat_fukken_disk.yml @@ -17,9 +17,13 @@ - type: WarpPoint follow: true location: nuke disk + blacklist: + tags: + - GhostOnlyWarp - type: Tag tags: - HighRiskItem + - GhostOnlyWarp - type: StealTarget stealGroup: NukeDisk - type: EmitSoundOnPickup diff --git a/Resources/Prototypes/Entities/Objects/Power/powersink.yml b/Resources/Prototypes/Entities/Objects/Power/powersink.yml index 40406209a7..5d1043f08c 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powersink.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powersink.yml @@ -45,5 +45,11 @@ - type: Sprite sprite: Objects/Power/powersink.rsi state: powersink + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint location: powersink + blacklist: + tags: + - GhostOnlyWarp diff --git a/Resources/Prototypes/Entities/Structures/Machines/nuke.yml b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml index 6c351c0074..425a7ea5de 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/nuke.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml @@ -100,9 +100,15 @@ Nuke: !type:ContainerSlot - type: StealTarget stealGroup: NuclearBomb + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint follow: true location: nuclear bomb + blacklist: + tags: + - GhostOnlyWarp - type: FTLSmashImmune - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml index e9faaa813d..1b0d43790d 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml @@ -67,9 +67,15 @@ - SingularityEngine - SingularityTeslaEngine - Power + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint follow: true location: singularity + blacklist: + tags: + - GhostOnlyWarp - type: Sprite sprite: Structures/Power/Generation/Singularity/singularity_1.rsi shader: unshaded diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml index e4dd0d42fe..1b7e641c7d 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml @@ -90,9 +90,15 @@ - type: ChaoticJump jumpMinInterval: 8 jumpMaxInterval: 15 + - type: Tag + tags: + - GhostOnlyWarp - type: WarpPoint follow: true location: tesla ball + blacklist: + tags: + - GhostOnlyWarp - type: Sprite drawdepth: Effects sprite: Structures/Power/Generation/Tesla/energy_ball.rsi diff --git a/Resources/Prototypes/Magic/teleport_scroll.yml b/Resources/Prototypes/Magic/teleport_scroll.yml new file mode 100644 index 0000000000..89c9ae5163 --- /dev/null +++ b/Resources/Prototypes/Magic/teleport_scroll.yml @@ -0,0 +1,26 @@ +- type: entity + id: WizardTeleportScroll + name: teleport scroll + suffix: Wizard + parent: [ BaseItem, BaseMagicalContraband ] + components: + - type: UserInterface + interfaces: + enum.TeleportLocationUiKey.Key: + type: TeleportLocationsBoundUserInterface + - type: ActivatableUI + key: enum.TeleportLocationUiKey.Key + - type: Sprite + sprite: Objects/Magic/magicactions.rsi + layers: + - state: spell_default + - type: TeleportLocations + name: teleportation-scroll-window-title + teleportEffect: WizardSmoke + closeAfterTeleport: true + speech: teleportation-scroll-speech-wizard + - type: UseDelay + delay: 1 + delays: + TeleportDelay: !type:UseDelayInfo + length: 300 diff --git a/Resources/Prototypes/Roles/Jobs/Fun/wizard_startinggear.yml b/Resources/Prototypes/Roles/Jobs/Fun/wizard_startinggear.yml index 50c65d4bc7..fd3142255a 100644 --- a/Resources/Prototypes/Roles/Jobs/Fun/wizard_startinggear.yml +++ b/Resources/Prototypes/Roles/Jobs/Fun/wizard_startinggear.yml @@ -12,7 +12,7 @@ id: WizardPDA ears: ClothingHeadsetAltCommand belt: ClothingBeltWand - # pocket1: TODO: Include wizard teleport scroll + pocket1: WizardTeleportScroll pocket2: WizardsGrimoire - type: startingGear @@ -30,9 +30,3 @@ jumpsuit: ClothingUniformJumpsuitColorPurple head: ClothingHeadHatVioletwizard outerClothing: ClothingOuterWizardViolet - -- type: startingGear - id: WizardHardsuitGear - parent: WizardVioletGear - equipment: - outerClothing: ClothingOuterHardsuitWizard diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 2426b3ab4b..a96e2d24ed 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -638,6 +638,10 @@ - type: Tag id: GeigerCounter +# Used for warps +- type: Tag + id: GhostOnlyWarp + - type: Tag id: GlassAirlock