Add a test that puts all components on an entity and checks for no exceptions (#1815)
* Add test that puts all components on an entity and checks for no exceptions Also fix all the exceptions that happened because of this * Add comments to the test * Fix nullable errors * Fix more nullable errors * More nullable error fixes * Unignore basic actor component * Fix more nullable errors * NULLABLE ERROR * Add string interpolation * Merge if checks * Remove redundant pragma warning disable 649 * Address reviews * Remove null wrappers around TryGetComponent * Merge conflict fixes * APC battery component error fix * Fix power test * Fix atmos mapgrid usages
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Content.Server.GameObjects.Components.Access;
|
||||
@@ -44,10 +45,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
protected const float AutoCloseDelay = 5;
|
||||
protected float CloseSpeed = AutoCloseDelay;
|
||||
|
||||
private AirtightComponent airtightComponent;
|
||||
private ICollidableComponent _collidableComponent;
|
||||
private AppearanceComponent _appearance;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
private static readonly TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.3f);
|
||||
private static readonly TimeSpan CloseTimeTwo = TimeSpan.FromSeconds(0.9f);
|
||||
@@ -68,21 +66,9 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
serializer.DataField(ref _occludes, "occludes", true);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
airtightComponent = Owner.GetComponent<AirtightComponent>();
|
||||
_collidableComponent = Owner.GetComponent<ICollidableComponent>();
|
||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
_cancellationTokenSource?.Cancel();
|
||||
_collidableComponent = null;
|
||||
_appearance = null;
|
||||
|
||||
base.OnRemove();
|
||||
}
|
||||
@@ -104,7 +90,6 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
ActivateImpl(eventArgs);
|
||||
}
|
||||
|
||||
|
||||
void ICollideBehavior.CollideWith(IEntity entity)
|
||||
{
|
||||
if (State != DoorState.Closed)
|
||||
@@ -135,8 +120,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
|
||||
private void SetAppearance(DoorVisualState state)
|
||||
{
|
||||
if (_appearance != null || Owner.TryGetComponent(out _appearance))
|
||||
_appearance.SetData(DoorVisuals.VisualState, state);
|
||||
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||
{
|
||||
appearance.SetData(DoorVisuals.VisualState, state);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanOpen()
|
||||
@@ -147,7 +134,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
public bool CanOpen(IEntity user)
|
||||
{
|
||||
if (!CanOpen()) return false;
|
||||
if (!Owner.TryGetComponent(out AccessReader accessReader))
|
||||
if (!Owner.TryGetComponent(out AccessReader? accessReader))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -165,7 +152,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
|
||||
Open();
|
||||
|
||||
if (user.TryGetComponent(out HandsComponent hands) && hands.Count == 0)
|
||||
if (user.TryGetComponent(out HandsComponent? hands) && hands.Count == 0)
|
||||
{
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Effects/bang.ogg", Owner,
|
||||
AudioParams.Default.WithVolume(-2));
|
||||
@@ -181,15 +168,22 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
|
||||
State = DoorState.Opening;
|
||||
SetAppearance(DoorVisualState.Opening);
|
||||
if (_occludes && Owner.TryGetComponent(out OccluderComponent occluder))
|
||||
if (_occludes && Owner.TryGetComponent(out OccluderComponent? occluder))
|
||||
{
|
||||
occluder.Enabled = false;
|
||||
}
|
||||
|
||||
Timer.Spawn(OpenTimeOne, async () =>
|
||||
{
|
||||
airtightComponent.AirBlocked = false;
|
||||
_collidableComponent.Hard = false;
|
||||
if (Owner.TryGetComponent(out AirtightComponent? airtight))
|
||||
{
|
||||
airtight.AirBlocked = false;
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out ICollidableComponent? collidable))
|
||||
{
|
||||
collidable.Hard = false;
|
||||
}
|
||||
|
||||
await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token);
|
||||
|
||||
@@ -208,7 +202,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
public bool CanClose(IEntity user)
|
||||
{
|
||||
if (!CanClose()) return false;
|
||||
if (!Owner.TryGetComponent(out AccessReader accessReader))
|
||||
if (!Owner.TryGetComponent(out AccessReader? accessReader))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -229,18 +223,22 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
|
||||
private void CheckCrush()
|
||||
{
|
||||
if (!Owner.TryGetComponent(out ICollidableComponent? body))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if collides with something
|
||||
var collidesWith = _collidableComponent.GetCollidingEntities(Vector2.Zero, false);
|
||||
var collidesWith = body.GetCollidingEntities(Vector2.Zero, false);
|
||||
if (collidesWith.Count() != 0)
|
||||
{
|
||||
// Crush
|
||||
bool hitSomeone = false;
|
||||
foreach (var e in collidesWith)
|
||||
{
|
||||
if (!e.TryGetComponent(out StunnableComponent stun)
|
||||
|| !e.TryGetComponent(out IDamageableComponent damage)
|
||||
|| !e.TryGetComponent(out ICollidableComponent otherBody)
|
||||
|| !Owner.TryGetComponent(out ICollidableComponent body))
|
||||
if (!e.TryGetComponent(out StunnableComponent? stun)
|
||||
|| !e.TryGetComponent(out IDamageableComponent? damage)
|
||||
|| !e.TryGetComponent(out ICollidableComponent? otherBody))
|
||||
continue;
|
||||
|
||||
var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB);
|
||||
@@ -264,7 +262,8 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
public bool Close()
|
||||
{
|
||||
bool shouldCheckCrush = false;
|
||||
if (_collidableComponent.IsColliding(Vector2.Zero, false))
|
||||
|
||||
if (Owner.TryGetComponent(out ICollidableComponent? collidable) && collidable.IsColliding(Vector2.Zero, false))
|
||||
{
|
||||
if (Safety)
|
||||
return false;
|
||||
@@ -276,7 +275,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
State = DoorState.Closing;
|
||||
OpenTimeCounter = 0;
|
||||
SetAppearance(DoorVisualState.Closing);
|
||||
if (_occludes && Owner.TryGetComponent(out OccluderComponent occluder))
|
||||
if (_occludes && Owner.TryGetComponent(out OccluderComponent? occluder))
|
||||
{
|
||||
occluder.Enabled = true;
|
||||
}
|
||||
@@ -288,8 +287,15 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
CheckCrush();
|
||||
}
|
||||
|
||||
airtightComponent.AirBlocked = true;
|
||||
_collidableComponent.Hard = true;
|
||||
if (Owner.TryGetComponent(out AirtightComponent? airtight))
|
||||
{
|
||||
airtight.AirBlocked = true;
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out ICollidableComponent? body))
|
||||
{
|
||||
body.Hard = true;
|
||||
}
|
||||
|
||||
await Timer.Delay(CloseTimeTwo, _cancellationTokenSource.Token);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user