Wizard Teleport Scroll (Teleport Location ECS) (#36424)

This commit is contained in:
keronshb
2025-04-28 13:42:24 -04:00
committed by GitHub
parent f6bae21184
commit 0a394d4af5
33 changed files with 645 additions and 125 deletions

View File

@@ -7,6 +7,7 @@ using Content.IntegrationTests;
using Content.IntegrationTests.Pair; using Content.IntegrationTests.Pair;
using Content.Server.Mind; using Content.Server.Mind;
using Content.Server.Warps; using Content.Server.Warps;
using Content.Shared.Warps;
using Robust.Shared; using Robust.Shared;
using Robust.Shared.Analyzers; using Robust.Shared.Analyzers;
using Robust.Shared.EntitySerialization; using Robust.Shared.EntitySerialization;

View File

@@ -0,0 +1,11 @@
using Content.Shared.Teleportation.Systems;
namespace Content.Client.Teleportation;
/// <summary>
/// <inheritdoc cref="SharedTeleportLocationsSystem"/>
/// </summary>
public sealed partial class TeleportLocationsSystem : SharedTeleportLocationsSystem
{
}

View File

@@ -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));
};
}
}

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -4,6 +4,7 @@ using Content.Server.Warps;
using Content.Shared.Administration; using Content.Shared.Administration;
using Content.Shared.Follower; using Content.Shared.Follower;
using Content.Shared.Ghost; using Content.Shared.Ghost;
using Content.Shared.Warps;
using Robust.Shared.Console; using Robust.Shared.Console;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Map; using Robust.Shared.Map;

View File

@@ -28,6 +28,7 @@ using Content.Shared.NameModifier.EntitySystems;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Storage.Components; using Content.Shared.Storage.Components;
using Content.Shared.Tag; using Content.Shared.Tag;
using Content.Shared.Warps;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;

View File

@@ -4,6 +4,7 @@ using Content.Server.Warps;
using Content.Shared.Objectives.Components; using Content.Shared.Objectives.Components;
using Content.Shared.Ninja.Components; using Content.Shared.Ninja.Components;
using Content.Shared.Roles; using Content.Shared.Roles;
using Content.Shared.Warps;
using Robust.Shared.Random; using Robust.Shared.Random;
namespace Content.Server.Objectives.Systems; namespace Content.Server.Objectives.Systems;

View File

@@ -13,6 +13,7 @@ using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Content.Shared.Warps;
namespace Content.Server.Pinpointer; namespace Content.Server.Pinpointer;

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Ghost; using Content.Shared.Ghost;
using Content.Shared.Warps;
namespace Content.Server.Warps; namespace Content.Server.Warps;

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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}

View File

@@ -1,10 +1,10 @@
meta: meta:
format: 7 format: 7
category: Grid category: Grid
engineVersion: 247.2.0 engineVersion: 250.0.0
forkId: "" forkId: ""
forkVersion: "" forkVersion: ""
time: 03/05/2025 09:01:26 time: 04/24/2025 00:06:42
entityCount: 9680 entityCount: 9680
maps: [] maps: []
grids: grids:
@@ -21722,6 +21722,88 @@ entities:
- type: Transform - type: Transform
pos: 3.5,-12.5 pos: 3.5,-12.5
parent: 1668 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 - proto: ChemistryHotplate
entities: entities:
- uid: 671 - uid: 671
@@ -23874,36 +23956,34 @@ entities:
- type: Transform - type: Transform
pos: -12.5,5.5 pos: -12.5,5.5
parent: 1668 parent: 1668
- proto: DefaultStationBeacon - proto: DefaultStationBeaconCentComm
entities: entities:
- uid: 4656 - uid: 4656
components: components:
- type: Transform - type: Transform
pos: -0.5,3.5 pos: -0.5,3.5
parent: 1668 parent: 1668
- type: NavMapBeacon - proto: DefaultStationBeaconCentCommAfterhours
text: CentComm entities:
- uid: 9452 - uid: 9452
components: components:
- type: Transform - type: Transform
pos: 22.5,-21.5 pos: 22.5,-21.5
parent: 1668 parent: 1668
- type: NavMapBeacon - proto: DefaultStationBeaconCentCommERT
text: Afterhours entities:
- uid: 9479
components:
- type: Transform
pos: -0.5,-41.5
parent: 1668
- type: NavMapBeacon
text: Thunderdome
- uid: 9480 - uid: 9480
components: components:
- type: Transform - type: Transform
pos: -41.5,-7.5 pos: -41.5,-7.5
parent: 1668 parent: 1668
- type: NavMapBeacon - proto: DefaultStationBeaconCentCommThunderdome
text: ERT entities:
- uid: 9479
components:
- type: Transform
pos: -0.5,-41.5
parent: 1668
- proto: DefibrillatorCabinetFilled - proto: DefibrillatorCabinetFilled
entities: entities:
- uid: 511 - uid: 511
@@ -26409,36 +26489,6 @@ entities:
- type: Transform - type: Transform
pos: 13.91264,32.80469 pos: 13.91264,32.80469
parent: 1668 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 - proto: ERTEngineerPDA
entities: entities:
- uid: 6784 - uid: 6784
@@ -43141,36 +43191,6 @@ entities:
- type: Transform - type: Transform
pos: -1.4979519,1.1034296 pos: -1.4979519,1.1034296
parent: 1668 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 - proto: OreProcessor
entities: entities:
- uid: 4080 - uid: 4080
@@ -53982,28 +54002,6 @@ entities:
- Left: Reverse - Left: Reverse
- Right: Forward - Right: Forward
- Middle: Off - 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 - proto: UraniumReinforcedWindowDirectional
entities: entities:
- uid: 9601 - uid: 9601

