Skip to content

Commit

Permalink
use nav beacon locations for announcements
Browse files Browse the repository at this point in the history
  • Loading branch information
EmoGarbage404 committed Mar 25, 2024
1 parent 266cc85 commit 5630e16
Show file tree
Hide file tree
Showing 15 changed files with 228 additions and 98 deletions.
6 changes: 4 additions & 2 deletions Content.Server/Dragon/DragonRiftSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Numerics;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Utility;

namespace Content.Server.Dragon;

Expand Down Expand Up @@ -69,8 +70,9 @@ public override void Update(float frameTime)
comp.State = DragonRiftState.AlmostFinished;
Dirty(uid, comp);

var location = xform.LocalPosition;
_chat.DispatchGlobalAnnouncement(Loc.GetString("carp-rift-warning", ("location", location)), playSound: false, colorOverride: Color.Red);
var msg = Loc.GetString("carp-rift-warning",
("location", FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((uid, xform)))));
_chat.DispatchGlobalAnnouncement(msg, playSound: false, colorOverride: Color.Red);
_audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true);
_navMap.SetBeaconEnabled(uid, true);
}
Expand Down
10 changes: 4 additions & 6 deletions Content.Server/Explosion/EntitySystems/TriggerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Explosion.Components;
using Content.Server.Flash;
using Content.Server.Pinpointer;
using Content.Shared.Flash.Components;
using Content.Server.Radio.EntitySystems;
using Content.Shared.Chemistry.Components;
Expand Down Expand Up @@ -31,6 +32,7 @@
using Robust.Shared.Random;
using Robust.Shared.Player;
using Content.Shared.Coordinates;
using Robust.Shared.Utility;

namespace Content.Server.Explosion.EntitySystems
{
Expand Down Expand Up @@ -67,6 +69,7 @@ public sealed partial class TriggerSystem : EntitySystem
[Dependency] private readonly BodySystem _body = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
[Dependency] private readonly RadioSystem _radioSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
Expand Down Expand Up @@ -185,12 +188,7 @@ private void HandleRattleTrigger(EntityUid uid, RattleComponent component, Trigg
return;

// Gets location of the implant
var ownerXform = Transform(uid);
var pos = ownerXform.MapPosition;
var x = (int) pos.X;
var y = (int) pos.Y;
var posText = $"({x}, {y})";

var posText = FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString(uid));
var critMessage = Loc.GetString(component.CritMessage, ("user", implanted.ImplantedEntity.Value), ("position", posText));
var deathMessage = Loc.GetString(component.DeathMessage, ("user", implanted.ImplantedEntity.Value), ("position", posText));

Expand Down
4 changes: 3 additions & 1 deletion Content.Server/Nuke/NukeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Robust.Shared.Map.Components;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Utility;

namespace Content.Server.Nuke;

Expand Down Expand Up @@ -463,7 +464,8 @@ public void ArmBomb(EntityUid uid, NukeComponent? component = null)

// warn a crew
var announcement = Loc.GetString("nuke-component-announcement-armed",
("time", (int) component.RemainingTime), ("position", posText));
("time", (int) component.RemainingTime),
("location", FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((uid, nukeXform)))));
var sender = Loc.GetString("nuke-component-announcement-sender");
_chatSystem.DispatchStationAnnouncement(stationUid ?? uid, announcement, sender, false, null, Color.Red);

Expand Down
114 changes: 114 additions & 0 deletions Content.Server/Pinpointer/NavMapSystem.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Administration.Logs;
using Content.Server.Station.Systems;
using Content.Server.Warps;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Localizations;
using Content.Shared.Pinpointer;
using Content.Shared.Tag;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
Expand All @@ -22,10 +26,15 @@ public sealed class NavMapSystem : SharedNavMapSystem
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly TagSystem _tags = default!;
[Dependency] private readonly MapSystem _map = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly TransformSystem _transform = default!;

private EntityQuery<PhysicsComponent> _physicsQuery;
private EntityQuery<TagComponent> _tagQuery;

public const float CloseDistance = 15f;
public const float FarDistance = 30f;

