Add test for adding each component individually to an entity (#1870)

* Add test for adding each component individually to entities

* Put one-to-one test before all-at-once test
This commit is contained in:
DrSmugleaf
2020-08-24 13:39:00 +02:00
committed by GitHub
parent 9e6459ac79
commit a4f527351e
13 changed files with 297 additions and 114 deletions

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -61,22 +60,15 @@ namespace Content.IntegrationTests.Tests
//Iterate list of prototypes to spawn
foreach (var prototype in prototypes)
{
try
Assert.DoesNotThrow(() =>
{
Logger.LogS(LogLevel.Debug, "EntityTest", $"Testing: {prototype.ID}");
testEntity = entityMan.SpawnEntity(prototype.ID, testLocation);
server.RunTicks(2);
Assert.That(testEntity.Initialized);
entityMan.DeleteEntity(testEntity.Uid);
}
//Fail any exceptions thrown on spawn
catch (Exception e)
{
Logger.LogS(LogLevel.Error, "EntityTest", $"Entity '{prototype.ID}' threw: {e.Message}");
Assert.Fail();
throw;
}
}, "Entity '{0}' threw an exception.",
prototype.ID);
}
});
@@ -106,6 +98,92 @@ namespace Content.IntegrationTests.Tests
await client.WaitIdleAsync();
}
[Test]
public async Task AllComponentsOneToOneDeleteTest()
{
var skipComponents = new[]
{
"DebugExceptionOnAdd", // Debug components that explicitly throw exceptions
"DebugExceptionExposeData",
"DebugExceptionInitialize",
"DebugExceptionStartup",
"Map", // We aren't testing a map entity in this test
"MapGrid"
};
var testEntity = @"
- type: entity
id: AllComponentsOneToOneDeleteTestEntity";
var server = StartServerDummyTicker();
await server.WaitIdleAsync();
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var mapLoader = server.ResolveDependency<IMapLoader>();
var pauseManager = server.ResolveDependency<IPauseManager>();
var componentFactory = server.ResolveDependency<IComponentFactory>();
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
IMapGrid grid = default;
server.Post(() =>
{
// Load test entity
using var reader = new StringReader(testEntity);
prototypeManager.LoadFromStream(reader);
// Load test map
var mapId = mapManager.CreateMap();
pauseManager.AddUninitializedMap(mapId);
grid = mapLoader.LoadBlueprint(mapId, "Maps/stationstation.yml");
pauseManager.DoMapInitialize(mapId);
});
server.Assert(() =>
{
var testLocation = new GridCoordinates(new Vector2(0, 0), grid);
foreach (var type in componentFactory.AllRegisteredTypes)
{
var component = (Component) componentFactory.GetComponent(type);
// If this component is ignored
if (skipComponents.Contains(component.Name))
{
continue;
}
var entity = entityManager.SpawnEntity("AllComponentsOneToOneDeleteTestEntity", testLocation);
Assert.That(entity.Initialized);
// The component may already exist if it is a mandatory component
// such as MetaData or Transform
if (entity.HasComponent(type))
{
continue;
}
component.Owner = entity;
Logger.LogS(LogLevel.Debug, "EntityTest", $"Adding component: {component.Name}");
Assert.DoesNotThrow(() =>
{
entityManager.ComponentManager.AddComponent(entity, component);
}, "Component '{0}' threw an exception.",
component.Name);
server.RunTicks(10);
entityManager.DeleteEntity(entity.Uid);
}
});
await server.WaitIdleAsync();
}
[Test]
public async Task AllComponentsOneEntityDeleteTest()
{
@@ -183,8 +261,6 @@ namespace Content.IntegrationTests.Tests
Assert.That(distinctComponents, Is.Not.Empty);
server.Assert(() =>
{
Assert.DoesNotThrow(() =>
{
foreach (var distinct in distinctComponents)
{
@@ -213,7 +289,11 @@ namespace Content.IntegrationTests.Tests
Logger.LogS(LogLevel.Debug, "EntityTest", $"Adding component: {component.Name}");
Assert.DoesNotThrow(() =>
{
entityManager.ComponentManager.AddComponent(entity, component);
}, "Component '{0}' threw an exception.",
component.Name);
}
server.RunTicks(48); // Run one full second on the server
@@ -221,7 +301,6 @@ namespace Content.IntegrationTests.Tests
entityManager.DeleteEntity(entity.Uid);
}
});
});
await server.WaitIdleAsync();
}

