mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
* sprite, start work on systems * Woah! Its work! * Show gateways! Yay! * Update ring.png * Update portal.yml * bububui * Fuck UI * draw lines! * clear old links lines * UI button work now! * we can cut links via UI now! * yay! linking via UI * comfortable linking * Update hand_teleporter.yml * ambience, linked entities events * nice connect and disconnect sounds! * unpowering and memory * power fix * chip added * chip linking & auto linking * chip examined * auto linked chips&gates variants * Update meta.json * Update computers.yml * syndicate gateway console, portal coloring, realtime UI update * QoL update * Circuitboards * Update StationGatewayNavMapControl.cs * optimize Draw(), add Filled console variant * documentation * mass renaming bro * resprited * resprite agani * Update tags.yml * Update Resources/Prototypes/Entities/Structures/Machines/station_teleporter.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Objects/Devices/teleporters_chips.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Content.Server/StationTeleporter/Components/TeleporterChipComponent.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Content.Shared/StationTeleporter/StationTeleporterComponent.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * renaming renaming * sharedization * UI fix * Data simplify * remove autodeletion * PostWallDrawingAction * Update TeleporterChipComponent.cs * fix lines offset * labeler renaming, rebound restiction removed * prevent link popup and sound spamming * auto linking refactor * RD handheld teleporter integration * fix randomteleport bug * Update hand_teleporter.yml * Update SharedStationTeleporterSystem.cs * Update SharedStationTeleporterSystem.UI.cs * some clean up * first smol review pass * and that * review pass 2 * Update station_teleporter.yml * review pass 3 * review pass 4 * finally * update protos * another clean up * fix bugs * add to players * remove unnecesary update loop lol. * Update computers.yml * fieldrance review apply * Kazne resprite --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com>
161 lines
6 KiB
C#
161 lines
6 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using Content.Shared.Teleportation.Components;
|
|
|
|
namespace Content.Shared.Teleportation.Systems;
|
|
|
|
/// <summary>
|
|
/// Handles symmetrically linking two entities together, and removing links properly.
|
|
/// This does not do anything on its own (outside of deleting entities that have 0 links, if that option is true)
|
|
/// Systems can do whatever they please with the linked entities, such as <see cref="SharedPortalSystem"/>.
|
|
/// </summary>
|
|
public sealed partial class LinkedEntitySystem : EntitySystem
|
|
{
|
|
[Dependency] private SharedAppearanceSystem _appearance = default!;
|
|
|
|
/// <inheritdoc/>
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<LinkedEntityComponent, ComponentShutdown>(OnLinkShutdown);
|
|
}
|
|
|
|
private void OnLinkShutdown(EntityUid uid, LinkedEntityComponent component, ComponentShutdown args)
|
|
{
|
|
// Remove any links to this entity when deleted.
|
|
foreach (var ent in component.LinkedEntities.ToArray())
|
|
{
|
|
if (!Deleted(ent) && LifeStage(ent) < EntityLifeStage.Terminating && TryComp<LinkedEntityComponent>(ent, out var link))
|
|
{
|
|
TryUnlink(uid, ent, component, link);
|
|
}
|
|
}
|
|
}
|
|
|
|
#region Public API
|
|
|
|
/// <summary>
|
|
/// Links two entities together. Does not require the existence of <see cref="LinkedEntityComponent"/> on either
|
|
/// already. Linking is symmetrical, so order doesn't matter.
|
|
/// </summary>
|
|
/// <param name="first">The first entity to link</param>
|
|
/// <param name="second">The second entity to link</param>
|
|
/// <param name="deleteOnEmptyLinks">Whether both entities should now delete once their links are removed</param>
|
|
/// <returns>Whether linking was successful (e.g. they weren't already linked)</returns>
|
|
public bool TryLink(EntityUid first, EntityUid second, bool deleteOnEmptyLinks=false)
|
|
{
|
|
var firstLink = EnsureComp<LinkedEntityComponent>(first);
|
|
var secondLink = EnsureComp<LinkedEntityComponent>(second);
|
|
|
|
firstLink.DeleteOnEmptyLinks = deleteOnEmptyLinks;
|
|
secondLink.DeleteOnEmptyLinks = deleteOnEmptyLinks;
|
|
|
|
_appearance.SetData(first, LinkedEntityVisuals.HasAnyLinks, true);
|
|
_appearance.SetData(second, LinkedEntityVisuals.HasAnyLinks, true);
|
|
|
|
Dirty(first, firstLink);
|
|
Dirty(second, secondLink);
|
|
|
|
if (firstLink.LinkedEntities.Add(second) && secondLink.LinkedEntities.Add(first))
|
|
{
|
|
var firstEv = new LinkedEntityChangedEvent(firstLink.LinkedEntities);
|
|
RaiseLocalEvent(first, ref firstEv);
|
|
var secondEv = new LinkedEntityChangedEvent(secondLink.LinkedEntities);
|
|
RaiseLocalEvent(second, ref secondEv);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Does a one-way link from source to target.
|
|
/// </summary>
|
|
/// <param name="deleteOnEmptyLinks">Whether both entities should now delete once their links are removed</param>
|
|
public bool OneWayLink(EntityUid source, EntityUid target, bool deleteOnEmptyLinks=false)
|
|
{
|
|
var firstLink = EnsureComp<LinkedEntityComponent>(source);
|
|
firstLink.DeleteOnEmptyLinks = deleteOnEmptyLinks;
|
|
|
|
_appearance.SetData(source, LinkedEntityVisuals.HasAnyLinks, true);
|
|
|
|
Dirty(source, firstLink);
|
|
|
|
if (firstLink.LinkedEntities.Add(target))
|
|
{
|
|
var ev = new LinkedEntityChangedEvent(firstLink.LinkedEntities);
|
|
RaiseLocalEvent(source, ref ev);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unlinks two entities. Deletes either entity if <see cref="LinkedEntityComponent.DeleteOnEmptyLinks"/>
|
|
/// was true and its links are now empty. Symmetrical, so order doesn't matter.
|
|
/// </summary>
|
|
/// <param name="first">The first entity to unlink</param>
|
|
/// <param name="second">The second entity to unlink</param>
|
|
/// <param name="firstLink">Resolve comp</param>
|
|
/// <param name="secondLink">Resolve comp</param>
|
|
/// <returns>Whether unlinking was successful (e.g. they both were actually linked to one another)</returns>
|
|
public bool TryUnlink(EntityUid first, EntityUid second,
|
|
LinkedEntityComponent? firstLink = null, LinkedEntityComponent? secondLink = null)
|
|
{
|
|
if (!Resolve(first, ref firstLink))
|
|
return false;
|
|
|
|
if (!Resolve(second, ref secondLink))
|
|
return false;
|
|
|
|
var success = firstLink.LinkedEntities.Remove(second)
|
|
&& secondLink.LinkedEntities.Remove(first);
|
|
|
|
_appearance.SetData(first, LinkedEntityVisuals.HasAnyLinks, firstLink.LinkedEntities.Any());
|
|
_appearance.SetData(second, LinkedEntityVisuals.HasAnyLinks, secondLink.LinkedEntities.Any());
|
|
|
|
Dirty(first, firstLink);
|
|
Dirty(second, secondLink);
|
|
|
|
var firstEv = new LinkedEntityChangedEvent(firstLink.LinkedEntities);
|
|
RaiseLocalEvent(first, ref firstEv);
|
|
var secondEv = new LinkedEntityChangedEvent(secondLink.LinkedEntities);
|
|
RaiseLocalEvent(second, ref secondEv);
|
|
|
|
if (firstLink.LinkedEntities.Count == 0 && firstLink.DeleteOnEmptyLinks)
|
|
QueueDel(first);
|
|
|
|
if (secondLink.LinkedEntities.Count == 0 && secondLink.DeleteOnEmptyLinks)
|
|
QueueDel(second);
|
|
|
|
return success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the first entity this entity is linked to.
|
|
/// If multiple are linked only the first one is picked.
|
|
/// </summary>
|
|
public bool GetLink(EntityUid uid, [NotNullWhen(true)] out EntityUid? dest, LinkedEntityComponent? comp = null)
|
|
{
|
|
dest = null;
|
|
if (!Resolve(uid, ref comp, false))
|
|
return false;
|
|
|
|
var first = comp.LinkedEntities.FirstOrDefault();
|
|
if (first != default)
|
|
{
|
|
dest = first;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
[ByRefEvent]
|
|
public readonly record struct LinkedEntityChangedEvent(HashSet<EntityUid> NewLinks);
|