]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Wizard Teleport Scroll (Teleport Location ECS) (#36424)
authorkeronshb <54602815+keronshb@users.noreply.github.com>
Mon, 28 Apr 2025 17:42:24 +0000 (13:42 -0400)
committerGitHub <noreply@github.com>
Mon, 28 Apr 2025 17:42:24 +0000 (19:42 +0200)
33 files changed:
Content.Benchmarks/PvsBenchmark.cs
Content.Client/Teleportation/TeleportLocationsSystem.cs [new file with mode: 0644]
Content.Client/Teleportation/Ui/TeleportLocationsBoundUserInterface.cs [new file with mode: 0644]
Content.Client/Teleportation/Ui/TeleportMenu.xaml [new file with mode: 0644]
Content.Client/Teleportation/Ui/TeleportMenu.xaml.cs [new file with mode: 0644]
Content.Server/Administration/Commands/WarpCommand.cs
Content.Server/Ghost/GhostSystem.cs
Content.Server/Objectives/Systems/NinjaConditionsSystem.cs
Content.Server/Pinpointer/NavMapSystem.cs
Content.Server/Teleportation/TeleportLocationsSystem.cs [new file with mode: 0644]
Content.Server/Warps/WarpPointComponent.cs [deleted file]
Content.Server/Warps/WarpPointSystem.cs
Content.Shared/Teleportation/Components/TeleportLocationsComponent.cs [new file with mode: 0644]
Content.Shared/Teleportation/Systems/SharedTeleportLocationsSystem.cs [new file with mode: 0644]
Content.Shared/Teleportation/TeleportLocationsUi.cs [new file with mode: 0644]
Content.Shared/Warps/WarpPointComponent.cs [new file with mode: 0644]
Resources/Locale/en-US/teleportation/teleportation-menu-gui.ftl [new file with mode: 0644]
Resources/Maps/centcomm.yml
Resources/Prototypes/Catalog/Fills/Lockers/suit_storage.yml
Resources/Prototypes/Entities/Markers/warp_point.yml
Resources/Prototypes/Entities/Mobs/Player/narsie.yml
Resources/Prototypes/Entities/Mobs/Player/ratvar.yml
Resources/Prototypes/Entities/Mobs/Player/silicon.yml
Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml
Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml
Resources/Prototypes/Entities/Objects/Misc/dat_fukken_disk.yml
Resources/Prototypes/Entities/Objects/Power/powersink.yml
Resources/Prototypes/Entities/Structures/Machines/nuke.yml
Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml
Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
Resources/Prototypes/Magic/teleport_scroll.yml [new file with mode: 0644]
Resources/Prototypes/Roles/Jobs/Fun/wizard_startinggear.yml
Resources/Prototypes/tags.yml

index 2f87545426eb1fdafa0e7725a81f848975ab50bf..1edbcb644870ebbc6c6034397d24f1233455e852 100644 (file)
@@ -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 (file)
index 0000000..d191b8d
--- /dev/null
@@ -0,0 +1,11 @@
+using Content.Shared.Teleportation.Systems;
+
+namespace Content.Client.Teleportation;
+
+/// <summary>
+/// <inheritdoc cref="SharedTeleportLocationsSystem"/>
+/// </summary>
+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 (file)
index 0000000..80b4f30
--- /dev/null
@@ -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<TeleportMenu>();
+
+        if (!EntMan.TryGetComponent<TeleportLocationsComponent>(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 (file)
index 0000000..50a77bb
--- /dev/null
@@ -0,0 +1,10 @@
+<DefaultWindow xmlns="https://spacestation14.io" Title = "{Loc 'teleportation-scroll-window-title'}" MinSize="450 450" SetSize="450 450">
+    <BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4">
+        <LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True" Margin="0 4" />
+        <ScrollContainer Name="TeleportScroll" VerticalExpand="True" HorizontalExpand="True" HScrollEnabled="False">
+            <BoxContainer Name="TeleportButtonContainer" Orientation="Vertical" VerticalExpand="True" SeparationOverride="5">
+                <!-- Teleport buttons get added here by code -->
+            </BoxContainer>
+        </ScrollContainer>
+    </BoxContainer>
+</DefaultWindow>
diff --git a/Content.Client/Teleportation/Ui/TeleportMenu.xaml.cs b/Content.Client/Teleportation/Ui/TeleportMenu.xaml.cs
new file mode 100644 (file)
index 0000000..1a730bf
--- /dev/null
@@ -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<TeleportPoint> Warps = new();
+
+    public event Action<NetEntity, string>? 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);
+    }
+}
index afc42c7e19f9844f2e38d719db01f3833fc4cbf0..06d771ec2ff2ab67e2d97d5ddf00503808481e57 100644 (file)
@@ -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;
index 8596927b28a89165300651c491559ee8c8c4aeed..ac0455c9a774604ebd49ff4e8309bae9f4948b5d 100644 (file)
@@ -28,6 +28,7 @@ using Content.Shared.NameModifier.EntitySystems;
 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;
