Files

160 lines
5.4 KiB
C#
Raw Permalink Normal View History

2024-01-27 15:19:52 +03:00
using System.Threading;
2024-03-27 19:30:19 +07:00
using Content.Shared._White.Cult.Components;
2024-01-27 15:19:52 +03:00
using Content.Shared.Coordinates.Helpers;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction.Events;
using Content.Shared.Maps;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared._White.Cult.Items;
2024-03-27 19:30:19 +07:00
using Content.Shared.Movement.Pulling.Systems;
2024-01-27 15:19:52 +03:00
using Robust.Server.GameObjects;
2024-01-27 16:02:34 +03:00
using Robust.Shared.Audio.Systems;
2024-01-27 15:19:52 +03:00
using Robust.Shared.Map;
2024-03-27 19:30:19 +07:00
using Robust.Shared.Random;
2024-01-27 15:19:52 +03:00
using Robust.Shared.Timing;
using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server._White.Cult.Items.Systems;
2024-01-27 15:19:52 +03:00
public sealed class VoidTeleportSystem : EntitySystem
{
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly TurfSystem _turf = default!;
[Dependency] private readonly SharedTransformSystem _xform = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
2024-03-27 19:30:19 +07:00
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly PointLightSystem _pointLight = default!;
[Dependency] private readonly PullingSystem _pulling = default!;
[Dependency] private readonly IRobustRandom _random = default!;
2024-01-27 15:19:52 +03:00
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<VoidTeleportComponent, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<VoidTeleportComponent, ComponentInit>(OnInit);
}
private void OnInit(EntityUid uid, VoidTeleportComponent component, ComponentInit args)
{
UpdateAppearance(uid, component);
}
private void OnUseInHand(EntityUid uid, VoidTeleportComponent component, UseInHandEvent args)
{
if (!HasComp<CultistComponent>(args.User))
{
_hands.TryDrop(args.User);
_popup.PopupEntity(Loc.GetString("void-teleport-not-cultist"), args.User, args.User);
return;
}
if (!component.Active || component.UsesLeft <= 0)
{
_popup.PopupEntity(Loc.GetString("void-teleport-drained"), args.User, args.User);
return;
}
if (component.NextUse > _timing.CurTime)
{
_popup.PopupEntity(Loc.GetString("void-teleport-cooldown"), args.User, args.User);
return;
}
if (!TryComp<TransformComponent>(args.User, out var transform))
return;
var oldCoords = transform.Coordinates;
EntityCoordinates coords = default;
2024-02-27 15:12:53 +09:00
var foundTeleportPos = false;
2024-01-27 15:19:52 +03:00
var attempts = 10;
//Repeat until proper place for tp is found
2024-02-27 15:12:53 +09:00
while (attempts > 0)
2024-01-27 15:19:52 +03:00
{
attempts--;
//Get coords to where tp
2024-03-27 19:30:19 +07:00
var random = _random.Next(component.MinRange, component.MaxRange);
2024-01-27 15:19:52 +03:00
var offset = transform.LocalRotation.ToWorldVec().Normalized();
var direction = transform.LocalRotation.GetDir().ToVec();
var newOffset = offset + direction * random;
coords = transform.Coordinates.Offset(newOffset).SnapToGrid(EntityManager);
var tile = coords.GetTileRef();
//Check for walls
if (tile != null && _turf.IsTileBlocked(tile.Value, CollisionGroup.AllMask))
continue;
2024-02-27 15:12:53 +09:00
foundTeleportPos = true;
2024-01-27 15:19:52 +03:00
break;
}
2024-02-27 15:12:53 +09:00
if (!foundTeleportPos)
return;
2024-01-27 15:19:52 +03:00
CreatePulse(uid, component);
_xform.SetCoordinates(args.User, coords);
2024-03-27 19:30:19 +07:00
_transform.AttachToGridOrMap(args.User, transform);
2024-01-27 15:19:52 +03:00
2024-03-27 19:30:19 +07:00
if (_pulling.TryGetPulledEntity(args.User, out var pulled))
2024-01-27 15:19:52 +03:00
{
_xform.SetCoordinates(pulled.Value, coords);
2024-03-27 19:30:19 +07:00
_transform.AttachToGridOrMap(pulled.Value);
2024-01-27 15:19:52 +03:00
}
//Play tp sound
_audio.PlayPvs(component.TeleportInSound, coords);
2024-03-27 19:30:19 +07:00
_audio.PlayPvs(component.TeleportOutSound, oldCoords);
2024-01-27 15:19:52 +03:00
//Create tp effect
_entMan.SpawnEntity(component.TeleportInEffect, coords);
_entMan.SpawnEntity(component.TeleportOutEffect, oldCoords);
component.UsesLeft--;
component.NextUse = _timing.CurTime + component.Cooldown;
}
private void UpdateAppearance(EntityUid uid, VoidTeleportComponent comp)
{
AppearanceComponent? appearance = null;
if (!Resolve(uid, ref appearance, false))
return;
_appearance.SetData(uid, VeilVisuals.Activated, comp.Active, appearance);
}
private void CreatePulse(EntityUid uid, VoidTeleportComponent component)
{
2024-03-27 19:30:19 +07:00
if (_pointLight.TryGetLight(uid, out var light))
{
_pointLight.SetEnergy(uid, 5f, light);
}
2024-01-27 15:19:52 +03:00
Timer.Spawn(component.TimerDelay, () => TurnOffPulse(uid, component), component.Token.Token);
}
2024-03-27 19:30:19 +07:00
private void TurnOffPulse(EntityUid uid, VoidTeleportComponent comp)
2024-01-27 15:19:52 +03:00
{
2024-03-27 19:30:19 +07:00
if (!_pointLight.TryGetLight(uid, out var light))
2024-01-27 15:19:52 +03:00
return;
2024-03-27 19:30:19 +07:00
_pointLight.SetEnergy(uid, 1f, light);
2024-01-27 15:19:52 +03:00
comp.Token = new CancellationTokenSource();
if (comp.UsesLeft <= 0)
{
comp.Active = false;
2024-03-27 19:30:19 +07:00
_pointLight.SetEnabled(uid, false);
2024-01-27 15:19:52 +03:00
2024-03-27 19:30:19 +07:00
UpdateAppearance(uid, comp);
2024-01-27 15:19:52 +03:00
}
}
2024-03-27 19:30:19 +07:00
}