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:
@@ -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<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()
|
||||
{
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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]"},
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user