public override void Initialize()
{
base.Initialize();
Expand All @@ -40,6 +49,7 @@ public override void Initialize()
SubscribeLocalEvent<NavMapComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<GridSplitEvent>(OnNavMapSplit);

SubscribeLocalEvent<NavMapBeaconComponent, MapInitEvent>(OnNavMapBeaconMapInit);
SubscribeLocalEvent<NavMapBeaconComponent, ComponentStartup>(OnNavMapBeaconStartup);
SubscribeLocalEvent<NavMapBeaconComponent, AnchorStateChangedEvent>(OnNavMapBeaconAnchor);

Expand All @@ -57,8 +67,22 @@ private void OnStationInit(StationGridAddedEvent ev)
RefreshGrid(ev.GridId, comp, Comp<MapGridComponent>(ev.GridId));
}

private void OnNavMapBeaconMapInit(EntityUid uid, NavMapBeaconComponent component, MapInitEvent args)
{
if (component.DefaultText == null || component.Text != null)
return;

component.Text = Loc.GetString(component.DefaultText);
Dirty(uid, component);
RefreshNavGrid(uid);
}

private void OnNavMapBeaconStartup(EntityUid uid, NavMapBeaconComponent component, ComponentStartup args)
{
// don't run this a second time if the map is already init as OnNavMapBeaconMapInit will handle it
if (LifeStage(uid) >= EntityLifeStage.MapInitialized)
return;

RefreshNavGrid(uid);
}

Expand Down Expand Up @@ -384,4 +408,94 @@ public void ToggleBeacon(EntityUid uid, NavMapBeaconComponent? comp = null)

SetBeaconEnabled(uid, !comp.Enabled, comp);
}

/// <summary>
/// For a given position, tries to find the nearest configurable beacon that is marked as visible.
/// This is used for things like announcements where you want to find the closest "landmark" to something.
/// </summary>
[PublicAPI]
public bool TryGetNearestBeacon(Entity<TransformComponent?> ent, [NotNullWhen(true)] out Entity<NavMapBeaconComponent>? beacon)
{
beacon = null;
if (!Resolve(ent, ref ent.Comp))
return false;

return TryGetNearestBeacon(_transform.GetMapCoordinates(ent, ent.Comp), out beacon);
}

/// <summary>
/// For a given position, tries to find the nearest configurable beacon that is marked as visible.
/// This is used for things like announcements where you want to find the closest "landmark" to something.
/// </summary>
public bool TryGetNearestBeacon(MapCoordinates coordinates, [NotNullWhen(true)] out Entity<NavMapBeaconComponent>? beacon)
{
beacon = null;
var minDistance = float.PositiveInfinity;

var query = EntityQueryEnumerator<ConfigurableNavMapBeaconComponent, NavMapBeaconComponent, TransformComponent>();
while (query.MoveNext(out var uid, out _, out var navBeacon, out var xform))
{
if (!navBeacon.Enabled)
continue;

if (navBeacon.Text == null)
continue;

if (coordinates.MapId != xform.MapID)
continue;

var coords = _transform.GetWorldPosition(xform);
var distanceSquared = (coordinates.Position - coords).LengthSquared();
if (!float.IsInfinity(minDistance) && distanceSquared >= minDistance)
continue;

minDistance = distanceSquared;
beacon = (uid, navBeacon);
}

return beacon != null;
}

[PublicAPI]
public string GetNearestBeaconString(Entity<TransformComponent?> ent)
{
if (!Resolve(ent, ref ent.Comp))
return Loc.GetString("nav-beacon-pos-no-beacons");

return GetNearestBeaconString(_transform.GetMapCoordinates(ent, ent.Comp));
}