index ee99658f66ef12de4f0d7f9ffd25a99d40e8ab41..808829f6d925ac8964fdef9400801f2b47a01683 100644 (file)
@@ -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;
index 3ab0e8eff1a42d3aea6143b9a78367015d7e6d5d..2819f5ba429f0d41c0bd61ed98147da241bebaf0 100644 (file)
@@ -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 (file)
index 0000000..14211d9
--- /dev/null
@@ -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;
+
+/// <summary>
+/// <inheritdoc cref="SharedTeleportLocationsSystem"/>
+/// </summary>
+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<TeleportLocationsComponent, MapInitEvent>(OnMapInit);
+        SubscribeLocalEvent<TeleportLocationsComponent, BeforeActivatableUIOpenEvent>(OnBeforeUiOpen);
+    }
+
+    private void OnMapInit(Entity<TeleportLocationsComponent> ent, ref MapInitEvent args)
+    {
+        UpdateTeleportPoints(ent);
+    }
+
+    private void OnBeforeUiOpen(Entity<TeleportLocationsComponent> ent, ref BeforeActivatableUIOpenEvent args)
+    {
+        UpdateTeleportPoints(ent);
+    }
+
+    protected override void OnTeleportToLocationRequest(Entity<TeleportLocationsComponent> 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
+    /// <summary>
+    ///     Gets the teleport points to send to the BUI
+    /// </summary>
+    private void UpdateTeleportPoints(Entity<TeleportLocationsComponent> ent)
+    {
+        ent.Comp.AvailableWarps.Clear();
+
+        var allEnts = AllEntityQuery<WarpPointComponent>();
+
+        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 (file)
index ce169f2..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Content.Server.Warps
-{
-    /// <summary>
-    /// Allows ghosts etc to warp to this entity by name.
-    /// </summary>
-    [RegisterComponent]
-    public sealed partial class WarpPointComponent : Component
-    {
-        [ViewVariables(VVAccess.ReadWrite), DataField]
-        public string? Location;
-
-        /// <summary>
-        ///     If true, ghosts warping to this entity will begin following it.
-        /// </summary>
-        [DataField]
-        public bool Follow;
-    }
-}
index d3b978a147d67e85fd95be2ebc1ae48f1ba9fa45..2e2264a81abd37ad304d3ccd2fd9e2e9c612db04 100644 (file)
@@ -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 (file)
index 0000000..ef5d6c5
--- /dev/null
@@ -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.
+/// <summary>
+/// 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
+/// </summary>
+[RegisterComponent, NetworkedComponent, Access(typeof(SharedTeleportLocationsSystem)), AutoGenerateComponentState]
+public sealed partial class TeleportLocationsComponent : Component
+{
+    /// <summary>
+    /// List of available warp points
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public HashSet<TeleportPoint> AvailableWarps = new();
+
+    /// <summary>
+    /// What should spawn as an effect when the user teleports?
+    /// </summary>
+    [DataField]
+    public EntProtoId? TeleportEffect;
+
+    /// <summary>
+    /// Should this close the BUI after teleport?
+    /// </summary>
+    [DataField]
+    public bool CloseAfterTeleport;
+
+    /// <summary>
+    /// Name of the Teleport Location menu
+    /// </summary>
+    [DataField]
+    public LocId Name;
+
+    /// <summary>
+    /// 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)"
+    /// </summary>
+    [DataField]
+    public LocId? Speech;
+}
+
+/// <summary>
+/// A teleport point, which has a location (the destination) and the entity that it represents.
+/// </summary>
+[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 (file)
index 0000000..eb4be36
--- /dev/null
@@ -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;
+
+/// <summary>
+/// <inheritdoc cref="TeleportLocationsComponent"/>
+/// </summary>
+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<TeleportLocationsComponent, ActivatableUIOpenAttemptEvent>(OnUiOpenAttempt);
+        SubscribeLocalEvent<TeleportLocationsComponent, TeleportLocationDestinationMessage>(OnTeleportToLocationRequest);
+    }
+
+    private void OnUiOpenAttempt(Entity<TeleportLocationsComponent> ent, ref ActivatableUIOpenAttemptEvent args)
+    {
+        if (!Delay.IsDelayed(ent.Owner, TeleportDelay))
+            return;
+
+        args.Cancel();
+    }
+
+    protected virtual void OnTeleportToLocationRequest(Entity<TeleportLocationsComponent> ent, ref TeleportLocationDestinationMessage args)
+    {
+        if (!TryGetEntity(args.NetEnt, out var telePointEnt) || TerminatingOrDeleted(telePointEnt) || !HasComp<WarpPointComponent>(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 (file)
index 0000000..f4ca975
--- /dev/null
@@ -0,0 +1,19 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Teleportation;
+
+[Serializable, NetSerializable]
+public enum TeleportLocationUiKey : byte
+{
+    Key
+}
+
+/// <summary>
+/// Sends message to request that the clicker teleports to the requested location
+/// </summary>
+[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 (file)
index 0000000..61e84a6
--- /dev/null
@@ -0,0 +1,27 @@
+using Content.Shared.Whitelist;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Warps;
+
+/// <summary>
+/// Allows ghosts etc to warp to this entity by name.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class WarpPointComponent : Component
+{
+    [ViewVariables(VVAccess.ReadWrite), DataField]
+    public string? Location;
+
+    /// <summary>
+    /// If true, ghosts warping to this entity will begin following it.
+    /// </summary>
+    [DataField]
+    public bool Follow;
+
+    /// <summary>
+    /// What points should be excluded?
+    /// Useful where you want things like a ghost to reach only like CentComm
+    /// </summary>
+    [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 (file)
index 0000000..847f2cb
--- /dev/null
@@ -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}
index 39ed39ed9e2ae9c1224af56e7dbbafda51200e71..6405c6592314e0a65e7200e9c736010fc41dae64 100644 (file)
@@ -1,10 +1,10 @@
 meta:
   format: 7
   category: Grid
-  engineVersion: 247.2.0
+  engineVersion: 250.0.0
   forkId: ""
   forkVersion: ""
-  time: 03/05/2025 09:01:26
+  time: 04/24/2025 00:06:42
   entityCount: 9680
 maps: []
 grids:
@@ -21722,6 +21722,88 @@ entities:
     - type: Transform
       pos: 3.5,-12.5
       parent: 1668
+- proto: ChemistryBottleEpinephrine
+  entities:
+  - uid: 6859
+    components:
+    - type: Transform
+      parent: 6846
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+  - uid: 6860
+    components:
+    - type: Transform
+      parent: 6846
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+  - uid: 6867
+    components:
+    - type: Transform
+      parent: 6865
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+  - uid: 6871
+    components:
+    - type: Transform
+      parent: 6865
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+- proto: ChemistryBottleOmnizine
+  entities:
+  - uid: 6862
+    components:
+    - type: Transform
+      parent: 6846
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+  - uid: 6863
+    components:
+    - type: Transform
+      parent: 6846
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+  - uid: 6866
+    components:
+    - type: Transform
+      parent: 6865
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+  - uid: 6876
+    components:
+    - type: Transform
+      parent: 6865
+    - type: Physics
+      canCollide: False
+    - type: InsideEntityStorage
+- proto: ChemistryBottleUnstableMutagen
+  entities:
+  - uid: 1035
+    components:
+    - type: Transform
+      pos: 7.383148,-17.230762
+      parent: 1668
+  - uid: 1036
+    components:
+    - type: Transform
+      pos: 7.6053705,-17.223818
+      parent: 1668
+  - uid: 1037
+    components:
+    - type: Transform
+      pos: 7.5012035,-17.411318
+      parent: 1668
+  - uid: 1038
+    components:
+    - type: Transform
+      pos: 7.7303705,-17.411318
+      parent: 1668
 - proto: ChemistryHotplate
   entities:
   - uid: 671
@@ -23874,36 +23956,34 @@ entities:
     - type: Transform
       pos: -12.5,5.5
       parent: 1668
-- proto: DefaultStationBeacon
+- proto: DefaultStationBeaconCentComm
   entities:
   - uid: 4656
     components:
     - type: Transform
       pos: -0.5,3.5
       parent: 1668
-    - type: NavMapBeacon
-      text: CentComm
+- proto: DefaultStationBeaconCentCommAfterhours
+  entities:
   - uid: 9452
     components:
     - type: Transform
       pos: 22.5,-21.5
       parent: 1668
-    - type: NavMapBeacon
-      text: Afterhours
-  - uid: 9479
+- proto: DefaultStationBeaconCentCommERT
+  entities:
+  - uid: 9480
     components:
     - type: Transform
-      pos: -0.5,-41.5
+      pos: -41.5,-7.5
       parent: 1668
-    - type: NavMapBeacon
-      text: Thunderdome
-  - uid: 9480
+- proto: DefaultStationBeaconCentCommThunderdome
+  entities:
+  - uid: 9479
     components:
     - type: Transform
-      pos: -41.5,-7.5
+      pos: -0.5,-41.5
       parent: 1668
-    - type: NavMapBeacon
-      text: ERT
 - proto: DefibrillatorCabinetFilled
   entities:
   - uid: 511
@@ -26409,36 +26489,6 @@ entities:
     - type: Transform
       pos: 13.91264,32.80469
       parent: 1668
-- proto: EpinephrineChemistryBottle
-  entities:
-  - uid: 6859
-    components:
-    - type: Transform
-      parent: 6846
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
-  - uid: 6860
-    components:
-    - type: Transform
-      parent: 6846
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
-  - uid: 6867
-    components:
-    - type: Transform
-      parent: 6865
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
-  - uid: 6871
-    components:
-    - type: Transform
-      parent: 6865
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
 - proto: ERTEngineerPDA
   entities:
   - uid: 6784
@@ -43141,36 +43191,6 @@ entities:
     - type: Transform
       pos: -1.4979519,1.1034296
       parent: 1668
-- proto: OmnizineChemistryBottle
-  entities:
-  - uid: 6862
-    components:
-    - type: Transform
-      parent: 6846
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
-  - uid: 6863
-    components:
-    - type: Transform
-      parent: 6846
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
-  - uid: 6866
-    components:
-    - type: Transform
-      parent: 6865
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
-  - uid: 6876
-    components:
-    - type: Transform
-      parent: 6865
-    - type: Physics
-      canCollide: False
-    - type: InsideEntityStorage
 - proto: OreProcessor
   entities:
   - uid: 4080
@@ -53982,28 +54002,6 @@ entities:
         - Left: Reverse
         - Right: Forward
         - Middle: Off
-- proto: UnstableMutagenChemistryBottle
-  entities:
-  - uid: 1035
-    components:
-    - type: Transform
-      pos: 7.383148,-17.230762
-      parent: 1668
-  - uid: 1036
-    components:
-    - type: Transform
-      pos: 7.6053705,-17.223818
-      parent: 1668
-  - uid: 1037
-    components:
-    - type: Transform
-      pos: 7.5012035,-17.411318
-      parent: 1668
-  - uid: 1038
-    components:
-    - type: Transform
-      pos: 7.7303705,-17.411318
-      parent: 1668
 - proto: UraniumReinforcedWindowDirectional
   entities:
   - uid: 9601
index f33474702437bc1e3f75324f8e0d40a780dabc27..a8fd6e2b2dc2299e1a7dfa551d6dfb96b3559a1b 100644 (file)
   - type: StorageFill
     contents:
         - id: OxygenTankFilled
-        - id: ClothingOuterHardsuitWizard
         - id: ClothingMaskBreath
-        - id: JetpackVoidFilled
+        # TODO: Gone until reworked to have no space protection
+        #- id: ClothingOuterHardsuitWizard
+        #- id: JetpackVoidFilled
index 2536fde47458f49416b319d7f1894b61d2d3265e..675938c09bc45e3503547812ca4008eff30f0db3 100644 (file)
   - 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
   suffix: ninja bombing target
   components:
   - type: BombingTarget
+  - type: Tag
+    tags:
+    - GhostOnlyWarp
   - type: WarpPoint
     location: bombing target
+    blacklist:
+      tags:
+      - GhostOnlyWarp
   - type: Sprite
     layers:
     - state: pink
index 5d07409b5f81574c2340c3ae567850caca357f61..f2b81f796c7a531e63011f7ab169b5fb20a64c27 100644 (file)
   - type: GravityWell
     baseRadialAcceleration: 6
     maxRange: 8
+  - type: Tag
+    tags:
+    - GhostOnlyWarp
   - type: WarpPoint
     follow: true
     location: Nar'Sie
+    blacklist:
+      tags:
+      - GhostOnlyWarp
index 530f5e10374cce751645b3a6122ff0de91106b8f..658f14a6d40d445e1cd943ae57ee58cc064568ea 100644 (file)
   - type: GravityWell
     baseRadialAcceleration: 6
     maxRange: 8
+  - type: Tag
+    tags:
+    - GhostOnlyWarp
   - type: WarpPoint
     follow: true
     location: Ratvar
+    blacklist:
+      tags:
+      - GhostOnlyWarp
index 934e9d3674460a67b113e71f24a85e7df9fefafb..99a4cbd7962d8960bbbc9bf10fefe691c4266a91 100644 (file)
   description: Handles AI interactions across holocards + AI cores
   components:
   - type: ItemSlots
+  - type: Tag
+    tags:
+    - GhostOnlyWarp
   - type: StationAiHolder
     slot:
       name: station-ai-mind-slot
   suffix: Empty
   components:
   - type: WarpPoint
+    blacklist:
+      tags:
+      - GhostOnlyWarp
   - type: ContainerComp
     proto: AiHeld
     container: station_ai_mind_slot
   categories: [ HideSpawnMenu, DoNotMap ]
   components:
   - type: NoFTL
+  - type: Tag
+    tags:
+    - GhostOnlyWarp
   - type: WarpPoint
     follow: true
+    blacklist:
+      tags:
+      - GhostOnlyWarp
   - type: Eye
     pvsScale: 1.5
   - type: Visibility
   components:
   - type: Transform
     anchored: true
+  - type: Tag
+    tags:
+    - GhostOnlyWarp
   - type: WarpPoint
     follow: true
+    blacklist:
+      tags:
+      - GhostOnlyWarp
   - type: Eye
   - type: ContentEye
   - type: Examiner
index 3d5b78397ef3b259b46a0ac08169d4a802854488..569fd47d00a88d82d565451627bbe9fef0e71dc8 100644 (file)
   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
index bbadf4f220c903b9ab6f369dbf8730e639155896..324502c3d1f732b52999c30ac867b30fdc33ce9b 100644 (file)
@@ -32,6 +32,9 @@
   - type: WarpPoint
     follow: true
     location: immovable rod
+    blacklist:
+      tags:
+      - GhostOnlyWarp
 
 - type: entity
   id: ImmovableRodDespawn
index e1fc3fa5b6f647588390784b15cec63fbc883afc..523385788ba179e7afc383169096844ccecec872 100644 (file)
   - type: WarpPoint
     follow: true
     location: nuke disk
+    blacklist:
+      tags:
+      - GhostOnlyWarp
   - type: Tag
     tags:
     - HighRiskItem
+    - GhostOnlyWarp
   - type: StealTarget
     stealGroup: NukeDisk
 
index 40406209a7221eae6645262ff26033dd29eee54b..5d1043f08c44fa111bb550b2ece32427876ab32f 100644 (file)
     - type: Sprite
       sprite: Objects/Power/powersink.rsi
       state: powersink
+    - type: Tag
+      tags:
+      - GhostOnlyWarp
     - type: WarpPoint
       location: powersink
+      blacklist:
+        tags:
+        - GhostOnlyWarp
index 7fdd80bd2b11174babd4bc6ab42a8824e9df6893..0ac4a9e98f29cd04d9d4337daa46c686533631dd 100644 (file)
       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
index 461b17efbb69c363987f43f481963f615c46a5d2..1e439ddae48774d740f119b3b22aec8b352f0131 100644 (file)
     - 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
index 909601e06665139051cb94fe2a18f3bf772e0656..d31f7526abebaea143f15cf9b5b46451200e9b8d 100644 (file)
   - 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 (file)
index 0000000..89c9ae5
--- /dev/null
@@ -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
index d296a02754c922530e9cf520229bed0235b01fa1..d137df195ee79572d31f4b8aa02a19082b594346 100644 (file)
@@ -10,7 +10,7 @@
     id: WizardPDA
     ears: ClothingHeadsetAltWizard
     belt: ClothingBeltWand
-    # pocket1: TODO: Include wizard teleport scroll
+    pocket1: WizardTeleportScroll
     pocket2: WizardsGrimoire
 
 - type: startingGear
@@ -28,9 +28,3 @@
     jumpsuit: ClothingUniformJumpsuitColorPurple
     head: ClothingHeadHatVioletwizard
     outerClothing: ClothingOuterWizardViolet
-
-- type: startingGear
-  id: WizardHardsuitGear
-  parent: WizardVioletGear
-  equipment:
-    outerClothing: ClothingOuterHardsuitWizard
index efd74cfe64955d8de82cb5caaa6288b87a8e7aba..9020bec89fb5427813e214c3ad9964479e03dc6d 100644 (file)
 - type: Tag
   id: GeigerCounter
 
+# Used for warps
+- type: Tag
+  id: GhostOnlyWarp
+
 - type: Tag
   id: GlassAirlock