View File

@@ -270,6 +270,7 @@
- type: StorageFill - type: StorageFill
contents: contents:
- id: OxygenTankFilled - id: OxygenTankFilled
- id: ClothingOuterHardsuitWizard
- id: ClothingMaskBreath - id: ClothingMaskBreath
- id: JetpackVoidFilled # TODO: Gone until reworked to have no space protection
#- id: ClothingOuterHardsuitWizard
#- id: JetpackVoidFilled

View File

@@ -16,6 +16,22 @@
- type: WarpPoint - type: WarpPoint
location: beacon 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 - type: entity
parent: WarpPoint parent: WarpPoint
id: WarpPointBombing id: WarpPointBombing
@@ -23,8 +39,14 @@
suffix: ninja bombing target suffix: ninja bombing target
components: components:
- type: BombingTarget - type: BombingTarget
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
location: bombing target location: bombing target
blacklist:
tags:
- GhostOnlyWarp
- type: Sprite - type: Sprite
layers: layers:
- state: pink - state: pink

View File

@@ -94,6 +94,12 @@
- type: GravityWell - type: GravityWell
baseRadialAcceleration: 6 baseRadialAcceleration: 6
maxRange: 8 maxRange: 8
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
follow: true follow: true
location: Nar'Sie location: Nar'Sie
blacklist:
tags:
- GhostOnlyWarp

View File

@@ -89,6 +89,12 @@
- type: GravityWell - type: GravityWell
baseRadialAcceleration: 6 baseRadialAcceleration: 6
maxRange: 8 maxRange: 8
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
follow: true follow: true
location: Ratvar location: Ratvar
blacklist:
tags:
- GhostOnlyWarp

View File

@@ -105,6 +105,9 @@
description: Handles AI interactions across holocards + AI cores description: Handles AI interactions across holocards + AI cores
components: components:
- type: ItemSlots - type: ItemSlots
- type: Tag
tags:
- GhostOnlyWarp
- type: StationAiHolder - type: StationAiHolder
slot: slot:
name: station-ai-mind-slot name: station-ai-mind-slot
@@ -197,6 +200,9 @@
suffix: Empty suffix: Empty
components: components:
- type: WarpPoint - type: WarpPoint
blacklist:
tags:
- GhostOnlyWarp
- type: ContainerComp - type: ContainerComp
proto: AiHeld proto: AiHeld
container: station_ai_mind_slot container: station_ai_mind_slot
@@ -327,8 +333,14 @@
categories: [ HideSpawnMenu, DoNotMap ] categories: [ HideSpawnMenu, DoNotMap ]
components: components:
- type: NoFTL - type: NoFTL
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
follow: true follow: true
blacklist:
tags:
- GhostOnlyWarp
- type: Eye - type: Eye
pvsScale: 1.5 pvsScale: 1.5
- type: Visibility - type: Visibility
@@ -349,8 +361,14 @@
components: components:
- type: Transform - type: Transform
anchored: true anchored: true
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
follow: true follow: true
blacklist:
tags:
- GhostOnlyWarp
- type: Eye - type: Eye
- type: ContentEye - type: ContentEye
- type: Examiner - type: Examiner

