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:
Kara
2023-08-15 13:56:14 -07:00
committed by GitHub
parent 452f2112e8
commit 2e86f4c556
11 changed files with 106 additions and 18 deletions

View File

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