diff --git a/Content.IntegrationTests/Tests/EntityTest.cs b/Content.IntegrationTests/Tests/EntityTest.cs index 4fd9846263..ae458d078b 100644 --- a/Content.IntegrationTests/Tests/EntityTest.cs +++ b/Content.IntegrationTests/Tests/EntityTest.cs @@ -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 - { - 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; - } + 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); + }, "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(); + var entityManager = server.ResolveDependency(); + var mapLoader = server.ResolveDependency(); + var pauseManager = server.ResolveDependency(); + var componentFactory = server.ResolveDependency(); + var prototypeManager = server.ResolveDependency(); + + 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() { @@ -184,43 +262,44 @@ namespace Content.IntegrationTests.Tests server.Assert(() => { - Assert.DoesNotThrow(() => + foreach (var distinct in distinctComponents) { - foreach (var distinct in distinctComponents) + var testLocation = new GridCoordinates(new Vector2(0, 0), grid); + var entity = entityManager.SpawnEntity("AllComponentsOneEntityDeleteTestEntity", testLocation); + + Assert.That(entity.Initialized); + + foreach (var type in distinct.components) { - var testLocation = new GridCoordinates(new Vector2(0, 0), grid); - var entity = entityManager.SpawnEntity("AllComponentsOneEntityDeleteTestEntity", testLocation); + var component = (Component) componentFactory.GetComponent(type); - Assert.That(entity.Initialized); - - foreach (var type in distinct.components) + // If the entity already has this component, if it was ensured or added by another + if (entity.HasComponent(component.GetType())) { - var component = (Component) componentFactory.GetComponent(type); - - // If the entity already has this component, if it was ensured or added by another - if (entity.HasComponent(component.GetType())) - { - continue; - } - - // If this component is ignored - if (skipComponents.Contains(component.Name)) - { - continue; - } - - component.Owner = entity; - - Logger.LogS(LogLevel.Debug, "EntityTest", $"Adding component: {component.Name}"); - - entityManager.ComponentManager.AddComponent(entity, component); + continue; } - server.RunTicks(48); // Run one full second on the server + // If this component is ignored + if (skipComponents.Contains(component.Name)) + { + continue; + } - entityManager.DeleteEntity(entity.Uid); + 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(48); // Run one full second on the server + + entityManager.DeleteEntity(entity.Uid); + } }); await server.WaitIdleAsync(); diff --git a/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs b/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs index 571e78f64f..24f4879d55 100644 --- a/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs @@ -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().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() diff --git a/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs b/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs index 066cf21836..ace097cce5 100644 --- a/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs @@ -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(); + + 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; diff --git a/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs b/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs index e94cc91f43..ee190c6461 100644 --- a/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs @@ -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().PlayFromEntity(_sound, Owner); return true; - } } } diff --git a/Content.Server/GameObjects/Components/Fluids/MopComponent.cs b/Content.Server/GameObjects/Components/Fluids/MopComponent.cs index 11188bcd5f..338af8611c 100644 --- a/Content.Server/GameObjects/Components/Fluids/MopComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/MopComponent.cs @@ -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(); public ReagentUnit MaxVolume { - get => _contents.MaxVolume; - set => _contents.MaxVolume = value; + get => Owner.GetComponentOrNull()?.MaxVolume ?? ReagentUnit.Zero; + set + { + if (Owner.TryGetComponent(out SolutionComponent? solution)) + { + solution.MaxVolume = value; + } + } } - public ReagentUnit CurrentVolume => _contents.CurrentVolume; + public ReagentUnit CurrentVolume => + Owner.GetComponentOrNull()?.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 = ""; /// 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(); + 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().PlayFromEntity(_pickupSound, Owner); - } } } diff --git a/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs b/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs index a3703a5e21..62551505c2 100644 --- a/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs @@ -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(); - _contents.Initialize(); } _snapGrid = Owner.EnsureComponent(); diff --git a/Content.Server/GameObjects/Components/Fluids/SprayComponent.cs b/Content.Server/GameObjects/Components/Fluids/SprayComponent.cs index d1e9c6f098..e10ae9c7df 100644 --- a/Content.Server/GameObjects/Components/Fluids/SprayComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/SprayComponent.cs @@ -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()?.CurrentVolume ?? ReagentUnit.Zero; public override void Initialize() { base.Initialize(); - _contents = Owner.GetComponent(); + + 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? diff --git a/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs b/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs index 45baeb54e7..22d9e8a775 100644 --- a/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs +++ b/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs @@ -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(); + if (!Owner.EnsureComponent(out CollidableComponent _)) + { + Logger.Warning($"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(CollidableComponent)}"); + } + _doAfterSystem = EntitySystem.Get(); } diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/EmergencyLightComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/EmergencyLightComponent.cs index 3fa04af25a..58a53cf253 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/EmergencyLightComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/EmergencyLightComponent.cs @@ -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(); - [ViewVariables] - private PointLightComponent Light => Owner.GetComponent(); - [ViewVariables] - private PowerReceiverComponent PowerReceiver => Owner.GetComponent(); - private SpriteComponent Sprite => Owner.GetComponent(); - [ViewVariables(VVAccess.ReadWrite)] private float _wattage; [ViewVariables(VVAccess.ReadWrite)] @@ -58,9 +50,14 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece /// 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().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().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 BatteryStateText = new Dictionary + public Dictionary BatteryStateText = new Dictionary { { EmergencyLightState.Full, "[color=darkgreen]Full[/color]"}, { EmergencyLightState.Empty, "[color=darkred]Empty[/color]"}, diff --git a/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs b/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs index 6f63859193..fc79c97485 100644 --- a/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs +++ b/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs @@ -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; - /// /// Maximum supply output by this panel (coverage = 1) /// @@ -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(); + if (!Owner.EnsureComponent(out PowerSupplierComponent _)) + { + Logger.Warning($"Entity {Owner.Name} at {Owner.Transform.MapPosition} didn't have a {nameof(PowerSupplierComponent)}"); + } + UpdateSupply(); } diff --git a/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs b/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs index b09881d2af..95ab0b07ee 100644 --- a/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs @@ -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()) + + 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)}"); } } diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs index dfc2f61b8a..7ee34c2175 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs @@ -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(); + + 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; diff --git a/Content.Server/GameObjects/Components/WiresComponent.cs b/Content.Server/GameObjects/Components/WiresComponent.cs index 39dfc9c064..bd0276ab62 100644 --- a/Content.Server/GameObjects/Components/WiresComponent.cs +++ b/Content.Server/GameObjects/Components/WiresComponent.cs @@ -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); + } } /// @@ -148,8 +150,11 @@ namespace Content.Server.GameObjects.Components { base.Initialize(); _audioSystem = EntitySystem.Get(); - _appearance = Owner.GetComponent(); - _appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen); + + if (Owner.TryGetComponent(out AppearanceComponent? appearance)) + { + appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen); + } if (UserInterface != null) {