Portal sprite & behavior tweaks (#19179)
* Portal repalette * Portal traversal verb + anchoring * map restriction * optional max distance checks if we decide to have them later * lower pointlight energy slightly hopefully makes it less garish
This commit is contained in:
@@ -22,7 +22,6 @@ public sealed class HandTeleporterSystem : EntitySystem
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<HandTeleporterComponent, UseInHandEvent>(OnUseInHand);
|
||||
|
||||
SubscribeLocalEvent<HandTeleporterComponent, TeleporterDoAfterEvent>(OnDoAfter);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Server.Ghost.Components;
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Teleportation.Systems;
|
||||
@@ -14,7 +15,7 @@ public sealed class PortalSystem : SharedPortalSystem
|
||||
protected override void LogTeleport(EntityUid portal, EntityUid subject, EntityCoordinates source,
|
||||
EntityCoordinates target)
|
||||
{
|
||||
if (HasComp<MindContainerComponent>(subject))
|
||||
if (HasComp<MindContainerComponent>(subject) && !HasComp<GhostComponent>(subject))
|
||||
_adminLogger.Add(LogType.Teleport, LogImpact.Low, $"{ToPrettyString(subject):player} teleported via {ToPrettyString(portal)} from {source} to {target}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ public sealed class HandTeleporterComponent : Component
|
||||
/// <summary>
|
||||
/// Delay for creating the portals in seconds.
|
||||
/// </summary>
|
||||
[DataField("portalCreationDelay")] public float PortalCreationDelay = 2.5f;
|
||||
[DataField("portalCreationDelay")]
|
||||
public float PortalCreationDelay = 1.0f;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -28,4 +28,23 @@ public sealed class PortalComponent : Component
|
||||
/// </summary>
|
||||
[DataField("maxRandomRadius")]
|
||||
public float MaxRandomRadius = 7.0f;
|
||||
|
||||
/// <summary>
|
||||
/// If false, this portal will fail to teleport and fizzle out if attempting to send an entity to a different map
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shouldn't be able to teleport people to centcomm or the eshuttle from the station
|
||||
/// </remarks>
|
||||
[DataField("canTeleportToOtherMaps")]
|
||||
public bool CanTeleportToOtherMaps = false;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum distance that portals can teleport to, in all cases. Mostly this matters for linked portals.
|
||||
/// Null means no restriction on distance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Obviously this should strictly be larger than <see cref="MaxRandomRadius"/> (or null)
|
||||
/// </remarks>
|
||||
[DataField("maxTeleportRadius")]
|
||||
public float? MaxTeleportRadius;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Directions;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Pinpointer;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Projectiles;
|
||||
using Content.Shared.Pulling;
|
||||
using Content.Shared.Pulling.Components;
|
||||
using Content.Shared.Teleportation.Components;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Physics.Dynamics;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Teleportation.Systems;
|
||||
|
||||
@@ -24,6 +29,7 @@ public abstract class SharedPortalSystem : EntitySystem
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedPullingSystem _pulling = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
private const string PortalFixture = "portalFixture";
|
||||
private const string ProjectileFixture = "projectile";
|
||||
@@ -35,11 +41,42 @@ public abstract class SharedPortalSystem : EntitySystem
|
||||
{
|
||||
SubscribeLocalEvent<PortalComponent, StartCollideEvent>(OnCollide);
|
||||
SubscribeLocalEvent<PortalComponent, EndCollideEvent>(OnEndCollide);
|
||||
SubscribeLocalEvent<PortalComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerbs);
|
||||
|
||||
SubscribeLocalEvent<PortalTimeoutComponent, ComponentGetState>(OnGetState);
|
||||
SubscribeLocalEvent<PortalTimeoutComponent, ComponentHandleState>(OnHandleState);
|
||||
}
|
||||
|
||||
private void OnGetVerbs(EntityUid uid, PortalComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
// Traversal altverb for ghosts to use that bypasses normal functionality
|
||||
if (!args.CanAccess || !HasComp<SharedGhostComponent>(args.User))
|
||||
return;
|
||||
|
||||
// Don't use the verb with unlinked or with multi-output portals
|
||||
// (this is only intended to be useful for ghosts to see where a linked portal leads)
|
||||
var disabled = !TryComp<LinkedEntityComponent>(uid, out var link) || link.LinkedEntities.Count != 1;
|
||||
|
||||
args.Verbs.Add(new AlternativeVerb
|
||||
{
|
||||
Priority = 11,
|
||||
Act = () =>
|
||||
{
|
||||
if (link == null || disabled)
|
||||
return;
|
||||
|
||||
var ent = link.LinkedEntities.First();
|
||||
TeleportEntity(uid, args.User, Transform(ent).Coordinates, ent, false);
|
||||
},
|
||||
Disabled = disabled,
|
||||
Text = Loc.GetString("portal-component-ghost-traverse"),
|
||||
Message = disabled
|
||||
? Loc.GetString("portal-component-no-linked-entities")
|
||||
: Loc.GetString("portal-component-can-ghost-traverse"),
|
||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/open.svg.192dpi.png"))
|
||||
});
|
||||
}
|
||||
|
||||
private void OnGetState(EntityUid uid, PortalTimeoutComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new PortalTimeoutComponentState(component.EnteredPortal);
|
||||
@@ -138,12 +175,38 @@ public abstract class SharedPortalSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void TeleportEntity(EntityUid portal, EntityUid subject, EntityCoordinates target, EntityUid? targetEntity=null,
|
||||
private void TeleportEntity(EntityUid portal, EntityUid subject, EntityCoordinates target, EntityUid? targetEntity=null, bool playSound=true,
|
||||
PortalComponent? portalComponent = null)
|
||||
{
|
||||
if (!Resolve(portal, ref portalComponent))
|
||||
return;
|
||||
|
||||
var ourCoords = Transform(portal).Coordinates;
|
||||
var onSameMap = ourCoords.GetMapId(EntityManager) == target.GetMapId(EntityManager);
|
||||
var distanceInvalid = portalComponent.MaxTeleportRadius != null
|
||||
&& ourCoords.TryDistance(EntityManager, target, out var distance)
|
||||
&& distance > portalComponent.MaxTeleportRadius;
|
||||
|
||||
if (!onSameMap && !portalComponent.CanTeleportToOtherMaps || distanceInvalid)
|
||||
{
|
||||
if (!_netMan.IsServer)
|
||||
return;
|
||||
|
||||
// Early out if this is an invalid configuration
|
||||
_popup.PopupCoordinates(Loc.GetString("portal-component-invalid-configuration-fizzle"),
|
||||
ourCoords, Filter.Pvs(ourCoords, entityMan: EntityManager), true);
|
||||
|
||||
_popup.PopupCoordinates(Loc.GetString("portal-component-invalid-configuration-fizzle"),
|
||||
target, Filter.Pvs(target, entityMan: EntityManager), true);
|
||||
|
||||
QueueDel(portal);
|
||||
|
||||
if (targetEntity != null)
|
||||
QueueDel(targetEntity.Value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var arrivalSound = CompOrNull<PortalComponent>(targetEntity)?.ArrivalSound ?? portalComponent.ArrivalSound;
|
||||
var departureSound = portalComponent.DepartureSound;
|
||||
|
||||
@@ -159,6 +222,9 @@ public abstract class SharedPortalSystem : EntitySystem
|
||||
|
||||
_transform.SetCoordinates(subject, target);
|
||||
|
||||
if (!playSound)
|
||||
return;
|
||||
|
||||
_audio.PlayPredicted(departureSound, portal, subject);
|
||||
_audio.PlayPredicted(arrivalSound, subject, subject);
|
||||
}
|
||||
|
||||
8
Resources/Locale/en-US/portal/portal.ftl
Normal file
8
Resources/Locale/en-US/portal/portal.ftl
Normal file
@@ -0,0 +1,8 @@
|
||||
### Portal verb text
|
||||
|
||||
portal-component-ghost-traverse = Traverse
|
||||
|
||||
portal-component-no-linked-entities = Can't ghost traverse a portal that doesn't have exactly 1 linked portal
|
||||
portal-component-can-ghost-traverse = Teleport to the linked portal
|
||||
|
||||
portal-component-invalid-configuration-fizzle = The portal fizzles out!
|
||||
@@ -4,6 +4,8 @@
|
||||
name: bluespace portal
|
||||
description: Transports you to a linked destination!
|
||||
components:
|
||||
- type: Transform
|
||||
anchored: True
|
||||
- type: InteractionOutline
|
||||
- type: Clickable
|
||||
- type: Physics
|
||||
@@ -34,8 +36,9 @@
|
||||
- type: PointLight
|
||||
color: OrangeRed
|
||||
radius: 3
|
||||
energy: 3
|
||||
energy: 1
|
||||
netsync: false
|
||||
|
||||
- type: entity
|
||||
id: PortalBlue
|
||||
parent: BasePortal
|
||||
@@ -46,5 +49,5 @@
|
||||
- type: PointLight
|
||||
color: SkyBlue
|
||||
radius: 3
|
||||
energy: 3
|
||||
energy: 1
|
||||
netsync: false
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"y": 32
|
||||
},
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgStation at commit https://github.com/tgstation/tgstation/blob/4a367160a204db4c5b51c1f811a3b899f0bde3ea/icons/obj/stationobjs.dmi",
|
||||
"copyright": "Taken from tgStation at commit https://github.com/tgstation/tgstation/blob/4a367160a204db4c5b51c1f811a3b899f0bde3ea/icons/obj/stationobjs.dmi and repaletted using old tg sprites by mirrorcult",
|
||||
"states": [
|
||||
{
|
||||
"name": "portal-blue",
|
||||
@@ -24,15 +24,6 @@
|
||||
0.1, 0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "portal",
|
||||
"delays": [
|
||||
[
|
||||
0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
|
||||
0.1, 0.1
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user