public string GetNearestBeaconString(MapCoordinates coordinates)
{
if (!TryGetNearestBeacon(coordinates, out var beacon))
return Loc.GetString("nav-beacon-pos-no-beacons");

var pos = _transform.GetMapCoordinates(beacon.Value);

var rotOffset = Angle.Zero;
if (_mapManager.TryFindGridAt(pos, out var grid, out _))
rotOffset = Transform(grid).LocalRotation;

var dir = (pos.Position - coordinates.Position).GetDir();
var adjustedDir = (dir.ToAngle() - rotOffset + (Math.PI)).GetDir();

var length = (pos.Position - coordinates.Position).Length();
if (length < CloseDistance)
{
return Loc.GetString("nav-beacon-pos-format",
("color", beacon.Value.Comp.Color),
("marker", beacon.Value.Comp.Text!));
}

var modifier = length > FarDistance
? Loc.GetString("nav-beacon-pos-format-direction-mod-far")
: string.Empty;

// we can null suppress the text being null because TRyGetNearestVisibleStationBeacon always gives us a beacon with not-null text.
return Loc.GetString("nav-beacon-pos-format-direction",
("modifier", modifier),
("direction", ContentLocalizationManager.FormatDirection(adjustedDir).ToLowerInvariant()),
("color", beacon.Value.Comp.Color),
("marker", beacon.Value.Comp.Text!));
}
}
10 changes: 5 additions & 5 deletions Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.GameTicking.Events;
using Content.Server.Pinpointer;
using Content.Server.Popups;
using Content.Server.RoundEnd;
using Content.Server.Screens.Components;
Expand All @@ -33,6 +34,7 @@
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Server.Shuttles.Systems;

Expand All @@ -55,6 +57,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
[Dependency] private readonly DockingSystem _dock = default!;
[Dependency] private readonly EntityManager _entityManager = default!;
[Dependency] private readonly IdCardSystem _idSystem = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
[Dependency] private readonly MapLoaderSystem _map = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
Expand Down Expand Up @@ -307,11 +310,8 @@ public void CallEmergencyShuttle(EntityUid stationUid, StationEmergencyShuttleCo
}
else
{
if (TryComp<TransformComponent>(targetGrid.Value, out var targetXform))
{
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform, xformQuery);
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-nearby", ("direction", angle.GetDir())), playDefaultSound: false);
}
var location = FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((stationShuttle.EmergencyShuttle.Value, xform)));
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-nearby", ("direction", location)), playDefaultSound: false);

_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle {ToPrettyString(stationUid)} unable to find a valid docking port for {ToPrettyString(stationUid)}");
// TODO: Need filter extensions or something don't blame me.
Expand Down
8 changes: 8 additions & 0 deletions Content.Shared/Localizations/ContentLocalizationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ public static string FormatList(List<string> list)
};
}

/// <summary>
/// Formats a direction struct as a human-readable string.
/// </summary>
public static string FormatDirection(Direction dir)
{
return Loc.GetString($"zzzz-fmt-direction-{dir.ToString()}");
}

private static ILocValue FormatLoc(LocArgs args)
{
var id = ((LocValueString) args.Args[0]).Value;
Expand Down
7 changes: 7 additions & 0 deletions Content.Shared/Pinpointer/NavMapBeaconComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ public sealed partial class NavMapBeaconComponent : Component
[AutoNetworkedField]
public string? Text;

/// <summary>
/// A localization string that populates <see cref="Text"/> if it is null at mapinit.
/// Used so that mappers can still override Text while mapping.
/// </summary>
[DataField]
public LocId? DefaultText;

[ViewVariables(VVAccess.ReadWrite), DataField]
[AutoNetworkedField]
public Color Color = Color.Orange;
Expand Down
14 changes: 0 additions & 14 deletions Content.Shared/Pinpointer/SharedNavMapSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ public abstract class SharedNavMapSystem : EntitySystem
{
public const byte ChunkSize = 4;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<NavMapBeaconComponent, MapInitEvent>(OnNavMapBeaconMapInit);
}

/// <summary>
/// Converts the chunk's tile into a bitflag for the slot.
/// </summary>
Expand All @@ -38,13 +31,6 @@ public static Vector2i GetTile(int flag)
return new Vector2i(x, y);
}

private void OnNavMapBeaconMapInit(EntityUid uid, NavMapBeaconComponent component, MapInitEvent args)
{
component.Text ??= string.Empty;
component.Text = Loc.GetString(component.Text);
Dirty(uid, component);
}

