2023-02-06 00:03:53 -05:00
using System.Linq ;
2023-07-08 14:08:32 +10:00
using System.Numerics ;
2023-06-13 21:32:03 -04:00
using Content.Server.Anomaly.Components ;
2024-01-11 13:56:06 -08:00
using Content.Shared.Administration.Logs ;
2023-02-06 00:03:53 -05:00
using Content.Shared.Anomaly.Components ;
2024-01-11 13:56:06 -08:00
using Content.Shared.Database ;
2023-02-06 00:03:53 -05:00
using Content.Shared.Mobs.Components ;
using Content.Shared.Teleportation.Components ;
2023-11-27 22:12:34 +11:00
using Robust.Shared.Audio ;
using Robust.Shared.Audio.Systems ;
2023-02-06 00:03:53 -05:00
using Robust.Shared.Random ;
2023-06-13 21:32:03 -04:00
namespace Content.Server.Anomaly.Effects ;
2023-02-06 00:03:53 -05:00
public sealed class BluespaceAnomalySystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default ! ;
2024-01-11 13:56:06 -08:00
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default ! ;
2023-02-06 00:03:53 -05:00
[Dependency] private readonly SharedAudioSystem _audio = default ! ;
[Dependency] private readonly EntityLookupSystem _lookup = default ! ;
[Dependency] private readonly SharedTransformSystem _xform = default ! ;
/// <inheritdoc/>
public override void Initialize ( )
{
SubscribeLocalEvent < BluespaceAnomalyComponent , AnomalyPulseEvent > ( OnPulse ) ;
SubscribeLocalEvent < BluespaceAnomalyComponent , AnomalySupercriticalEvent > ( OnSupercritical ) ;
SubscribeLocalEvent < BluespaceAnomalyComponent , AnomalySeverityChangedEvent > ( OnSeverityChanged ) ;
}
private void OnPulse ( EntityUid uid , BluespaceAnomalyComponent component , ref AnomalyPulseEvent args )
{
2023-06-13 21:32:03 -04:00
var xformQuery = GetEntityQuery < TransformComponent > ( ) ;
var xform = xformQuery . GetComponent ( uid ) ;
2023-02-06 00:03:53 -05:00
var range = component . MaxShuffleRadius * args . Severity ;
2023-10-19 12:34:31 -07:00
var mobs = new HashSet < Entity < MobStateComponent > > ( ) ;
_lookup . GetEntitiesInRange ( xform . Coordinates , range , mobs ) ;
var allEnts = new List < EntityUid > ( mobs . Select ( m = > m . Owner ) ) { uid } ;
2023-02-06 16:11:20 -05:00
var coords = new List < Vector2 > ( ) ;
2023-02-06 00:03:53 -05:00
foreach ( var ent in allEnts )
{
if ( xformQuery . TryGetComponent ( ent , out var xf ) )
2024-02-28 00:51:20 +11:00
coords . Add ( xf . MapPosition . Position ) ;
2023-02-06 00:03:53 -05:00
}
_random . Shuffle ( coords ) ;
for ( var i = 0 ; i < allEnts . Count ; i + + )
{
2024-01-11 13:56:06 -08:00
_adminLogger . Add ( LogType . Teleport , $"{ToPrettyString(allEnts[i])} has been shuffled to {coords[i]} by the {ToPrettyString(uid)} at {xform.Coordinates}" ) ;
2023-02-06 16:11:20 -05:00
_xform . SetWorldPosition ( allEnts [ i ] , coords [ i ] , xformQuery ) ;
2023-02-06 00:03:53 -05:00
}
}
private void OnSupercritical ( EntityUid uid , BluespaceAnomalyComponent component , ref AnomalySupercriticalEvent args )
{
var xform = Transform ( uid ) ;
var mapPos = _xform . GetWorldPosition ( xform ) ;
var radius = component . SupercriticalTeleportRadius ;
2023-07-08 14:08:32 +10:00
var gridBounds = new Box2 ( mapPos - new Vector2 ( radius , radius ) , mapPos + new Vector2 ( radius , radius ) ) ;
2023-10-19 12:34:31 -07:00
var mobs = new HashSet < Entity < MobStateComponent > > ( ) ;
_lookup . GetEntitiesInRange ( xform . Coordinates , component . MaxShuffleRadius , mobs ) ;
foreach ( var comp in mobs )
2023-02-06 00:03:53 -05:00
{
var ent = comp . Owner ;
var randomX = _random . NextFloat ( gridBounds . Left , gridBounds . Right ) ;
var randomY = _random . NextFloat ( gridBounds . Bottom , gridBounds . Top ) ;
var pos = new Vector2 ( randomX , randomY ) ;
2024-01-11 13:56:06 -08:00
_adminLogger . Add ( LogType . Teleport , $"{ToPrettyString(ent)} has been teleported to {pos} by the supercritical {ToPrettyString(uid)} at {mapPos}" ) ;
2023-02-06 00:03:53 -05:00
_xform . SetWorldPosition ( ent , pos ) ;
_audio . PlayPvs ( component . TeleportSound , ent ) ;
}
}
private void OnSeverityChanged ( EntityUid uid , BluespaceAnomalyComponent component , ref AnomalySeverityChangedEvent args )
{
if ( ! TryComp < PortalComponent > ( uid , out var portal ) )
return ;
portal . MaxRandomRadius = ( component . MaxPortalRadius - component . MinPortalRadius ) * args . Severity + component . MinPortalRadius ;
}
}