View File

@@ -4,6 +4,7 @@ using Content.Shared.Chemistry;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
@@ -40,7 +41,14 @@ namespace Content.Server.GameObjects.Components.Chemistry
protected override void Startup()
{
base.Startup();
Owner.GetComponent<SolutionComponent>().Capabilities |= SolutionCaps.FitsInDispenser;
if (!Owner.EnsureComponent(out SolutionComponent solution))
{
Logger.Warning(
$"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(SolutionComponent)}");
}
solution.Capabilities |= SolutionCaps.FitsInDispenser;
}
public void CancelTransformation()

View File

@@ -7,6 +7,7 @@ using Robust.Shared.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
@@ -19,8 +20,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
[Dependency] private readonly IMapManager _mapManager = default!;
public override string Name => "Vapor";
[ViewVariables]
private SolutionComponent _contents;
[ViewVariables]
private ReagentUnit _transferAmount;
@@ -28,11 +27,15 @@ namespace Content.Server.GameObjects.Components.Chemistry
private Vector2 _direction;
private float _velocity;
public override void Initialize()
{
base.Initialize();
_contents = Owner.GetComponent<SolutionComponent>();
if (!Owner.EnsureComponent(out SolutionComponent _))
{
Logger.Warning(
$"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(SolutionComponent)}");
}
}
public void Start(Vector2 dir, float velocity)
@@ -56,6 +59,9 @@ namespace Content.Server.GameObjects.Components.Chemistry
public void Update()
{
if (!Owner.TryGetComponent(out SolutionComponent contents))
return;
if (!_running)
return;
@@ -70,11 +76,11 @@ namespace Content.Server.GameObjects.Components.Chemistry
foreach (var tile in tiles)
{
var pos = tile.GridIndices.ToGridCoordinates(_mapManager, tile.GridIndex);
SpillHelper.SpillAt(pos, _contents.SplitSolution(amount), "PuddleSmear", false); //make non PuddleSmear?
SpillHelper.SpillAt(pos, contents.SplitSolution(amount), "PuddleSmear", false); //make non PuddleSmear?
}
}
if (_contents.CurrentVolume == 0)
if (contents.CurrentVolume == 0)
{
// Delete this
Owner.Delete();
@@ -87,7 +93,14 @@ namespace Content.Server.GameObjects.Components.Chemistry
{
return false;
}
var result = _contents.TryAddSolution(solution);
if (!Owner.TryGetComponent(out SolutionComponent contents))
{
return false;
}
var result = contents.TryAddSolution(solution);
if (!result)
{
return false;

View File

@@ -60,11 +60,18 @@ namespace Content.Server.GameObjects.Components.Fluids
return false;
}
var mopContents = mopComponent.Contents;
if (mopContents == null)
{
return false;
}
// Let's fill 'er up
// If this is called the mop should be empty but just in case we'll do Max - Current
var transferAmount = ReagentUnit.Min(mopComponent.MaxVolume - mopComponent.CurrentVolume, CurrentVolume);
var solution = contents.SplitSolution(transferAmount);
if (!mopComponent.Contents.TryAddSolution(solution) || mopComponent.CurrentVolume == 0)
if (!mopContents.TryAddSolution(solution) || mopComponent.CurrentVolume == 0)
{
return false;
}
@@ -109,7 +116,14 @@ namespace Content.Server.GameObjects.Components.Fluids
return false;
}
var solution = mopComponent.Contents.SplitSolution(transferAmount);
var mopContents = mopComponent.Contents;
if (mopContents == null)
{
return false;
}
var solution = mopContents.SplitSolution(transferAmount);
if (!contents.TryAddSolution(solution))
{
//This really shouldn't happen
@@ -127,7 +141,6 @@ namespace Content.Server.GameObjects.Components.Fluids
EntitySystem.Get<AudioSystem>().PlayFromEntity(_sound, Owner);
return true;
}
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.Chemistry;
#nullable enable
using Content.Server.GameObjects.Components.Chemistry;
using Content.Server.Utility;
using Content.Shared.Chemistry;
using Content.Shared.Interfaces;
@@ -7,6 +8,7 @@ using Robust.Server.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Fluids
@@ -18,16 +20,23 @@ namespace Content.Server.GameObjects.Components.Fluids
public class MopComponent : Component, IAfterInteract
{
public override string Name => "Mop";
internal SolutionComponent Contents => _contents;
private SolutionComponent _contents;
public SolutionComponent? Contents => Owner.GetComponentOrNull<SolutionComponent>();
public ReagentUnit MaxVolume
{
get => _contents.MaxVolume;
set => _contents.MaxVolume = value;
get => Owner.GetComponentOrNull<SolutionComponent>()?.MaxVolume ?? ReagentUnit.Zero;
set
{
if (Owner.TryGetComponent(out SolutionComponent? solution))
{
solution.MaxVolume = value;
}
}
}
public ReagentUnit CurrentVolume => _contents.CurrentVolume;
public ReagentUnit CurrentVolume =>
Owner.GetComponentOrNull<SolutionComponent>()?.CurrentVolume ?? ReagentUnit.Zero;
// Currently there's a separate amount for pickup and dropoff so
// Picking up a puddle requires multiple clicks
@@ -36,7 +45,7 @@ namespace Content.Server.GameObjects.Components.Fluids
public ReagentUnit PickupAmount => _pickupAmount;
private ReagentUnit _pickupAmount;
private string _pickupSound;
private string _pickupSound = "";
/// <inheritdoc />
public override void ExposeData(ObjectSerializer serializer)
@@ -49,12 +58,16 @@ namespace Content.Server.GameObjects.Components.Fluids
public override void Initialize()
{
base.Initialize();
_contents = Owner.GetComponent<SolutionComponent>();
if (!Owner.EnsureComponent(out SolutionComponent _))
{
Logger.Warning($"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(SolutionComponent)}");
}
}
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
{
if (!Owner.TryGetComponent(out SolutionComponent? contents)) return;
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
if (CurrentVolume <= 0)
@@ -66,12 +79,12 @@ namespace Content.Server.GameObjects.Components.Fluids
if (eventArgs.Target == null)
{
// Drop the liquid on the mop on to the ground
SpillHelper.SpillAt(eventArgs.ClickLocation, _contents.SplitSolution(CurrentVolume), "PuddleSmear");
SpillHelper.SpillAt(eventArgs.ClickLocation, contents.SplitSolution(CurrentVolume), "PuddleSmear");
return;
}
if (!eventArgs.Target.TryGetComponent(out PuddleComponent puddleComponent))
if (!eventArgs.Target.TryGetComponent(out PuddleComponent? puddleComponent))
{
return;
}
@@ -102,23 +115,22 @@ namespace Content.Server.GameObjects.Components.Fluids
if (puddleCleaned) //After cleaning the puddle, make a new puddle with solution from the mop as a "wet floor". Then evaporate it slowly.
{
SpillHelper.SpillAt(eventArgs.ClickLocation, _contents.SplitSolution(transferAmount), "PuddleSmear");
SpillHelper.SpillAt(eventArgs.ClickLocation, contents.SplitSolution(transferAmount), "PuddleSmear");
}
else
{
_contents.SplitSolution(transferAmount);
contents.SplitSolution(transferAmount);
}
// Give some visual feedback shit's happening (for anyone who can't hear sound)
Owner.PopupMessage(eventArgs.User, Loc.GetString("Swish"));
if (_pickupSound == null)
if (string.IsNullOrWhiteSpace(_pickupSound))
{
return;
}
EntitySystem.Get<AudioSystem>().PlayFromEntity(_pickupSound, Owner);
}
}
}