[Serializable, NetSerializable]
protected sealed class NavMapComponentState : ComponentState
{
Expand Down
8 changes: 8 additions & 0 deletions Resources/Locale/en-US/_directions.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
zzzz-fmt-direction-North = North
zzzz-fmt-direction-South = South
zzzz-fmt-direction-East = East
zzzz-fmt-direction-West = West
zzzz-fmt-direction-NorthEast = NorthEast
zzzz-fmt-direction-SouthEast = SouthEast
zzzz-fmt-direction-NorthWest = NorthWest
zzzz-fmt-direction-SouthWest = SouthWest
2 changes: 1 addition & 1 deletion Resources/Locale/en-US/dragon/rifts.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
carp-rift-warning = A rift is causing an unnaturally large energy flux at {$location}. Stop it at all costs!
carp-rift-warning = A rift is causing an unnaturally large energy flux {$location}. Stop it at all costs!
carp-rift-duplicate = Cannot have 2 charging rifts at the same time!
carp-rift-examine = It is [color=yellow]{$percentage}%[/color] charged!
carp-rift-max = You have reached your maximum amount of rifts
Expand Down
4 changes: 2 additions & 2 deletions Resources/Locale/en-US/implant/implant.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ scramble-implant-activated-popup = Your appearance shifts and changes!
## Implant Messages

deathrattle-implant-dead-message = {$user} has died at {$position}.
deathrattle-implant-critical-message = {$user} life signs critical, immediate assistance required at {$position}.
deathrattle-implant-dead-message = {$user} has died {$position}.
deathrattle-implant-critical-message = {$user} life signs critical, immediate assistance required {$position}.
5 changes: 5 additions & 0 deletions Resources/Locale/en-US/navmap-beacons/station_map.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ nav-beacon-examine-text = It is [color={$enabled ->
[true] forestgreen]on
*[false] crimson]off
}[/color] and the display reads [color={$color}]"{$label}"[/color]
nav-beacon-pos-no-beacons = in the middle of nowhere
nav-beacon-pos-format = [color={$color}]near {$marker}[/color]
nav-beacon-pos-format-direction = [color={$color}]{$modifier}{$direction} of {$marker}[/color]
nav-beacon-pos-format-direction-mod-far = far {""}
2 changes: 1 addition & 1 deletion Resources/Locale/en-US/nuke/nuke-component.ftl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
nuke-component-cant-anchor-floor = The anchoring bolts fail to lock into the floor!
nuke-component-announcement-sender = Nuclear Fission Explosive
nuke-component-announcement-armed = Attention! The station's self-destruct mechanism has been engaged at global coordinates {$position}. {$time} seconds until detonation. If this was made in error, the mechanism may still be disarmed.
nuke-component-announcement-armed = Attention! The station's self-destruct mechanism has been engaged {$location}. {$time} seconds until detonation. If this was made in error, the mechanism may still be disarmed.
nuke-component-announcement-unarmed = The station's self-destruct was deactivated! Have a nice day!
nuke-component-announcement-send-codes = Attention! Self-destruction codes have been sent to designated fax machines.
nuke-component-doafter-warning = You start fiddling with wires and knobs in order to disarm the nuke.. This may take a while.
Expand Down
2 changes: 1 addition & 1 deletion Resources/Locale/en-US/shuttles/emergency.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ emergency-shuttle-left = The Emergency Shuttle has left the station. Estimate {$
emergency-shuttle-launch-time = The emergency shuttle will launch in {$consoleAccumulator} seconds.
emergency-shuttle-docked = The Emergency Shuttle has docked with the station on the {$direction} side. It will leave in {$time} seconds.
emergency-shuttle-good-luck = The Emergency Shuttle is unable to find a station. Good luck.
emergency-shuttle-nearby = The Emergency Shuttle is unable to find a valid docking port. It has warped in {$direction} of the station.
emergency-shuttle-nearby = The Emergency Shuttle is unable to find a valid docking port. It has warped {$direction}.
# Emergency shuttle console popup / announcement
emergency-shuttle-console-no-early-launches = Early launch is disabled
Expand Down
Loading

0 comments on commit 5630e16

Please sign in to comment.