2020-10-28 19:19:47 +01:00
using System ;
using System.Collections.Generic ;
using System.Threading ;
2021-02-11 01:13:03 -08:00
using Robust.Shared.GameObjects ;
2020-10-28 19:19:47 +01:00
using Robust.Shared.IoC ;
using Robust.Shared.Log ;
using Robust.Shared.Maths ;
2021-03-08 04:09:59 +11:00
using Robust.Shared.Physics ;
2021-02-18 20:45:45 -08:00
using Timer = Robust . Shared . Timing . Timer ;
2020-10-28 19:19:47 +01:00
namespace Content.Server.GameObjects.Components.Singularity
{
public class ContainmentFieldConnection : IDisposable
{
public readonly ContainmentFieldGeneratorComponent Generator1 ;
public readonly ContainmentFieldGeneratorComponent Generator2 ;
2020-11-27 11:00:49 +01:00
private readonly List < IEntity > _fields = new ( ) ;
2020-10-28 19:19:47 +01:00
private int _sharedEnergyPool ;
2020-11-27 11:00:49 +01:00
private readonly CancellationTokenSource _powerDecreaseCancellationTokenSource = new ( ) ;
2020-10-28 19:19:47 +01:00
public int SharedEnergyPool
{
get = > _sharedEnergyPool ;
set
{
2021-05-28 10:44:13 +01:00
_sharedEnergyPool = Math . Clamp ( value , 0 , 25 ) ;
2020-10-28 19:19:47 +01:00
if ( _sharedEnergyPool = = 0 )
{
Dispose ( ) ;
}
}
}
public ContainmentFieldConnection ( ContainmentFieldGeneratorComponent generator1 , ContainmentFieldGeneratorComponent generator2 )
{
Generator1 = generator1 ;
Generator2 = generator2 ;
//generateFields
var pos1 = generator1 . Owner . Transform . Coordinates ;
var pos2 = generator2 . Owner . Transform . Coordinates ;
if ( pos1 = = pos2 )
{
Dispose ( ) ;
return ;
}
var entityManager = IoCManager . Resolve < IEntityManager > ( ) ;
var delta = ( pos2 - pos1 ) . Position ;
var dirVec = delta . Normalized ;
var stopDist = delta . Length ;
var currentOffset = dirVec ;
while ( currentOffset . Length < stopDist )
{
var currentCoords = pos1 . Offset ( currentOffset ) ;
var newEnt = entityManager . SpawnEntity ( "ContainmentField" , currentCoords ) ;
if ( ! newEnt . TryGetComponent < ContainmentFieldComponent > ( out var containmentFieldComponent ) )
{
Logger . Error ( "While creating Fields in ContainmentFieldConnection, a ContainmentField without a ContainmentFieldComponent was created. Deleting newly spawned ContainmentField..." ) ;
newEnt . Delete ( ) ;
continue ;
}
containmentFieldComponent . Parent = this ;
2021-03-14 15:02:22 -07:00
newEnt . Transform . WorldRotation = dirVec . ToWorldAngle ( ) ;
2020-10-28 19:19:47 +01:00
_fields . Add ( newEnt ) ;
currentOffset + = dirVec ;
}
Timer . SpawnRepeating ( 1000 , ( ) = > { SharedEnergyPool - - ; } , _powerDecreaseCancellationTokenSource . Token ) ;
}
public bool CanRepell ( IEntity toRepell )
{
var powerNeeded = 1 ;
2021-03-09 04:33:41 -06:00
if ( toRepell . TryGetComponent < ServerSingularityComponent > ( out var singularityComponent ) )
2020-10-28 19:19:47 +01:00
{
powerNeeded + = 2 * singularityComponent . Level ;
}
return _sharedEnergyPool > powerNeeded ;
}
/// <summary>
/// Tries to repell a Entity. This deletes the connection if the repelling fails!
/// </summary>
/// <param name="repellFrom">Entity to repell from. Should be a field, otherwise return will be false.</param>
/// <param name="toRepell">Entity to repell.</param>
public void TryRepell ( IEntity repellFrom , IEntity toRepell )
{
2021-03-08 04:09:59 +11:00
// TODO: Fix this also it's fucking repel
if ( ! _fields . Contains ( repellFrom ) | | ! toRepell . TryGetComponent < IPhysBody > ( out var collidableComponent ) ) return ;
2020-10-28 19:19:47 +01:00
2021-03-08 04:09:59 +11:00
return ;
2020-10-28 19:19:47 +01:00
var speed = 5 ;
2021-03-08 04:09:59 +11:00
//var containmentFieldRepellController = collidableComponent.EnsureController<ContainmentFieldRepellController>();
2020-10-28 19:19:47 +01:00
if ( ! CanRepell ( toRepell ) )
{
Dispose ( ) ;
return ;
}
if ( Math . Abs ( repellFrom . Transform . WorldRotation . Degrees + 90f ) < 0.1f | |
Math . Abs ( repellFrom . Transform . WorldRotation . Degrees - 90f ) < 0.1f )
{
if ( repellFrom . Transform . WorldPosition . X . CompareTo ( toRepell . Transform . WorldPosition . X ) > 0 )
{
2021-03-08 04:09:59 +11:00
//containmentFieldRepellController.Repell(Direction.West, speed);
2020-10-28 19:19:47 +01:00
}
else
{
2021-03-08 04:09:59 +11:00
//containmentFieldRepellController.Repell(Direction.East, speed);
2020-10-28 19:19:47 +01:00
}
}
else
{
if ( repellFrom . Transform . WorldPosition . Y . CompareTo ( toRepell . Transform . WorldPosition . Y ) > 0 )
{
2021-03-08 04:09:59 +11:00
//containmentFieldRepellController.Repell(Direction.South, speed);
2020-10-28 19:19:47 +01:00
}
else
{
2021-03-08 04:09:59 +11:00
//containmentFieldRepellController.Repell(Direction.North, speed);
2020-10-28 19:19:47 +01:00
}
}
return ;
}
public void Dispose ( )
{
_powerDecreaseCancellationTokenSource . Cancel ( ) ;
foreach ( var field in _fields )
{
field . Delete ( ) ;
}
_fields . Clear ( ) ;
Generator1 . RemoveConnection ( this ) ;
Generator2 . RemoveConnection ( this ) ;
}
}
}