View File

@@ -115,6 +115,7 @@ namespace Content.Server.GameObjects.Components.Fluids
public override void Initialize()
{
base.Initialize();
if (Owner.TryGetComponent(out SolutionComponent solutionComponent))
{
_contents = solutionComponent;
@@ -122,7 +123,6 @@ namespace Content.Server.GameObjects.Components.Fluids
else
{
_contents = Owner.AddComponent<SolutionComponent>();
_contents.Initialize();
}
_snapGrid = Owner.EnsureComponent<SnapGridComponent>();

View File

@@ -8,6 +8,7 @@ using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
@@ -45,13 +46,17 @@ namespace Content.Server.GameObjects.Components.Fluids
set => _sprayVelocity = value;
}
private SolutionComponent _contents;
public ReagentUnit CurrentVolume => _contents.CurrentVolume;
public ReagentUnit CurrentVolume => Owner.GetComponentOrNull<SolutionComponent>()?.CurrentVolume ?? ReagentUnit.Zero;
public override void Initialize()
{
base.Initialize();
_contents = Owner.GetComponent<SolutionComponent>();
if (!Owner.EnsureComponent(out SolutionComponent _))
{
Logger.Warning(
$"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(SolutionComponent)}");
}
}
public override void ExposeData(ObjectSerializer serializer)
@@ -74,8 +79,11 @@ namespace Content.Server.GameObjects.Components.Fluids
if (eventArgs.ClickLocation.GridID != playerPos.GridID)
return;
if (!Owner.TryGetComponent(out SolutionComponent contents))
return;
var direction = (eventArgs.ClickLocation.Position - playerPos.Position).Normalized;
var solution = _contents.SplitSolution(_transferAmount);
var solution = contents.SplitSolution(_transferAmount);
playerPos = playerPos.Offset(direction); // Move a bit so we don't hit the player
//TODO: check for wall?

View File

@@ -17,6 +17,7 @@ using Content.Server.GameObjects.Components.Body;
using Content.Server.GameObjects.EntitySystems.DoAfter;
using Robust.Shared.Maths;
using System;
using Robust.Shared.Log;
namespace Content.Server.GameObjects.Components.Movement
{
@@ -39,14 +40,17 @@ namespace Content.Server.GameObjects.Components.Movement
[ViewVariables]
private float _climbDelay;
private ICollidableComponent _collidableComponent;
private DoAfterSystem _doAfterSystem;
public override void Initialize()
{
base.Initialize();
_collidableComponent = Owner.GetComponent<ICollidableComponent>();
if (!Owner.EnsureComponent(out CollidableComponent _))
{
Logger.Warning($"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(CollidableComponent)}");
}
_doAfterSystem = EntitySystem.Get<DoAfterSystem>();
}

View File

@@ -3,8 +3,8 @@ using System.Collections.Generic;
using Content.Shared.GameObjects.EntitySystems;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
@@ -22,14 +22,6 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
[ViewVariables]
private EmergencyLightState _lightState = EmergencyLightState.Charging;
[ViewVariables]
private BatteryComponent Battery => Owner.GetComponent<BatteryComponent>();
[ViewVariables]
private PointLightComponent Light => Owner.GetComponent<PointLightComponent>();
[ViewVariables]
private PowerReceiverComponent PowerReceiver => Owner.GetComponent<PowerReceiverComponent>();
private SpriteComponent Sprite => Owner.GetComponent<SpriteComponent>();
[ViewVariables(VVAccess.ReadWrite)]
private float _wattage;
[ViewVariables(VVAccess.ReadWrite)]
@@ -58,9 +50,14 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
/// </summary>
public void UpdateState()
{
if (PowerReceiver.Powered)
if (!Owner.TryGetComponent(out PowerReceiverComponent receiver))
{
PowerReceiver.Load = (int) Math.Abs(_wattage);
return;
}
if (receiver.Powered)
{
receiver.Load = (int) Math.Abs(_wattage);
TurnOff();
_lightState = EmergencyLightState.Charging;
}
@@ -76,9 +73,14 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
if (_lightState == EmergencyLightState.Empty
|| _lightState == EmergencyLightState.Full) return;
if (!Owner.TryGetComponent(out BatteryComponent battery))
{
return;
}
if(_lightState == EmergencyLightState.On)
{
if (!Battery.TryUseCharge(_wattage * frameTime))
if (!battery.TryUseCharge(_wattage * frameTime))
{
_lightState = EmergencyLightState.Empty;
TurnOff();
@@ -86,10 +88,14 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
}
else
{
Battery.CurrentCharge += _chargingWattage * frameTime * _chargingEfficiency;
if (Battery.BatteryState == BatteryState.Full)
battery.CurrentCharge += _chargingWattage * frameTime * _chargingEfficiency;
if (battery.BatteryState == BatteryState.Full)
{
PowerReceiver.Load = 1;
if (Owner.TryGetComponent(out PowerReceiverComponent receiver))
{
receiver.Load = 1;
}
_lightState = EmergencyLightState.Full;
}
}
@@ -97,25 +103,49 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
private void TurnOff()
{
Sprite.LayerSetState(0, "emergency_light_off");
Light.Enabled = false;
if (Owner.TryGetComponent(out SpriteComponent sprite))
{
sprite.LayerSetState(0, "emergency_light_off");
}
if (Owner.TryGetComponent(out PointLightComponent light))
{
light.Enabled = false;
}
}
private void TurnOn()
{
Sprite.LayerSetState(0, "emergency_light_on");
Light.Enabled = true;
if (Owner.TryGetComponent(out SpriteComponent sprite))
{
sprite.LayerSetState(0, "emergency_light_on");
}
if (Owner.TryGetComponent(out PointLightComponent light))
{
light.Enabled = true;
}
}
public override void Initialize()
{
base.Initialize();
Owner.GetComponent<PowerReceiverComponent>().OnPowerStateChanged += UpdateState;
if (!Owner.EnsureComponent(out PowerReceiverComponent receiver))
{
Logger.Warning($"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(PowerReceiverComponent)}");
}
receiver.OnPowerStateChanged += UpdateState;
}
public override void OnRemove()
{
Owner.GetComponent<PowerReceiverComponent>().OnPowerStateChanged -= UpdateState;
if (Owner.TryGetComponent(out PowerReceiverComponent receiver))
{
receiver.OnPowerStateChanged -= UpdateState;
}
base.OnRemove();
}
@@ -132,7 +162,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
On
}
public Dictionary<EmergencyLightState, string> BatteryStateText = new Dictionary<EmergencyLightState, String>
public Dictionary<EmergencyLightState, string> BatteryStateText = new Dictionary<EmergencyLightState, string>
{
{ EmergencyLightState.Full, "[color=darkgreen]Full[/color]"},
{ EmergencyLightState.Empty, "[color=darkred]Empty[/color]"},

View File

@@ -4,6 +4,7 @@ using Content.Shared.GameObjects.EntitySystems;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
@@ -19,8 +20,6 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
{
public override string Name => "SolarPanel";
private PowerSupplierComponent _powerSupplier;
/// <summary>
/// Maximum supply output by this panel (coverage = 1)
/// </summary>
@@ -64,15 +63,21 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
private void UpdateSupply()
{
if (_powerSupplier != null)
_powerSupplier.SupplyRate = (int) (_maxSupply * _coverage);
if (Owner.TryGetComponent(out PowerSupplierComponent supplier))
{
supplier.SupplyRate = (int) (_maxSupply * _coverage);
}
}
public override void Initialize()
{
base.Initialize();
_powerSupplier = Owner.GetComponent<PowerSupplierComponent>();
if (!Owner.EnsureComponent(out PowerSupplierComponent _))
{
Logger.Warning($"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(PowerSupplierComponent)}");
}
UpdateSupply();
}

View File

@@ -1,4 +1,3 @@
using System;
using Content.Server.GameObjects.Components.Mobs;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
@@ -32,10 +31,11 @@ namespace Content.Server.GameObjects.Components.Projectiles
public override void Initialize()
{
base.Initialize();
if (!Owner.HasComponent<ProjectileComponent>())
if (!Owner.EnsureComponent(out ProjectileComponent _))
{
Logger.Error("StunProjectile entity must have a ProjectileComponent");
throw new InvalidOperationException();
Logger.Warning(
$"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(ProjectileComponent)}");
}
}

View File

@@ -28,6 +28,7 @@ using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Content.Shared.GameObjects.Components.Damage;
using Robust.Shared.GameObjects;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{
@@ -157,7 +158,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
public override void OnAdd()
{
base.OnAdd();
var rangedWeaponComponent = Owner.GetComponent<ServerRangedWeaponComponent>();
if (!Owner.EnsureComponent(out ServerRangedWeaponComponent rangedWeaponComponent))
{
Logger.Warning(
$"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(ServerRangedWeaponComponent)}");
}
rangedWeaponComponent.Barrel ??= this;
rangedWeaponComponent.FireHandler += Fire;

View File

@@ -37,7 +37,6 @@ namespace Content.Server.GameObjects.Components
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
private AudioSystem _audioSystem = default!;
private AppearanceComponent _appearance = default!;
private bool _isPanelOpen;
@@ -105,7 +104,10 @@ namespace Content.Server.GameObjects.Components
private void UpdateAppearance()
{
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen && IsPanelVisible);
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
{
appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen && IsPanelVisible);
}
}
/// <summary>
@@ -148,8 +150,11 @@ namespace Content.Server.GameObjects.Components
{
base.Initialize();
_audioSystem = EntitySystem.Get<AudioSystem>();
_appearance = Owner.GetComponent<AppearanceComponent>();
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen);
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
{
appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen);
}
if (UserInterface != null)
{