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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user