View File

@@ -713,3 +713,50 @@
components: components:
- type: NavMapBeacon - type: NavMapBeacon
defaultText: station-beacon-vox 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

View File

@@ -32,6 +32,9 @@
- type: WarpPoint - type: WarpPoint
follow: true follow: true
location: immovable rod location: immovable rod
blacklist:
tags:
- GhostOnlyWarp
- type: entity - type: entity
id: ImmovableRodDespawn id: ImmovableRodDespawn

View File

@@ -17,9 +17,13 @@
- type: WarpPoint - type: WarpPoint
follow: true follow: true
location: nuke disk location: nuke disk
blacklist:
tags:
- GhostOnlyWarp
- type: Tag - type: Tag
tags: tags:
- HighRiskItem - HighRiskItem
- GhostOnlyWarp
- type: StealTarget - type: StealTarget
stealGroup: NukeDisk stealGroup: NukeDisk

View File

@@ -45,5 +45,11 @@
- type: Sprite - type: Sprite
sprite: Objects/Power/powersink.rsi sprite: Objects/Power/powersink.rsi
state: powersink state: powersink
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
location: powersink location: powersink
blacklist:
tags:
- GhostOnlyWarp

View File

@@ -107,9 +107,15 @@
Nuke: !type:ContainerSlot Nuke: !type:ContainerSlot
- type: StealTarget - type: StealTarget
stealGroup: NuclearBomb stealGroup: NuclearBomb
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
follow: true follow: true
location: nuclear bomb location: nuclear bomb
blacklist:
tags:
- GhostOnlyWarp
- type: FTLSmashImmune - type: FTLSmashImmune
- type: entity - type: entity

View File

@@ -66,9 +66,15 @@
- SingularityEngine - SingularityEngine
- SingularityTeslaEngine - SingularityTeslaEngine
- Power - Power
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
follow: true follow: true
location: singularity location: singularity
blacklist:
tags:
- GhostOnlyWarp
- type: Sprite - type: Sprite
sprite: Structures/Power/Generation/Singularity/singularity_1.rsi sprite: Structures/Power/Generation/Singularity/singularity_1.rsi
shader: unshaded shader: unshaded

View File

@@ -89,9 +89,15 @@
- type: ChaoticJump - type: ChaoticJump
jumpMinInterval: 8 jumpMinInterval: 8
jumpMaxInterval: 15 jumpMaxInterval: 15
- type: Tag
tags:
- GhostOnlyWarp
- type: WarpPoint - type: WarpPoint
follow: true follow: true
location: tesla ball location: tesla ball
blacklist:
tags:
- GhostOnlyWarp
- type: Sprite - type: Sprite
drawdepth: Effects drawdepth: Effects
sprite: Structures/Power/Generation/Tesla/energy_ball.rsi sprite: Structures/Power/Generation/Tesla/energy_ball.rsi

View File

@@ -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

View File

@@ -10,7 +10,7 @@
id: WizardPDA id: WizardPDA
ears: ClothingHeadsetAltWizard ears: ClothingHeadsetAltWizard
belt: ClothingBeltWand belt: ClothingBeltWand
# pocket1: TODO: Include wizard teleport scroll pocket1: WizardTeleportScroll
pocket2: WizardsGrimoire pocket2: WizardsGrimoire
- type: startingGear - type: startingGear
@@ -28,9 +28,3 @@
jumpsuit: ClothingUniformJumpsuitColorPurple jumpsuit: ClothingUniformJumpsuitColorPurple
head: ClothingHeadHatVioletwizard head: ClothingHeadHatVioletwizard
outerClothing: ClothingOuterWizardViolet outerClothing: ClothingOuterWizardViolet
- type: startingGear
id: WizardHardsuitGear
parent: WizardVioletGear
equipment:
outerClothing: ClothingOuterHardsuitWizard

View File

@@ -581,6 +581,10 @@
- type: Tag - type: Tag
id: GeigerCounter id: GeigerCounter
# Used for warps
- type: Tag
id: GhostOnlyWarp
- type: Tag - type: Tag
id: GlassAirlock id: GlassAirlock