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:
@@ -17,9 +17,7 @@ namespace Content.Client.GameObjects.Components.Body
|
|||||||
[ComponentReference(typeof(IBodyManagerComponent))]
|
[ComponentReference(typeof(IBodyManagerComponent))]
|
||||||
public class BodyManagerComponent : SharedBodyManagerComponent, IClientDraggable
|
public class BodyManagerComponent : SharedBodyManagerComponent, IClientDraggable
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public bool ClientCanDropOn(CanDropEventArgs eventArgs)
|
public bool ClientCanDropOn(CanDropEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,13 +27,9 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action? OnMidiPlaybackEnded;
|
public event Action? OnMidiPlaybackEnded;
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IMidiManager _midiManager = default!;
|
[Dependency] private readonly IMidiManager _midiManager = default!;
|
||||||
|
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
[Dependency] private readonly IClientNetManager _netManager = default!;
|
[Dependency] private readonly IClientNetManager _netManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private IMidiRenderer? _renderer;
|
private IMidiRenderer? _renderer;
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ namespace Content.Client.GameObjects.Components.Items
|
|||||||
{
|
{
|
||||||
private HandsGui? _gui;
|
private HandsGui? _gui;
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud = default!;
|
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
private readonly List<Hand> _hands = new List<Hand>();
|
private readonly List<Hand> _hands = new List<Hand>();
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
using System.IO;
|
using System.Threading.Tasks;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Content.Server.GameObjects.Components.Doors;
|
using Content.Server.GameObjects.Components.Doors;
|
||||||
using Content.Shared.Physics;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Robust.Server.Console.Commands;
|
|
||||||
using Robust.Shared.GameObjects.Components;
|
using Robust.Shared.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using static Content.Server.GameObjects.Components.Doors.ServerDoorComponent;
|
using static Content.Server.GameObjects.Components.Doors.ServerDoorComponent;
|
||||||
|
|
||||||
namespace Content.IntegrationTests.Tests.Doors
|
namespace Content.IntegrationTests.Tests.Doors
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Robust.Server.Interfaces.Maps;
|
using Robust.Server.Interfaces.Maps;
|
||||||
@@ -11,6 +14,7 @@ using Robust.Shared.Log;
|
|||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Logger = Robust.Shared.Log.Logger;
|
||||||
|
|
||||||
namespace Content.IntegrationTests.Tests
|
namespace Content.IntegrationTests.Tests
|
||||||
{
|
{
|
||||||
@@ -30,7 +34,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
var pauseMan = server.ResolveDependency<IPauseManager>();
|
var pauseMan = server.ResolveDependency<IPauseManager>();
|
||||||
var prototypes = new List<EntityPrototype>();
|
var prototypes = new List<EntityPrototype>();
|
||||||
IMapGrid grid = default;
|
IMapGrid grid = default;
|
||||||
IEntity testEntity = null;
|
IEntity testEntity;
|
||||||
|
|
||||||
//Build up test environment
|
//Build up test environment
|
||||||
server.Post(() =>
|
server.Post(() =>
|
||||||
@@ -59,7 +63,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.LogS(LogLevel.Debug, "EntityTest", "Testing: " + prototype.ID);
|
Logger.LogS(LogLevel.Debug, "EntityTest", $"Testing: {prototype.ID}");
|
||||||
testEntity = entityMan.SpawnEntity(prototype.ID, testLocation);
|
testEntity = entityMan.SpawnEntity(prototype.ID, testLocation);
|
||||||
server.RunTicks(2);
|
server.RunTicks(2);
|
||||||
Assert.That(testEntity.Initialized);
|
Assert.That(testEntity.Initialized);
|
||||||
@@ -69,8 +73,8 @@ namespace Content.IntegrationTests.Tests
|
|||||||
//Fail any exceptions thrown on spawn
|
//Fail any exceptions thrown on spawn
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.LogS(LogLevel.Error, "EntityTest", "Entity '" + prototype.ID + "' threw: " + e.Message);
|
Logger.LogS(LogLevel.Error, "EntityTest", $"Entity '{prototype.ID}' threw: {e.Message}");
|
||||||
//Assert.Fail();
|
Assert.Fail();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,5 +105,125 @@ namespace Content.IntegrationTests.Tests
|
|||||||
|
|
||||||
await client.WaitIdleAsync();
|
await client.WaitIdleAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task AllComponentsOneEntityDeleteTest()
|
||||||
|
{
|
||||||
|
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: AllComponentsOneEntityDeleteTestEntity";
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
var distinctComponents = new List<(List<Type> components, List<Type> references)>
|
||||||
|
{
|
||||||
|
(new List<Type>(), new List<Type>())
|
||||||
|
};
|
||||||
|
|
||||||
|
// Split components into groups, ensuring that their references don't conflict
|
||||||
|
foreach (var type in componentFactory.AllRegisteredTypes)
|
||||||
|
{
|
||||||
|
var registration = componentFactory.GetRegistration(type);
|
||||||
|
|
||||||
|
for (var i = 0; i < distinctComponents.Count; i++)
|
||||||
|
{
|
||||||
|
var distinct = distinctComponents[i];
|
||||||
|
|
||||||
|
if (distinct.references.Intersect(registration.References).Any())
|
||||||
|
{
|
||||||
|
// Ensure the next list if this one has conflicting references
|
||||||
|
if (i + 1 >= distinctComponents.Count)
|
||||||
|
{
|
||||||
|
distinctComponents.Add((new List<Type>(), new List<Type>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the component and its references if no conflicting references were found
|
||||||
|
distinct.components.Add(type);
|
||||||
|
distinct.references.AddRange(registration.References);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
Assert.That(distinctComponents, Is.Not.Empty);
|
||||||
|
|
||||||
|
server.Assert(() =>
|
||||||
|
{
|
||||||
|
Assert.DoesNotThrow(() =>
|
||||||
|
{
|
||||||
|
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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
server.RunTicks(48); // Run one full second on the server
|
||||||
|
|
||||||
|
entityManager.DeleteEntity(entity.Uid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.WaitIdleAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
Assert.That(apcEnt.TryGetComponent<ApcComponent>(out var apc));
|
Assert.That(apcEnt.TryGetComponent<ApcComponent>(out var apc));
|
||||||
Assert.That(apcExtensionEnt.TryGetComponent<PowerProviderComponent>(out var provider));
|
Assert.That(apcExtensionEnt.TryGetComponent<PowerProviderComponent>(out var provider));
|
||||||
Assert.That(powerReceiverEnt.TryGetComponent(out receiver));
|
Assert.That(powerReceiverEnt.TryGetComponent(out receiver));
|
||||||
|
Assert.NotNull(apc.Battery);
|
||||||
|
|
||||||
provider.PowerTransferRange = 5; //arbitrary range to reach receiver
|
provider.PowerTransferRange = 5; //arbitrary range to reach receiver
|
||||||
receiver.PowerReceptionRange = 5; //arbitrary range to reach provider
|
receiver.PowerReceptionRange = 5; //arbitrary range to reach provider
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ namespace Content.Server.Atmos
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class GasSprayerComponent : Component, IAfterInteract
|
public class GasSprayerComponent : Component, IAfterInteract
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
//TODO: create a function that can create a gas based on a solution mix
|
//TODO: create a function that can create a gas based on a solution mix
|
||||||
public override string Name => "GasSprayer";
|
public override string Name => "GasSprayer";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
@@ -15,6 +16,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Access
|
namespace Content.Server.GameObjects.Components.Access
|
||||||
{
|
{
|
||||||
@@ -22,16 +24,19 @@ namespace Content.Server.GameObjects.Components.Access
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class IdCardConsoleComponent : SharedIdCardConsoleComponent, IActivate
|
public class IdCardConsoleComponent : SharedIdCardConsoleComponent, IActivate
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
private ContainerSlot _privilegedIdContainer = default!;
|
||||||
private ContainerSlot _privilegedIdContainer;
|
private ContainerSlot _targetIdContainer = default!;
|
||||||
private ContainerSlot _targetIdContainer;
|
|
||||||
private AccessReader _accessReader;
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(IdCardConsoleUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -40,16 +45,30 @@ namespace Content.Server.GameObjects.Components.Access
|
|||||||
_privilegedIdContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-privilegedId", Owner);
|
_privilegedIdContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-privilegedId", Owner);
|
||||||
_targetIdContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-targetId", Owner);
|
_targetIdContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-targetId", Owner);
|
||||||
|
|
||||||
_accessReader = Owner.GetComponent<AccessReader>();
|
if (!Owner.EnsureComponent(out AccessReader _))
|
||||||
|
{
|
||||||
|
Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} didn't have a {nameof(AccessReader)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserInterface == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} doesn't have a {nameof(ServerUserInterfaceComponent)}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(IdCardConsoleUiKey.Key);
|
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
{
|
{
|
||||||
|
if (obj.Session.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (obj.Message)
|
switch (obj.Message)
|
||||||
{
|
{
|
||||||
case IdButtonPressedMessage msg:
|
case IdButtonPressedMessage msg:
|
||||||
@@ -72,13 +91,19 @@ namespace Content.Server.GameObjects.Components.Access
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if there is an ID in <see cref="_privilegedIdContainer"/> and said ID satisfies the requirements of <see cref="_accessReader"/>.
|
/// Returns true if there is an ID in <see cref="_privilegedIdContainer"/> and said ID satisfies the requirements of <see cref="AccessReader"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool PrivilegedIdIsAuthorized()
|
private bool PrivilegedIdIsAuthorized()
|
||||||
{
|
{
|
||||||
var privilegedIdEntity = _privilegedIdContainer.ContainedEntity;
|
if (!Owner.TryGetComponent(out AccessReader? reader))
|
||||||
return privilegedIdEntity != null && _accessReader.IsAllowed(privilegedIdEntity);
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var privilegedIdEntity = _privilegedIdContainer.ContainedEntity;
|
||||||
|
return privilegedIdEntity != null && reader.IsAllowed(privilegedIdEntity);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the "Submit" button in the UI gets pressed.
|
/// Called when the "Submit" button in the UI gets pressed.
|
||||||
/// Writes data passed from the UI into the ID stored in <see cref="_targetIdContainer"/>, if present.
|
/// Writes data passed from the UI into the ID stored in <see cref="_targetIdContainer"/>, if present.
|
||||||
@@ -110,7 +135,7 @@ namespace Content.Server.GameObjects.Components.Access
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleId(IEntity user, ContainerSlot container)
|
private void HandleId(IEntity user, ContainerSlot container)
|
||||||
{
|
{
|
||||||
if (!user.TryGetComponent(out IHandsComponent hands))
|
if (!user.TryGetComponent(out IHandsComponent? hands))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You have no hands."));
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You have no hands."));
|
||||||
return;
|
return;
|
||||||
@@ -133,7 +158,13 @@ namespace Content.Server.GameObjects.Components.Access
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!hands.Drop(hands.ActiveHand, container))
|
|
||||||
|
if (hands.ActiveHand == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hands.Drop(hands.ActiveHand, container))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You can't let go of the ID card!"));
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You can't let go of the ID card!"));
|
||||||
return;
|
return;
|
||||||
@@ -185,17 +216,17 @@ namespace Content.Server.GameObjects.Components.Access
|
|||||||
_privilegedIdContainer.ContainedEntity?.Name ?? "",
|
_privilegedIdContainer.ContainedEntity?.Name ?? "",
|
||||||
_targetIdContainer.ContainedEntity?.Name ?? "");
|
_targetIdContainer.ContainedEntity?.Name ?? "");
|
||||||
}
|
}
|
||||||
_userInterface.SetState(newState);
|
UserInterface?.SetState(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate(ActivateEventArgs eventArgs)
|
public void Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if(!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if(!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
using Robust.Shared.GameObjects.Components.Transform;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
@@ -13,7 +14,6 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class AirtightComponent : Component, IMapInit
|
public class AirtightComponent : Component, IMapInit
|
||||||
{
|
{
|
||||||
private SnapGridComponent _snapGrid;
|
|
||||||
private (GridId, MapIndices) _lastPosition;
|
private (GridId, MapIndices) _lastPosition;
|
||||||
|
|
||||||
public override string Name => "Airtight";
|
public override string Name => "Airtight";
|
||||||
@@ -28,7 +28,11 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_airBlocked = value;
|
_airBlocked = value;
|
||||||
EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID)?.Invalidate(_snapGrid.Position);
|
|
||||||
|
if (Owner.TryGetComponent(out SnapGridComponent? snapGrid))
|
||||||
|
{
|
||||||
|
EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID)?.Invalidate(snapGrid.Position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,19 +52,23 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
// Using the SnapGrid is critical for the performance of the room builder, and thus if
|
// Using the SnapGrid is critical for the performance of the room builder, and thus if
|
||||||
// it is absent the component will not be airtight. An exception is much easier to track
|
// it is absent the component will not be airtight. A warning is much easier to track
|
||||||
// down than the object magically not being airtight, so throw one if the SnapGrid component
|
// down than the object magically not being airtight, so log one if the SnapGrid component
|
||||||
// is missing.
|
// is missing.
|
||||||
if (!Owner.TryGetComponent(out _snapGrid))
|
if (!Owner.EnsureComponent(out SnapGridComponent _))
|
||||||
throw new Exception("Airtight entities must have a SnapGrid component");
|
Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition.ToString()} doesn't have a {nameof(SnapGridComponent)}");
|
||||||
|
|
||||||
UpdatePosition();
|
UpdatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MapInit()
|
public void MapInit()
|
||||||
{
|
{
|
||||||
_snapGrid.OnPositionChanged += OnTransformMove;
|
if (Owner.TryGetComponent(out SnapGridComponent? snapGrid))
|
||||||
_lastPosition = (Owner.Transform.GridID, _snapGrid.Position);
|
{
|
||||||
|
snapGrid.OnPositionChanged += OnTransformMove;
|
||||||
|
_lastPosition = (Owner.Transform.GridID, snapGrid.Position);
|
||||||
|
}
|
||||||
|
|
||||||
UpdatePosition();
|
UpdatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,11 +78,15 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
|
|
||||||
_airBlocked = false;
|
_airBlocked = false;
|
||||||
|
|
||||||
_snapGrid.OnPositionChanged -= OnTransformMove;
|
if (Owner.TryGetComponent(out SnapGridComponent? snapGrid))
|
||||||
|
{
|
||||||
|
snapGrid.OnPositionChanged -= OnTransformMove;
|
||||||
|
|
||||||
if(_fixVacuum)
|
if (_fixVacuum)
|
||||||
EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID)?
|
EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID)?
|
||||||
.FixVacuum(_snapGrid.Position);
|
.FixVacuum(snapGrid.Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UpdatePosition();
|
UpdatePosition();
|
||||||
}
|
}
|
||||||
@@ -83,15 +95,24 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
{
|
{
|
||||||
UpdatePosition(_lastPosition.Item1, _lastPosition.Item2);
|
UpdatePosition(_lastPosition.Item1, _lastPosition.Item2);
|
||||||
UpdatePosition();
|
UpdatePosition();
|
||||||
_lastPosition = (Owner.Transform.GridID, _snapGrid.Position);
|
|
||||||
|
if (Owner.TryGetComponent(out SnapGridComponent? snapGrid))
|
||||||
|
{
|
||||||
|
_lastPosition = (Owner.Transform.GridID, snapGrid.Position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePosition() => UpdatePosition(Owner.Transform.GridID, _snapGrid.Position);
|
private void UpdatePosition()
|
||||||
|
{
|
||||||
|
if (Owner.TryGetComponent(out SnapGridComponent? snapGrid))
|
||||||
|
{
|
||||||
|
UpdatePosition(Owner.Transform.GridID, snapGrid.Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdatePosition(GridId gridId, MapIndices pos)
|
private void UpdatePosition(GridId gridId, MapIndices pos)
|
||||||
{
|
{
|
||||||
EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(gridId)?.Invalidate(pos);
|
EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(gridId)?.Invalidate(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,30 +16,37 @@ using Robust.Shared.Interfaces.Map;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Atmos
|
namespace Content.Server.GameObjects.Components.Atmos
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped, IUse
|
public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped, IUse
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private IMapManager _mapManager = default!;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private BoundUserInterface _userInterface = default!;
|
|
||||||
private GasAnalyzerDanger _pressureDanger;
|
private GasAnalyzerDanger _pressureDanger;
|
||||||
private float _timeSinceSync;
|
private float _timeSinceSync;
|
||||||
private const float TimeBetweenSyncs = 2f;
|
private const float TimeBetweenSyncs = 2f;
|
||||||
private bool _checkPlayer = false; // Check at the player pos or at some other tile?
|
private bool _checkPlayer = false; // Check at the player pos or at some other tile?
|
||||||
private GridCoordinates? _position; // The tile that we scanned
|
private GridCoordinates? _position; // The tile that we scanned
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(GasAnalyzerUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(GasAnalyzerUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ComponentState GetComponentState()
|
public override ComponentState GetComponentState()
|
||||||
@@ -56,7 +63,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
{
|
{
|
||||||
_checkPlayer = true;
|
_checkPlayer = true;
|
||||||
_position = null;
|
_position = null;
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
Resync();
|
Resync();
|
||||||
}
|
}
|
||||||
@@ -71,7 +78,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
{
|
{
|
||||||
_checkPlayer = false;
|
_checkPlayer = false;
|
||||||
_position = pos;
|
_position = pos;
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
Resync();
|
Resync();
|
||||||
}
|
}
|
||||||
@@ -79,7 +86,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
public void CloseInterface(IPlayerSession session)
|
public void CloseInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_position = null;
|
_position = null;
|
||||||
_userInterface.Close(session);
|
UserInterface?.Close(session);
|
||||||
Resync();
|
Resync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +130,15 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
|
|
||||||
private void UpdateUserInterface()
|
private void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
|
if (UserInterface == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string? error = null;
|
string? error = null;
|
||||||
|
|
||||||
// Check if the player is still holding the gas analyzer => if not, don't update
|
// Check if the player is still holding the gas analyzer => if not, don't update
|
||||||
foreach (var session in _userInterface.SubscribedSessions)
|
foreach (var session in UserInterface.SubscribedSessions)
|
||||||
{
|
{
|
||||||
if (session.AttachedEntity == null)
|
if (session.AttachedEntity == null)
|
||||||
return;
|
return;
|
||||||
@@ -156,7 +168,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
if (tile == null)
|
if (tile == null)
|
||||||
{
|
{
|
||||||
error = "No Atmosphere!";
|
error = "No Atmosphere!";
|
||||||
_userInterface.SetState(
|
UserInterface.SetState(
|
||||||
new GasAnalyzerBoundUserInterfaceState(
|
new GasAnalyzerBoundUserInterfaceState(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -166,7 +178,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
}
|
}
|
||||||
|
|
||||||
var gases = new List<GasEntry>();
|
var gases = new List<GasEntry>();
|
||||||
for (int i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
||||||
{
|
{
|
||||||
var gas = Atmospherics.GetGas(i);
|
var gas = Atmospherics.GetGas(i);
|
||||||
|
|
||||||
@@ -175,7 +187,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
gases.Add(new GasEntry(gas.Name, tile.Gases[i], gas.Color));
|
gases.Add(new GasEntry(gas.Name, tile.Gases[i], gas.Color));
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.SetState(
|
UserInterface.SetState(
|
||||||
new GasAnalyzerBoundUserInterfaceState(
|
new GasAnalyzerBoundUserInterfaceState(
|
||||||
tile.Pressure,
|
tile.Pressure,
|
||||||
tile.Temperature,
|
tile.Temperature,
|
||||||
|
|||||||
@@ -6,16 +6,21 @@ using Robust.Shared.ViewVariables;
|
|||||||
namespace Content.Server.GameObjects.Components.Atmos
|
namespace Content.Server.GameObjects.Components.Atmos
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class GasMixtureComponent : Component
|
public class GasMixtureHolderComponent : Component
|
||||||
{
|
{
|
||||||
public override string Name => "GasMixture";
|
public override string Name => "GasMixtureHolder";
|
||||||
|
|
||||||
[ViewVariables] public GasMixture GasMixture { get; set; } = new GasMixture();
|
[ViewVariables] public GasMixture GasMixture { get; set; } = new GasMixture();
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
base.ExposeData(serializer);
|
base.ExposeData(serializer);
|
||||||
serializer.DataField(this, x => GasMixture.Volume, "volume", 0f);
|
|
||||||
|
serializer.DataReadWriteFunction(
|
||||||
|
"volume",
|
||||||
|
0f,
|
||||||
|
vol => GasMixture.Volume = vol,
|
||||||
|
() => GasMixture.Volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -50,7 +51,6 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
private float _timer = 0f;
|
private float _timer = 0f;
|
||||||
private Stopwatch _stopwatch = new Stopwatch();
|
private Stopwatch _stopwatch = new Stopwatch();
|
||||||
public int UpdateCounter { get; private set; } = 0;
|
public int UpdateCounter { get; private set; } = 0;
|
||||||
private IMapGrid _grid;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly HashSet<ExcitedGroup> _excitedGroups = new HashSet<ExcitedGroup>(1000);
|
private readonly HashSet<ExcitedGroup> _excitedGroups = new HashSet<ExcitedGroup>(1000);
|
||||||
@@ -89,42 +89,40 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void PryTile(MapIndices indices)
|
public void PryTile(MapIndices indices)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGridComponent)) return;
|
||||||
if (IsSpace(indices) || IsAirBlocked(indices)) return;
|
if (IsSpace(indices) || IsAirBlocked(indices)) return;
|
||||||
|
|
||||||
var tile = _grid.GetTileRef(indices).Tile;
|
var mapGrid = mapGridComponent.Grid;
|
||||||
|
var tile = mapGrid.GetTileRef(indices).Tile;
|
||||||
|
|
||||||
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
|
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
|
||||||
var tileDef = (ContentTileDefinition)tileDefinitionManager[tile.TypeId];
|
var tileDef = (ContentTileDefinition)tileDefinitionManager[tile.TypeId];
|
||||||
|
|
||||||
var underplating = tileDefinitionManager["underplating"];
|
var underplating = tileDefinitionManager["underplating"];
|
||||||
_grid.SetTile(indices, new Tile(underplating.TileId));
|
mapGrid.SetTile(indices, new Tile(underplating.TileId));
|
||||||
|
|
||||||
//Actually spawn the relevant tile item at the right position and give it some offset to the corner.
|
//Actually spawn the relevant tile item at the right position and give it some offset to the corner.
|
||||||
var tileItem = IoCManager.Resolve<IServerEntityManager>().SpawnEntity(tileDef.ItemDropPrototypeName, new GridCoordinates(indices.X, indices.Y, _grid));
|
var tileItem = IoCManager.Resolve<IServerEntityManager>().SpawnEntity(tileDef.ItemDropPrototypeName, new GridCoordinates(indices.X, indices.Y, mapGrid));
|
||||||
tileItem.Transform.WorldPosition += (0.2f, 0.2f);
|
tileItem.Transform.WorldPosition += (0.2f, 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_grid = Owner.GetComponent<IMapGridComponent>().Grid;
|
|
||||||
|
|
||||||
RepopulateTiles();
|
RepopulateTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnAdd()
|
public override void OnAdd()
|
||||||
{
|
{
|
||||||
base.OnAdd();
|
base.OnAdd();
|
||||||
|
|
||||||
_grid = Owner.GetComponent<IMapGridComponent>().Grid;
|
|
||||||
|
|
||||||
RepopulateTiles();
|
RepopulateTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RepopulateTiles()
|
public void RepopulateTiles()
|
||||||
{
|
{
|
||||||
foreach (var tile in _grid.GetAllTiles())
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
||||||
|
|
||||||
|
foreach (var tile in mapGrid.Grid.GetAllTiles())
|
||||||
{
|
{
|
||||||
if(!_tiles.ContainsKey(tile.GridIndices))
|
if(!_tiles.ContainsKey(tile.GridIndices))
|
||||||
_tiles.Add(tile.GridIndices, new TileAtmosphere(this, tile.GridIndex, tile.GridIndices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}));
|
_tiles.Add(tile.GridIndices, new TileAtmosphere(this, tile.GridIndex, tile.GridIndices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}));
|
||||||
@@ -145,6 +143,8 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
|
|
||||||
private void Revalidate()
|
private void Revalidate()
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
||||||
|
|
||||||
foreach (var indices in _invalidatedCoords.ToArray())
|
foreach (var indices in _invalidatedCoords.ToArray())
|
||||||
{
|
{
|
||||||
var tile = GetTile(indices);
|
var tile = GetTile(indices);
|
||||||
@@ -152,7 +152,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
|
|
||||||
if (tile == null)
|
if (tile == null)
|
||||||
{
|
{
|
||||||
tile = new TileAtmosphere(this, _grid.Index, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C});
|
tile = new TileAtmosphere(this, mapGrid.Grid.Index, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C});
|
||||||
_tiles[indices] = tile;
|
_tiles[indices] = tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,8 +199,9 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void FixVacuum(MapIndices indices)
|
public void FixVacuum(MapIndices indices)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
||||||
var tile = GetTile(indices);
|
var tile = GetTile(indices);
|
||||||
if (tile?.GridIndex != _grid.Index) return;
|
if (tile?.GridIndex != mapGrid.Grid.Index) return;
|
||||||
var adjacent = GetAdjacentTiles(indices);
|
var adjacent = GetAdjacentTiles(indices);
|
||||||
tile.Air = new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C};
|
tile.Air = new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C};
|
||||||
_tiles[indices] = tile;
|
_tiles[indices] = tile;
|
||||||
@@ -217,16 +218,17 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void AddActiveTile(TileAtmosphere tile)
|
public void AddActiveTile(TileAtmosphere? tile)
|
||||||
{
|
{
|
||||||
if (tile?.GridIndex != _grid.Index || tile?.Air == null) return;
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
||||||
|
if (tile?.GridIndex != mapGrid.Grid.Index || tile?.Air == null) return;
|
||||||
tile.Excited = true;
|
tile.Excited = true;
|
||||||
_activeTiles.Add(tile);
|
_activeTiles.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveActiveTile(TileAtmosphere tile)
|
public void RemoveActiveTile(TileAtmosphere? tile)
|
||||||
{
|
{
|
||||||
if (tile == null) return;
|
if (tile == null) return;
|
||||||
_activeTiles.Remove(tile);
|
_activeTiles.Remove(tile);
|
||||||
@@ -236,27 +238,29 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void AddHotspotTile(TileAtmosphere tile)
|
public void AddHotspotTile(TileAtmosphere? tile)
|
||||||
{
|
{
|
||||||
if (tile?.GridIndex != _grid.Index || tile?.Air == null) return;
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
||||||
|
if (tile?.GridIndex != mapGrid.Grid.Index || tile?.Air == null) return;
|
||||||
_hotspotTiles.Add(tile);
|
_hotspotTiles.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveHotspotTile(TileAtmosphere tile)
|
public void RemoveHotspotTile(TileAtmosphere? tile)
|
||||||
{
|
{
|
||||||
if (tile == null) return;
|
if (tile == null) return;
|
||||||
_hotspotTiles.Remove(tile);
|
_hotspotTiles.Remove(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddSuperconductivityTile(TileAtmosphere tile)
|
public void AddSuperconductivityTile(TileAtmosphere? tile)
|
||||||
{
|
{
|
||||||
if (tile?.GridIndex != _grid.Index) return;
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
||||||
|
if (tile?.GridIndex != mapGrid.Grid.Index) return;
|
||||||
_superconductivityTiles.Add(tile);
|
_superconductivityTiles.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveSuperconductivityTile(TileAtmosphere tile)
|
public void RemoveSuperconductivityTile(TileAtmosphere? tile)
|
||||||
{
|
{
|
||||||
if (tile == null) return;
|
if (tile == null) return;
|
||||||
_superconductivityTiles.Remove(tile);
|
_superconductivityTiles.Remove(tile);
|
||||||
@@ -264,9 +268,10 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void AddHighPressureDelta(TileAtmosphere tile)
|
public void AddHighPressureDelta(TileAtmosphere? tile)
|
||||||
{
|
{
|
||||||
if (tile?.GridIndex != _grid.Index) return;
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
||||||
|
if (tile?.GridIndex != mapGrid.Grid.Index) return;
|
||||||
_highPressureDelta.Add(tile);
|
_highPressureDelta.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,20 +297,22 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TileAtmosphere GetTile(GridCoordinates coordinates)
|
public TileAtmosphere? GetTile(GridCoordinates coordinates)
|
||||||
{
|
{
|
||||||
return GetTile(coordinates.ToMapIndices(_mapManager));
|
return GetTile(coordinates.ToMapIndices(_mapManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TileAtmosphere GetTile(MapIndices indices)
|
public TileAtmosphere? GetTile(MapIndices indices)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return null;
|
||||||
|
|
||||||
if (_tiles.TryGetValue(indices, out var tile)) return tile;
|
if (_tiles.TryGetValue(indices, out var tile)) return tile;
|
||||||
|
|
||||||
// We don't have that tile!
|
// We don't have that tile!
|
||||||
if (IsSpace(indices))
|
if (IsSpace(indices))
|
||||||
{
|
{
|
||||||
var space = new TileAtmosphere(this, _grid.Index, indices, new GasMixture(int.MaxValue){Temperature = Atmospherics.TCMB});
|
var space = new TileAtmosphere(this, mapGrid.Grid.Index, indices, new GasMixture(int.MaxValue){Temperature = Atmospherics.TCMB});
|
||||||
space.Air.MarkImmutable();
|
space.Air.MarkImmutable();
|
||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
@@ -324,7 +331,9 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
public bool IsSpace(MapIndices indices)
|
public bool IsSpace(MapIndices indices)
|
||||||
{
|
{
|
||||||
// TODO ATMOS use ContentTileDefinition to define in YAML whether or not a tile is considered space
|
// TODO ATMOS use ContentTileDefinition to define in YAML whether or not a tile is considered space
|
||||||
return _grid.GetTileRef(indices).Tile.IsEmpty;
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return default;
|
||||||
|
|
||||||
|
return mapGrid.Grid.GetTileRef(indices).Tile.IsEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<Direction, TileAtmosphere> GetAdjacentTiles(MapIndices indices, bool includeAirBlocked = false)
|
public Dictionary<Direction, TileAtmosphere> GetAdjacentTiles(MapIndices indices, bool includeAirBlocked = false)
|
||||||
@@ -334,7 +343,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
{
|
{
|
||||||
var side = indices.Offset(dir);
|
var side = indices.Offset(dir);
|
||||||
var tile = GetTile(side);
|
var tile = GetTile(side);
|
||||||
if(tile?.Air != null || includeAirBlocked)
|
if (tile != null && (tile.Air != null || includeAirBlocked))
|
||||||
sides[dir] = tile;
|
sides[dir] = tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +358,9 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public float GetVolumeForCells(int cellCount)
|
public float GetVolumeForCells(int cellCount)
|
||||||
{
|
{
|
||||||
return _grid.TileSize * cellCount * Atmospherics.CellVolume;
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return default;
|
||||||
|
|
||||||
|
return mapGrid.Grid.TileSize * cellCount * Atmospherics.CellVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -509,9 +520,11 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AirtightComponent GetObstructingComponent(MapIndices indices)
|
private AirtightComponent? GetObstructingComponent(MapIndices indices)
|
||||||
{
|
{
|
||||||
foreach (var v in _grid.GetSnapGridCell(indices, SnapGridOffset.Center))
|
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return default;
|
||||||
|
|
||||||
|
foreach (var v in mapGrid.Grid.GetSnapGridCell(indices, SnapGridOffset.Center))
|
||||||
{
|
{
|
||||||
if (v.Owner.TryGetComponent<AirtightComponent>(out var ac))
|
if (v.Owner.TryGetComponent<AirtightComponent>(out var ac))
|
||||||
return ac;
|
return ac;
|
||||||
@@ -534,22 +547,24 @@ namespace Content.Server.GameObjects.Components.Atmos
|
|||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
base.ExposeData(serializer);
|
base.ExposeData(serializer);
|
||||||
if (serializer.Reading)
|
if (serializer.Reading &&
|
||||||
|
Owner.TryGetComponent(out IMapGridComponent? mapGrid))
|
||||||
{
|
{
|
||||||
var gridId = Owner.GetComponent<IMapGridComponent>().Grid.Index;
|
var gridId = mapGrid.Grid.Index;
|
||||||
|
|
||||||
if (!serializer.TryReadDataField("uniqueMixes", out List<GasMixture> uniqueMixes) ||
|
if (!serializer.TryReadDataField("uniqueMixes", out List<GasMixture>? uniqueMixes) ||
|
||||||
!serializer.TryReadDataField("tiles", out Dictionary<MapIndices, int> tiles))
|
!serializer.TryReadDataField("tiles", out Dictionary<MapIndices, int>? tiles))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_tiles.Clear();
|
_tiles.Clear();
|
||||||
|
|
||||||
foreach (var (indices, mix) in tiles)
|
foreach (var (indices, mix) in tiles!)
|
||||||
{
|
{
|
||||||
_tiles.Add(indices, new TileAtmosphere(this, gridId, indices, (GasMixture)uniqueMixes[mix].Clone()));
|
_tiles.Add(indices, new TileAtmosphere(this, gridId, indices, (GasMixture)uniqueMixes![mix].Clone()));
|
||||||
Invalidate(indices);
|
Invalidate(indices);
|
||||||
}
|
}
|
||||||
} else if (serializer.Writing)
|
}
|
||||||
|
else if (serializer.Writing)
|
||||||
{
|
{
|
||||||
var uniqueMixes = new List<GasMixture>();
|
var uniqueMixes = new List<GasMixture>();
|
||||||
var uniqueMixHash = new Dictionary<GasMixture, int>();
|
var uniqueMixHash = new Dictionary<GasMixture, int>();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
#nullable enable
|
||||||
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
@@ -19,18 +20,13 @@ namespace Content.Server.GameObjects.Components.BarSign
|
|||||||
{
|
{
|
||||||
public override string Name => "BarSign";
|
public override string Name => "BarSign";
|
||||||
|
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||||
[Dependency] private readonly IRobustRandom _robustRandom;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private string _currentSign;
|
private string? _currentSign;
|
||||||
|
|
||||||
private PowerReceiverComponent _power;
|
|
||||||
private SpriteComponent _sprite;
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public string CurrentSign
|
public string? CurrentSign
|
||||||
{
|
{
|
||||||
get => _currentSign;
|
get => _currentSign;
|
||||||
set
|
set
|
||||||
@@ -40,6 +36,8 @@ namespace Content.Server.GameObjects.Components.BarSign
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
|
|
||||||
private void UpdateSignInfo()
|
private void UpdateSignInfo()
|
||||||
{
|
{
|
||||||
if (_currentSign == null)
|
if (_currentSign == null)
|
||||||
@@ -53,15 +51,18 @@ namespace Content.Server.GameObjects.Components.BarSign
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_power.Powered)
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
{
|
{
|
||||||
_sprite.LayerSetState(0, "empty");
|
if (!Powered)
|
||||||
_sprite.LayerSetShader(0, "shaded");
|
{
|
||||||
|
sprite.LayerSetState(0, "empty");
|
||||||
|
sprite.LayerSetShader(0, "shaded");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_sprite.LayerSetState(0, prototype.Icon);
|
sprite.LayerSetState(0, prototype.Icon);
|
||||||
_sprite.LayerSetShader(0, "unshaded");
|
sprite.LayerSetShader(0, "unshaded");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(prototype.Name))
|
if (!string.IsNullOrEmpty(prototype.Name))
|
||||||
@@ -80,21 +81,25 @@ namespace Content.Server.GameObjects.Components.BarSign
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_power = Owner.GetComponent<PowerReceiverComponent>();
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
_sprite = Owner.GetComponent<SpriteComponent>();
|
{
|
||||||
|
receiver.OnPowerStateChanged += PowerOnOnPowerStateChanged;
|
||||||
_power.OnPowerStateChanged += PowerOnOnPowerStateChanged;
|
}
|
||||||
|
|
||||||
UpdateSignInfo();
|
UpdateSignInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
_power.OnPowerStateChanged -= PowerOnOnPowerStateChanged;
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
|
{
|
||||||
|
receiver.OnPowerStateChanged -= PowerOnOnPowerStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PowerOnOnPowerStateChanged(object sender, PowerStateEventArgs e)
|
private void PowerOnOnPowerStateChanged(object? sender, PowerStateEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateSignInfo();
|
UpdateSignInfo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
using Content.Server.Body;
|
using Content.Server.Body;
|
||||||
using Content.Shared.Body.Scanner;
|
using Content.Shared.Body.Scanner;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Body
|
namespace Content.Server.GameObjects.Components.Body
|
||||||
{
|
{
|
||||||
@@ -12,32 +15,44 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class BodyScannerComponent : Component, IActivate
|
public class BodyScannerComponent : Component, IActivate
|
||||||
{
|
{
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
public sealed override string Name => "BodyScanner";
|
public sealed override string Name => "BodyScanner";
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(BodyScannerUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor) ||
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor) ||
|
||||||
actor.playerSession.AttachedEntity == null)
|
actor.playerSession.AttachedEntity == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor.playerSession.AttachedEntity.TryGetComponent(out BodyManagerComponent attempt))
|
if (actor.playerSession.AttachedEntity.TryGetComponent(out BodyManagerComponent? attempt))
|
||||||
{
|
{
|
||||||
var state = InterfaceState(attempt.Template, attempt.Parts);
|
var state = InterfaceState(attempt.Template, attempt.Parts);
|
||||||
_userInterface.SetState(state);
|
UserInterface?.SetState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(BodyScannerUiKey.Key);
|
if (UserInterface == null)
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
{
|
||||||
|
Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} doesn't have a {nameof(ServerUserInterfaceComponent)}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg) { }
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg) { }
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Body.Circulatory;
|
using Content.Server.GameObjects.Components.Body.Circulatory;
|
||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.GameObjects.Components.Nutrition;
|
using Content.Shared.GameObjects.Components.Nutrition;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
@@ -20,24 +19,20 @@ namespace Content.Server.GameObjects.Components.Body.Digestive
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class StomachComponent : SharedStomachComponent
|
public class StomachComponent : SharedStomachComponent
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Max volume of internal solution storage
|
/// Max volume of internal solution storage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReagentUnit MaxVolume
|
public ReagentUnit MaxVolume
|
||||||
{
|
{
|
||||||
get => _stomachContents.MaxVolume;
|
get => Owner.TryGetComponent(out SolutionComponent? solution) ? solution.MaxVolume : ReagentUnit.Zero;
|
||||||
set => _stomachContents.MaxVolume = value;
|
set
|
||||||
|
{
|
||||||
|
if (Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
solution.MaxVolume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Internal solution storage
|
|
||||||
/// </summary>
|
|
||||||
[ViewVariables]
|
|
||||||
private SolutionComponent _stomachContents;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initial internal solution storage volume
|
/// Initial internal solution storage volume
|
||||||
@@ -68,20 +63,29 @@ namespace Content.Server.GameObjects.Components.Body.Digestive
|
|||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
|
|
||||||
_stomachContents = Owner.GetComponent<SolutionComponent>();
|
if (!Owner.EnsureComponent(out SolutionComponent solution))
|
||||||
_stomachContents.MaxVolume = _initialMaxVolume;
|
{
|
||||||
|
Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} didn't have a {nameof(SolutionComponent)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
solution.MaxVolume = _initialMaxVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryTransferSolution(Solution solution)
|
public bool TryTransferSolution(Solution solution)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out SolutionComponent? solutionComponent))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: For now no partial transfers. Potentially change by design
|
// TODO: For now no partial transfers. Potentially change by design
|
||||||
if (solution.TotalVolume + _stomachContents.CurrentVolume > _stomachContents.MaxVolume)
|
if (solution.TotalVolume + solutionComponent.CurrentVolume > solutionComponent.MaxVolume)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add solution to _stomachContents
|
// Add solution to _stomachContents
|
||||||
_stomachContents.TryAddSolution(solution, false, true);
|
solutionComponent.TryAddSolution(solution, false, true);
|
||||||
// Add each reagent to _reagentDeltas. Used to track how long each reagent has been in the stomach
|
// Add each reagent to _reagentDeltas. Used to track how long each reagent has been in the stomach
|
||||||
foreach (var reagent in solution.Contents)
|
foreach (var reagent in solution.Contents)
|
||||||
{
|
{
|
||||||
@@ -99,7 +103,8 @@ namespace Content.Server.GameObjects.Components.Body.Digestive
|
|||||||
/// <param name="frameTime">The time since the last update in seconds.</param>
|
/// <param name="frameTime">The time since the last update in seconds.</param>
|
||||||
public void Update(float frameTime)
|
public void Update(float frameTime)
|
||||||
{
|
{
|
||||||
if (!Owner.TryGetComponent(out BloodstreamComponent bloodstream))
|
if (!Owner.TryGetComponent(out SolutionComponent? solutionComponent) ||
|
||||||
|
!Owner.TryGetComponent(out BloodstreamComponent? bloodstream))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -114,7 +119,7 @@ namespace Content.Server.GameObjects.Components.Body.Digestive
|
|||||||
delta.Increment(frameTime);
|
delta.Increment(frameTime);
|
||||||
if (delta.Lifetime > _digestionDelay)
|
if (delta.Lifetime > _digestionDelay)
|
||||||
{
|
{
|
||||||
_stomachContents.TryRemoveReagent(delta.ReagentId, delta.Quantity);
|
solutionComponent.TryRemoveReagent(delta.ReagentId, delta.Quantity);
|
||||||
transferSolution.AddReagent(delta.ReagentId, delta.Quantity);
|
transferSolution.AddReagent(delta.ReagentId, delta.Quantity);
|
||||||
_reagentDeltas.Remove(delta);
|
_reagentDeltas.Remove(delta);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -6,6 +7,7 @@ using Content.Server.Body;
|
|||||||
using Content.Shared.Body.Surgery;
|
using Content.Shared.Body.Surgery;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
@@ -21,20 +23,23 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class DroppedBodyPartComponent : Component, IAfterInteract, IBodyPartContainer
|
public class DroppedBodyPartComponent : Component, IAfterInteract, IBodyPartContainer
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager = default!;
|
||||||
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private readonly Dictionary<int, object> _optionsCache = new Dictionary<int, object>();
|
private readonly Dictionary<int, object> _optionsCache = new Dictionary<int, object>();
|
||||||
private BodyManagerComponent _bodyManagerComponentCache;
|
private BodyManagerComponent? _bodyManagerComponentCache;
|
||||||
private int _idHash;
|
private int _idHash;
|
||||||
private IEntity _performerCache;
|
private IEntity? _performerCache;
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
|
|
||||||
public sealed override string Name => "DroppedBodyPart";
|
public sealed override string Name => "DroppedBodyPart";
|
||||||
|
|
||||||
[ViewVariables] public BodyPart ContainedBodyPart { get; private set; }
|
[ViewVariables] public BodyPart ContainedBodyPart { get; private set; } = default!;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(GenericSurgeryUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
@@ -48,7 +53,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
_performerCache = null;
|
_performerCache = null;
|
||||||
_bodyManagerComponentCache = null;
|
_bodyManagerComponentCache = null;
|
||||||
|
|
||||||
if (eventArgs.Target.TryGetComponent(out BodyManagerComponent bodyManager))
|
if (eventArgs.Target.TryGetComponent(out BodyManagerComponent? bodyManager))
|
||||||
{
|
{
|
||||||
SendBodySlotListToUser(eventArgs, bodyManager);
|
SendBodySlotListToUser(eventArgs, bodyManager);
|
||||||
}
|
}
|
||||||
@@ -58,9 +63,10 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
if (UserInterface != null)
|
||||||
.GetBoundUserInterface(GenericSurgeryUiKey.Key);
|
{
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TransferBodyPartData(BodyPart data)
|
public void TransferBodyPartData(BodyPart data)
|
||||||
@@ -68,7 +74,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
ContainedBodyPart = data;
|
ContainedBodyPart = data;
|
||||||
Owner.Name = Loc.GetString(ContainedBodyPart.Name);
|
Owner.Name = Loc.GetString(ContainedBodyPart.Name);
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out SpriteComponent component))
|
if (Owner.TryGetComponent(out SpriteComponent? component))
|
||||||
{
|
{
|
||||||
component.LayerSetRSI(0, data.RSIPath);
|
component.LayerSetRSI(0, data.RSIPath);
|
||||||
component.LayerSetState(0, data.RSIState);
|
component.LayerSetState(0, data.RSIState);
|
||||||
@@ -91,7 +97,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
foreach (var slot in unoccupiedSlots)
|
foreach (var slot in unoccupiedSlots)
|
||||||
{
|
{
|
||||||
if (!bodyManager.TryGetSlotType(slot, out var typeResult) ||
|
if (!bodyManager.TryGetSlotType(slot, out var typeResult) ||
|
||||||
typeResult != ContainedBodyPart.PartType ||
|
typeResult != ContainedBodyPart?.PartType ||
|
||||||
!bodyManager.TryGetBodyPartConnections(slot, out var parts))
|
!bodyManager.TryGetBodyPartConnections(slot, out var parts))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -129,7 +135,18 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleReceiveBodyPartSlot(int key)
|
private void HandleReceiveBodyPartSlot(int key)
|
||||||
{
|
{
|
||||||
CloseSurgeryUI(_performerCache.GetComponent<BasicActorComponent>().playerSession);
|
if (_performerCache == null ||
|
||||||
|
!_performerCache.TryGetComponent(out IActorComponent? actor))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseSurgeryUI(actor.playerSession);
|
||||||
|
|
||||||
|
if (_bodyManagerComponentCache == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
||||||
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
||||||
@@ -138,34 +155,42 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
Loc.GetString("You see no useful way to attach {0:theName} anymore.", Owner));
|
Loc.GetString("You see no useful way to attach {0:theName} anymore.", Owner));
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = targetObject as string;
|
var target = (string) targetObject!;
|
||||||
|
string message;
|
||||||
|
|
||||||
|
if (_bodyManagerComponentCache.InstallDroppedBodyPart(this, target))
|
||||||
|
{
|
||||||
|
message = Loc.GetString("You attach {0:theName}.", ContainedBodyPart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = Loc.GetString("You can't attach it!");
|
||||||
|
}
|
||||||
|
|
||||||
_sharedNotifyManager.PopupMessage(
|
_sharedNotifyManager.PopupMessage(
|
||||||
_bodyManagerComponentCache.Owner,
|
_bodyManagerComponentCache.Owner,
|
||||||
_performerCache,
|
_performerCache,
|
||||||
!_bodyManagerComponentCache.InstallDroppedBodyPart(this, target)
|
message);
|
||||||
? Loc.GetString("You can't attach it!")
|
|
||||||
: Loc.GetString("You attach {0:theName}.", ContainedBodyPart));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenSurgeryUI(IPlayerSession session)
|
private void OpenSurgeryUI(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSurgeryUIBodyPartSlotRequest(IPlayerSession session, Dictionary<string, int> options)
|
private void UpdateSurgeryUIBodyPartSlotRequest(IPlayerSession session, Dictionary<string, int> options)
|
||||||
{
|
{
|
||||||
_userInterface.SendMessage(new RequestBodyPartSlotSurgeryUIMessage(options), session);
|
UserInterface?.SendMessage(new RequestBodyPartSlotSurgeryUIMessage(options), session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseSurgeryUI(IPlayerSession session)
|
private void CloseSurgeryUI(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Close(session);
|
UserInterface?.Close(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseAllSurgeryUIs()
|
private void CloseAllSurgeryUIs()
|
||||||
{
|
{
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.Body;
|
using Content.Server.Body;
|
||||||
using Content.Server.Body.Mechanisms;
|
using Content.Server.Body.Mechanisms;
|
||||||
@@ -8,14 +8,15 @@ using Content.Shared.Interfaces;
|
|||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Body
|
namespace Content.Server.GameObjects.Components.Body
|
||||||
@@ -26,24 +27,27 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class DroppedMechanismComponent : Component, IAfterInteract
|
public class DroppedMechanismComponent : Component, IAfterInteract
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager = default!;
|
||||||
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private IPrototypeManager _prototypeManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public sealed override string Name => "DroppedMechanism";
|
public sealed override string Name => "DroppedMechanism";
|
||||||
|
|
||||||
private readonly Dictionary<int, object> _optionsCache = new Dictionary<int, object>();
|
private readonly Dictionary<int, object> _optionsCache = new Dictionary<int, object>();
|
||||||
|
|
||||||
private BodyManagerComponent _bodyManagerComponentCache;
|
private BodyManagerComponent? _bodyManagerComponentCache;
|
||||||
|
|
||||||
private int _idHash;
|
private int _idHash;
|
||||||
|
|
||||||
private IEntity _performerCache;
|
private IEntity? _performerCache;
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
[ViewVariables] public Mechanism ContainedMechanism { get; private set; } = default!;
|
||||||
|
|
||||||
[ViewVariables] public Mechanism ContainedMechanism { get; private set; }
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(GenericSurgeryUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
@@ -63,12 +67,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
}
|
}
|
||||||
else if (eventArgs.Target.TryGetComponent<DroppedBodyPartComponent>(out var droppedBodyPart))
|
else if (eventArgs.Target.TryGetComponent<DroppedBodyPartComponent>(out var droppedBodyPart))
|
||||||
{
|
{
|
||||||
if (droppedBodyPart.ContainedBodyPart == null)
|
DebugTools.AssertNotNull(droppedBodyPart.ContainedBodyPart);
|
||||||
{
|
|
||||||
Logger.Debug(
|
|
||||||
"Installing a mechanism was attempted on an IEntity with a DroppedBodyPartComponent that doesn't have a BodyPart in it!");
|
|
||||||
throw new InvalidOperationException("A DroppedBodyPartComponent exists without a BodyPart in it!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!droppedBodyPart.ContainedBodyPart.TryInstallDroppedMechanism(this))
|
if (!droppedBodyPart.ContainedBodyPart.TryInstallDroppedMechanism(this))
|
||||||
{
|
{
|
||||||
@@ -82,9 +81,10 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
if (UserInterface != null)
|
||||||
.GetBoundUserInterface(GenericSurgeryUiKey.Key);
|
{
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeDroppedMechanism(Mechanism data)
|
public void InitializeDroppedMechanism(Mechanism data)
|
||||||
@@ -92,7 +92,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
ContainedMechanism = data;
|
ContainedMechanism = data;
|
||||||
Owner.Name = Loc.GetString(ContainedMechanism.Name);
|
Owner.Name = Loc.GetString(ContainedMechanism.Name);
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out SpriteComponent component))
|
if (Owner.TryGetComponent(out SpriteComponent? component))
|
||||||
{
|
{
|
||||||
component.LayerSetRSI(0, data.RSIPath);
|
component.LayerSetRSI(0, data.RSIPath);
|
||||||
component.LayerSetState(0, data.RSIState);
|
component.LayerSetState(0, data.RSIState);
|
||||||
@@ -111,7 +111,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
|
|
||||||
if (serializer.Reading && debugLoadMechanismData != "")
|
if (serializer.Reading && debugLoadMechanismData != "")
|
||||||
{
|
{
|
||||||
_prototypeManager.TryIndex(debugLoadMechanismData, out MechanismPrototype data);
|
_prototypeManager.TryIndex(debugLoadMechanismData!, out MechanismPrototype data);
|
||||||
|
|
||||||
var mechanism = new Mechanism(data);
|
var mechanism = new Mechanism(data);
|
||||||
mechanism.EnsureInitialize();
|
mechanism.EnsureInitialize();
|
||||||
@@ -155,7 +155,18 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleReceiveBodyPart(int key)
|
private void HandleReceiveBodyPart(int key)
|
||||||
{
|
{
|
||||||
CloseSurgeryUI(_performerCache.GetComponent<BasicActorComponent>().playerSession);
|
if (_performerCache == null ||
|
||||||
|
!_performerCache.TryGetComponent(out IActorComponent? actor))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseSurgeryUI(actor.playerSession);
|
||||||
|
|
||||||
|
if (_bodyManagerComponentCache == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
||||||
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
||||||
@@ -165,36 +176,37 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = targetObject as BodyPart;
|
var target = (BodyPart) targetObject;
|
||||||
|
var message = target.TryInstallDroppedMechanism(this)
|
||||||
|
? Loc.GetString("You jam the {0} inside {1:them}.", ContainedMechanism.Name, _performerCache)
|
||||||
|
: Loc.GetString("You can't fit it in!");
|
||||||
|
|
||||||
_sharedNotifyManager.PopupMessage(
|
_sharedNotifyManager.PopupMessage(
|
||||||
_bodyManagerComponentCache.Owner,
|
_bodyManagerComponentCache.Owner,
|
||||||
_performerCache,
|
_performerCache,
|
||||||
!target.TryInstallDroppedMechanism(this)
|
message);
|
||||||
? Loc.GetString("You can't fit it in!")
|
|
||||||
: Loc.GetString("You jam the {1} inside {0:them}.", _performerCache, ContainedMechanism.Name));
|
|
||||||
|
|
||||||
// TODO: {1:theName}
|
// TODO: {1:theName}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenSurgeryUI(IPlayerSession session)
|
private void OpenSurgeryUI(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSurgeryUIBodyPartRequest(IPlayerSession session, Dictionary<string, int> options)
|
private void UpdateSurgeryUIBodyPartRequest(IPlayerSession session, Dictionary<string, int> options)
|
||||||
{
|
{
|
||||||
_userInterface.SendMessage(new RequestBodyPartSurgeryUIMessage(options), session);
|
UserInterface?.SendMessage(new RequestBodyPartSurgeryUIMessage(options), session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseSurgeryUI(IPlayerSession session)
|
private void CloseSurgeryUI(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Close(session);
|
UserInterface?.Close(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseAllSurgeryUIs()
|
private void CloseAllSurgeryUIs()
|
||||||
{
|
{
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.Body;
|
using Content.Server.Body;
|
||||||
using Content.Server.Body.Mechanisms;
|
using Content.Server.Body.Mechanisms;
|
||||||
@@ -18,6 +19,8 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Body
|
namespace Content.Server.GameObjects.Components.Body
|
||||||
{
|
{
|
||||||
@@ -30,9 +33,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class SurgeryToolComponent : Component, ISurgeon, IAfterInteract
|
public class SurgeryToolComponent : Component, ISurgeon, IAfterInteract
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager = default!;
|
||||||
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "SurgeryTool";
|
public override string Name => "SurgeryTool";
|
||||||
public override uint? NetID => ContentNetIDs.SURGERY;
|
public override uint? NetID => ContentNetIDs.SURGERY;
|
||||||
@@ -41,17 +42,22 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
|
|
||||||
private float _baseOperateTime;
|
private float _baseOperateTime;
|
||||||
|
|
||||||
private BodyManagerComponent _bodyManagerComponentCache;
|
private BodyManagerComponent? _bodyManagerComponentCache;
|
||||||
|
|
||||||
private ISurgeon.MechanismRequestCallback _callbackCache;
|
private ISurgeon.MechanismRequestCallback? _callbackCache;
|
||||||
|
|
||||||
private int _idHash;
|
private int _idHash;
|
||||||
|
|
||||||
private IEntity _performerCache;
|
private IEntity? _performerCache;
|
||||||
|
|
||||||
private SurgeryType _surgeryType;
|
private SurgeryType _surgeryType;
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(GenericSurgeryUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
@@ -60,7 +66,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -73,7 +79,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
_callbackCache = null;
|
_callbackCache = null;
|
||||||
|
|
||||||
// Attempt surgery on a BodyManagerComponent by sending a list of operable BodyParts to the client to choose from
|
// Attempt surgery on a BodyManagerComponent by sending a list of operable BodyParts to the client to choose from
|
||||||
if (eventArgs.Target.TryGetComponent(out BodyManagerComponent body))
|
if (eventArgs.Target.TryGetComponent(out BodyManagerComponent? body))
|
||||||
{
|
{
|
||||||
// Create dictionary to send to client (text to be shown : data sent back if selected)
|
// Create dictionary to send to client (text to be shown : data sent back if selected)
|
||||||
var toSend = new Dictionary<string, int>();
|
var toSend = new Dictionary<string, int>();
|
||||||
@@ -105,13 +111,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
// Attempt surgery on a DroppedBodyPart - there's only one possible target so no need for selection UI
|
// Attempt surgery on a DroppedBodyPart - there's only one possible target so no need for selection UI
|
||||||
_performerCache = eventArgs.User;
|
_performerCache = eventArgs.User;
|
||||||
|
|
||||||
if (droppedBodyPart.ContainedBodyPart == null)
|
DebugTools.AssertNotNull(droppedBodyPart.ContainedBodyPart);
|
||||||
{
|
|
||||||
// Throw error if the DroppedBodyPart has no data in it.
|
|
||||||
Logger.Debug(
|
|
||||||
"Surgery was attempted on an IEntity with a DroppedBodyPartComponent that doesn't have a BodyPart in it!");
|
|
||||||
throw new InvalidOperationException("A DroppedBodyPartComponent exists without a BodyPart in it!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If surgery can be performed...
|
// If surgery can be performed...
|
||||||
if (!droppedBodyPart.ContainedBodyPart.SurgeryCheck(_surgeryType))
|
if (!droppedBodyPart.ContainedBodyPart.SurgeryCheck(_surgeryType))
|
||||||
@@ -144,7 +144,7 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
toSend.Add(mechanism.Name, _idHash++);
|
toSend.Add(mechanism.Name, _idHash++);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_optionsCache.Count > 0)
|
if (_optionsCache.Count > 0 && _performerCache != null)
|
||||||
{
|
{
|
||||||
OpenSurgeryUI(_performerCache.GetComponent<BasicActorComponent>().playerSession);
|
OpenSurgeryUI(_performerCache.GetComponent<BasicActorComponent>().playerSession);
|
||||||
UpdateSurgeryUIMechanismRequest(_performerCache.GetComponent<BasicActorComponent>().playerSession,
|
UpdateSurgeryUIMechanismRequest(_performerCache.GetComponent<BasicActorComponent>().playerSession,
|
||||||
@@ -162,34 +162,35 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
if (UserInterface != null)
|
||||||
.GetBoundUserInterface(GenericSurgeryUiKey.Key);
|
{
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenSurgeryUI(IPlayerSession session)
|
private void OpenSurgeryUI(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSurgeryUIBodyPartRequest(IPlayerSession session, Dictionary<string, int> options)
|
private void UpdateSurgeryUIBodyPartRequest(IPlayerSession session, Dictionary<string, int> options)
|
||||||
{
|
{
|
||||||
_userInterface.SendMessage(new RequestBodyPartSurgeryUIMessage(options), session);
|
UserInterface?.SendMessage(new RequestBodyPartSurgeryUIMessage(options), session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSurgeryUIMechanismRequest(IPlayerSession session, Dictionary<string, int> options)
|
private void UpdateSurgeryUIMechanismRequest(IPlayerSession session, Dictionary<string, int> options)
|
||||||
{
|
{
|
||||||
_userInterface.SendMessage(new RequestMechanismSurgeryUIMessage(options), session);
|
UserInterface?.SendMessage(new RequestMechanismSurgeryUIMessage(options), session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseSurgeryUI(IPlayerSession session)
|
private void CloseSurgeryUI(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Close(session);
|
UserInterface?.Close(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseAllSurgeryUIs()
|
private void CloseAllSurgeryUIs()
|
||||||
{
|
{
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
||||||
@@ -211,14 +212,22 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleReceiveBodyPart(int key)
|
private void HandleReceiveBodyPart(int key)
|
||||||
{
|
{
|
||||||
CloseSurgeryUI(_performerCache.GetComponent<BasicActorComponent>().playerSession);
|
if (_performerCache == null ||
|
||||||
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
!_performerCache.TryGetComponent(out IActorComponent? actor))
|
||||||
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
|
||||||
{
|
{
|
||||||
SendNoUsefulWayToUseAnymorePopup();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = targetObject as BodyPart;
|
CloseSurgeryUI(actor.playerSession);
|
||||||
|
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
||||||
|
if (!_optionsCache.TryGetValue(key, out var targetObject) ||
|
||||||
|
_bodyManagerComponentCache == null)
|
||||||
|
{
|
||||||
|
SendNoUsefulWayToUseAnymorePopup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var target = (BodyPart) targetObject!;
|
||||||
|
|
||||||
if (!target.AttemptSurgery(_surgeryType, _bodyManagerComponentCache, this, _performerCache))
|
if (!target.AttemptSurgery(_surgeryType, _bodyManagerComponentCache, this, _performerCache))
|
||||||
{
|
{
|
||||||
@@ -233,19 +242,27 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
private void HandleReceiveMechanism(int key)
|
private void HandleReceiveMechanism(int key)
|
||||||
{
|
{
|
||||||
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
||||||
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
if (!_optionsCache.TryGetValue(key, out var targetObject) ||
|
||||||
|
_performerCache == null ||
|
||||||
|
!_performerCache.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
SendNoUsefulWayToUseAnymorePopup();
|
SendNoUsefulWayToUseAnymorePopup();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = targetObject as Mechanism;
|
var target = targetObject as Mechanism;
|
||||||
|
|
||||||
CloseSurgeryUI(_performerCache.GetComponent<BasicActorComponent>().playerSession);
|
CloseSurgeryUI(actor.playerSession);
|
||||||
_callbackCache(target, _bodyManagerComponentCache, this, _performerCache);
|
_callbackCache?.Invoke(target, _bodyManagerComponentCache, this, _performerCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendNoUsefulWayToUsePopup()
|
private void SendNoUsefulWayToUsePopup()
|
||||||
{
|
{
|
||||||
|
if (_bodyManagerComponentCache == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_sharedNotifyManager.PopupMessage(
|
_sharedNotifyManager.PopupMessage(
|
||||||
_bodyManagerComponentCache.Owner,
|
_bodyManagerComponentCache.Owner,
|
||||||
_performerCache,
|
_performerCache,
|
||||||
@@ -254,6 +271,11 @@ namespace Content.Server.GameObjects.Components.Body
|
|||||||
|
|
||||||
private void SendNoUsefulWayToUseAnymorePopup()
|
private void SendNoUsefulWayToUseAnymorePopup()
|
||||||
{
|
{
|
||||||
|
if (_bodyManagerComponentCache == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_sharedNotifyManager.PopupMessage(
|
_sharedNotifyManager.PopupMessage(
|
||||||
_bodyManagerComponentCache.Owner,
|
_bodyManagerComponentCache.Owner,
|
||||||
_performerCache,
|
_performerCache,
|
||||||
|
|||||||
@@ -34,13 +34,11 @@ namespace Content.Server.GameObjects.Components.Buckle
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class BuckleComponent : SharedBuckleComponent, IInteractHand, IDragDrop
|
public class BuckleComponent : SharedBuckleComponent, IInteractHand, IDragDrop
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private int _size;
|
private int _size;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Robust.Server.Interfaces.GameObjects;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
@@ -19,21 +20,11 @@ namespace Content.Server.GameObjects.Components.Cargo
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class CargoConsoleComponent : SharedCargoConsoleComponent, IActivate
|
public class CargoConsoleComponent : SharedCargoConsoleComponent, IActivate
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly ICargoOrderDataManager _cargoOrderDataManager = default!;
|
[Dependency] private readonly ICargoOrderDataManager _cargoOrderDataManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public int Points = 1000;
|
public int Points = 1000;
|
||||||
|
|
||||||
private BoundUserInterface _userInterface = default!;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public GalacticMarketComponent Market { get; private set; } = default!;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public CargoOrderDatabaseComponent Orders { get; private set; } = default!;
|
|
||||||
|
|
||||||
private CargoBankAccount? _bankAccount;
|
private CargoBankAccount? _bankAccount;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
@@ -65,22 +56,49 @@ namespace Content.Server.GameObjects.Components.Cargo
|
|||||||
|
|
||||||
private bool _requestOnly = false;
|
private bool _requestOnly = false;
|
||||||
|
|
||||||
private PowerReceiverComponent _powerReceiver = default!;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private bool Powered => _powerReceiver.Powered;
|
|
||||||
private CargoConsoleSystem _cargoConsoleSystem = default!;
|
private CargoConsoleSystem _cargoConsoleSystem = default!;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(CargoConsoleUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
Market = Owner.GetComponent<GalacticMarketComponent>();
|
|
||||||
Orders = Owner.GetComponent<CargoOrderDatabaseComponent>();
|
if (!Owner.EnsureComponent(out GalacticMarketComponent _))
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(CargoConsoleUiKey.Key);
|
{
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} had no {nameof(GalacticMarketComponent)}");
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
}
|
||||||
|
|
||||||
|
if (!Owner.EnsureComponent(out CargoOrderDatabaseComponent _))
|
||||||
|
{
|
||||||
|
Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} had no {nameof(GalacticMarketComponent)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserInterface != null)
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
_cargoConsoleSystem = EntitySystem.Get<CargoConsoleSystem>();
|
_cargoConsoleSystem = EntitySystem.Get<CargoConsoleSystem>();
|
||||||
BankAccount = _cargoConsoleSystem.StationAccount;
|
BankAccount = _cargoConsoleSystem.StationAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
if (UserInterface != null)
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads data from YAML
|
/// Reads data from YAML
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -93,8 +111,13 @@ namespace Content.Server.GameObjects.Components.Cargo
|
|||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out CargoOrderDatabaseComponent? orders))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var message = serverMsg.Message;
|
var message = serverMsg.Message;
|
||||||
if (!Orders.ConnectedToDatabase)
|
if (!orders.ConnectedToDatabase)
|
||||||
return;
|
return;
|
||||||
if (!Powered)
|
if (!Powered)
|
||||||
return;
|
return;
|
||||||
@@ -107,39 +130,39 @@ namespace Content.Server.GameObjects.Components.Cargo
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cargoOrderDataManager.AddOrder(Orders.Database.Id, msg.Requester, msg.Reason, msg.ProductId, msg.Amount, _bankAccount.Id);
|
_cargoOrderDataManager.AddOrder(orders.Database.Id, msg.Requester, msg.Reason, msg.ProductId, msg.Amount, _bankAccount.Id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CargoConsoleRemoveOrderMessage msg:
|
case CargoConsoleRemoveOrderMessage msg:
|
||||||
{
|
{
|
||||||
_cargoOrderDataManager.RemoveOrder(Orders.Database.Id, msg.OrderNumber);
|
_cargoOrderDataManager.RemoveOrder(orders.Database.Id, msg.OrderNumber);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CargoConsoleApproveOrderMessage msg:
|
case CargoConsoleApproveOrderMessage msg:
|
||||||
{
|
{
|
||||||
if (_requestOnly ||
|
if (_requestOnly ||
|
||||||
!Orders.Database.TryGetOrder(msg.OrderNumber, out var order) ||
|
!orders.Database.TryGetOrder(msg.OrderNumber, out var order) ||
|
||||||
_bankAccount == null)
|
_bankAccount == null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_prototypeManager.TryIndex(order.ProductId, out CargoProductPrototype product);
|
_prototypeManager.TryIndex(order.ProductId, out CargoProductPrototype product);
|
||||||
if (product == null)
|
if (product == null!)
|
||||||
break;
|
break;
|
||||||
var capacity = _cargoOrderDataManager.GetCapacity(Orders.Database.Id);
|
var capacity = _cargoOrderDataManager.GetCapacity(orders.Database.Id);
|
||||||
if (capacity.CurrentCapacity == capacity.MaxCapacity)
|
if (capacity.CurrentCapacity == capacity.MaxCapacity)
|
||||||
break;
|
break;
|
||||||
if (!_cargoConsoleSystem.ChangeBalance(_bankAccount.Id, (-product.PointCost) * order.Amount))
|
if (!_cargoConsoleSystem.ChangeBalance(_bankAccount.Id, (-product.PointCost) * order.Amount))
|
||||||
break;
|
break;
|
||||||
_cargoOrderDataManager.ApproveOrder(Orders.Database.Id, msg.OrderNumber);
|
_cargoOrderDataManager.ApproveOrder(orders.Database.Id, msg.OrderNumber);
|
||||||
UpdateUIState();
|
UpdateUIState();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CargoConsoleShuttleMessage _:
|
case CargoConsoleShuttleMessage _:
|
||||||
{
|
{
|
||||||
var approvedOrders = _cargoOrderDataManager.RemoveAndGetApprovedFrom(Orders.Database);
|
var approvedOrders = _cargoOrderDataManager.RemoveAndGetApprovedFrom(orders.Database);
|
||||||
Orders.Database.ClearOrderCapacity();
|
orders.Database.ClearOrderCapacity();
|
||||||
// TODO replace with shuttle code
|
// TODO replace with shuttle code
|
||||||
|
|
||||||
// TEMPORARY loop for spawning stuff on top of console
|
// TEMPORARY loop for spawning stuff on top of console
|
||||||
@@ -166,12 +189,12 @@ namespace Content.Server.GameObjects.Components.Cargo
|
|||||||
if (!Powered)
|
if (!Powered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateUIState()
|
private void UpdateUIState()
|
||||||
{
|
{
|
||||||
if (_bankAccount == null)
|
if (_bankAccount == null || !Owner.IsValid())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -180,7 +203,7 @@ namespace Content.Server.GameObjects.Components.Cargo
|
|||||||
var name = _bankAccount.Name;
|
var name = _bankAccount.Name;
|
||||||
var balance = _bankAccount.Balance;
|
var balance = _bankAccount.Balance;
|
||||||
var capacity = _cargoOrderDataManager.GetCapacity(id);
|
var capacity = _cargoOrderDataManager.GetCapacity(id);
|
||||||
_userInterface.SetState(new CargoConsoleInterfaceState(_requestOnly, id, name, balance, capacity));
|
UserInterface?.SetState(new CargoConsoleInterfaceState(_requestOnly, id, name, balance, capacity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.GUI;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
@@ -40,24 +42,26 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
[ComponentReference(typeof(IInteractUsing))]
|
[ComponentReference(typeof(IInteractUsing))]
|
||||||
public class ChemMasterComponent : SharedChemMasterComponent, IActivate, IInteractUsing, ISolutionChange
|
public class ChemMasterComponent : SharedChemMasterComponent, IActivate, IInteractUsing, ISolutionChange
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
[ViewVariables] private BoundUserInterface _userInterface;
|
[ViewVariables] private ContainerSlot _beakerContainer = default!;
|
||||||
[ViewVariables] private ContainerSlot _beakerContainer;
|
[ViewVariables] private string _packPrototypeId = "";
|
||||||
[ViewVariables] private string _packPrototypeId;
|
|
||||||
|
|
||||||
[ViewVariables] private bool HasBeaker => _beakerContainer.ContainedEntity != null;
|
[ViewVariables] private bool HasBeaker => _beakerContainer.ContainedEntity != null;
|
||||||
|
|
||||||
[ViewVariables] private bool BufferModeTransfer = true;
|
[ViewVariables] private bool _bufferModeTransfer = true;
|
||||||
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private bool Powered => _powerReceiver.Powered;
|
|
||||||
|
|
||||||
private readonly SolutionComponent BufferSolution = new SolutionComponent();
|
private readonly SolutionComponent BufferSolution = new SolutionComponent();
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(ChemMasterUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the serializer how to save/load this components yaml prototype.
|
/// Shows the serializer how to save/load this components yaml prototype.
|
||||||
@@ -77,14 +81,19 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(ChemMasterUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
_beakerContainer =
|
_beakerContainer =
|
||||||
ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-reagentContainerContainer", Owner);
|
ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-reagentContainerContainer", Owner);
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
|
||||||
_powerReceiver.OnPowerStateChanged += OnPowerChanged;
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
|
{
|
||||||
|
receiver.OnPowerStateChanged += OnPowerChanged;
|
||||||
|
}
|
||||||
|
|
||||||
//BufferSolution = Owner.BufferSolution
|
//BufferSolution = Owner.BufferSolution
|
||||||
BufferSolution.Solution = new Solution();
|
BufferSolution.Solution = new Solution();
|
||||||
@@ -93,7 +102,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPowerChanged(object sender, PowerStateEventArgs e)
|
private void OnPowerChanged(object? sender, PowerStateEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
@@ -105,6 +114,11 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// <param name="obj">A user interface message from the client.</param>
|
/// <param name="obj">A user interface message from the client.</param>
|
||||||
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
{
|
{
|
||||||
|
if (obj.Session.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var msg = (UiActionMessage) obj.Message;
|
var msg = (UiActionMessage) obj.Message;
|
||||||
var needsPower = msg.action switch
|
var needsPower = msg.action switch
|
||||||
{
|
{
|
||||||
@@ -124,11 +138,11 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
TransferReagent(msg.id, msg.amount, msg.isBuffer);
|
TransferReagent(msg.id, msg.amount, msg.isBuffer);
|
||||||
break;
|
break;
|
||||||
case UiAction.Transfer:
|
case UiAction.Transfer:
|
||||||
BufferModeTransfer = true;
|
_bufferModeTransfer = true;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
break;
|
break;
|
||||||
case UiAction.Discard:
|
case UiAction.Discard:
|
||||||
BufferModeTransfer = false;
|
_bufferModeTransfer = false;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
break;
|
break;
|
||||||
case UiAction.CreatePills:
|
case UiAction.CreatePills:
|
||||||
@@ -147,7 +161,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="playerEntity">The player entity.</param>
|
/// <param name="playerEntity">The player entity.</param>
|
||||||
/// <returns>Returns true if the entity can use the chem master, and false if it cannot.</returns>
|
/// <returns>Returns true if the entity can use the chem master, and false if it cannot.</returns>
|
||||||
private bool PlayerCanUseChemMaster(IEntity playerEntity, bool needsPower = true)
|
private bool PlayerCanUseChemMaster(IEntity? playerEntity, bool needsPower = true)
|
||||||
{
|
{
|
||||||
//Need player entity to check if they are still able to use the chem master
|
//Need player entity to check if they are still able to use the chem master
|
||||||
if (playerEntity == null)
|
if (playerEntity == null)
|
||||||
@@ -172,18 +186,18 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
if (beaker == null)
|
if (beaker == null)
|
||||||
{
|
{
|
||||||
return new ChemMasterBoundUserInterfaceState(Powered, false, ReagentUnit.New(0), ReagentUnit.New(0),
|
return new ChemMasterBoundUserInterfaceState(Powered, false, ReagentUnit.New(0), ReagentUnit.New(0),
|
||||||
"", Owner.Name, null, BufferSolution.ReagentList.ToList(), BufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume);
|
"", Owner.Name, new List<Solution.ReagentQuantity>(), BufferSolution.ReagentList.ToList(), _bufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
var solution = beaker.GetComponent<SolutionComponent>();
|
var solution = beaker.GetComponent<SolutionComponent>();
|
||||||
return new ChemMasterBoundUserInterfaceState(Powered, true, solution.CurrentVolume, solution.MaxVolume,
|
return new ChemMasterBoundUserInterfaceState(Powered, true, solution.CurrentVolume, solution.MaxVolume,
|
||||||
beaker.Name, Owner.Name, solution.ReagentList.ToList(), BufferSolution.ReagentList.ToList(), BufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume);
|
beaker.Name, Owner.Name, solution.ReagentList.ToList(), BufferSolution.ReagentList.ToList(), _bufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateUserInterface()
|
private void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
var state = GetUserInterfaceState();
|
var state = GetUserInterfaceState();
|
||||||
_userInterface.SetState(state);
|
UserInterface?.SetState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -207,7 +221,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
|
|
||||||
private void TransferReagent(string id, ReagentUnit amount, bool isBuffer)
|
private void TransferReagent(string id, ReagentUnit amount, bool isBuffer)
|
||||||
{
|
{
|
||||||
if (!HasBeaker && BufferModeTransfer) return;
|
if (!HasBeaker && _bufferModeTransfer) return;
|
||||||
var beaker = _beakerContainer.ContainedEntity;
|
var beaker = _beakerContainer.ContainedEntity;
|
||||||
var beakerSolution = beaker.GetComponent<SolutionComponent>();
|
var beakerSolution = beaker.GetComponent<SolutionComponent>();
|
||||||
if (isBuffer)
|
if (isBuffer)
|
||||||
@@ -227,7 +241,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
BufferSolution.Solution.RemoveReagent(id, actualAmount);
|
BufferSolution.Solution.RemoveReagent(id, actualAmount);
|
||||||
if (BufferModeTransfer)
|
if (_bufferModeTransfer)
|
||||||
{
|
{
|
||||||
beakerSolution.Solution.AddReagent(id, actualAmount);
|
beakerSolution.Solution.AddReagent(id, actualAmount);
|
||||||
}
|
}
|
||||||
@@ -351,12 +365,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
||||||
void IActivate.Activate(ActivateEventArgs args)
|
void IActivate.Activate(ActivateEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.User.TryGetComponent(out IActorComponent actor))
|
if (!args.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.User.TryGetComponent(out IHandsComponent hands))
|
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
_localizationManager.GetString("You have no hands."));
|
_localizationManager.GetString("You have no hands."));
|
||||||
@@ -366,7 +380,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
var activeHandEntity = hands.GetActiveHand?.Owner;
|
var activeHandEntity = hands.GetActiveHand?.Owner;
|
||||||
if (activeHandEntity == null)
|
if (activeHandEntity == null)
|
||||||
{
|
{
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,13 +393,20 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
|
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.User.TryGetComponent(out IHandsComponent hands))
|
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
_localizationManager.GetString("You have no hands."));
|
_localizationManager.GetString("You have no hands."));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hands.GetActiveHand == null)
|
||||||
|
{
|
||||||
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
|
Loc.GetString("You have nothing on your hand."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var activeHandEntity = hands.GetActiveHand.Owner;
|
var activeHandEntity = hands.GetActiveHand.Owner;
|
||||||
if (activeHandEntity.TryGetComponent<SolutionComponent>(out var solution))
|
if (activeHandEntity.TryGetComponent<SolutionComponent>(out var solution))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using Content.Server.GameObjects.Components.Body.Circulatory;
|
using Content.Server.GameObjects.Components.Body.Circulatory;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Utility;
|
using Content.Server.Utility;
|
||||||
@@ -22,9 +23,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class InjectorComponent : SharedInjectorComponent, IAfterInteract, IUse
|
public class InjectorComponent : SharedInjectorComponent, IAfterInteract, IUse
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not the injector is able to draw from containers or if it's a single use
|
/// Whether or not the injector is able to draw from containers or if it's a single use
|
||||||
@@ -53,11 +52,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
private InjectorToggleMode _toggleState;
|
private InjectorToggleMode _toggleState;
|
||||||
/// <summary>
|
|
||||||
/// Internal solution container
|
|
||||||
/// </summary>
|
|
||||||
[ViewVariables]
|
|
||||||
private SolutionComponent _internalContents;
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
@@ -69,9 +63,15 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
_internalContents = Owner.GetComponent<SolutionComponent>();
|
|
||||||
_internalContents.Capabilities |= SolutionCaps.Injector;
|
Owner.EnsureComponent<SolutionComponent>();
|
||||||
//Set _toggleState based on prototype
|
|
||||||
|
if (Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
solution.Capabilities |= SolutionCaps.Injector;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set _toggleState based on prototype
|
||||||
_toggleState = _injectOnly ? InjectorToggleMode.Inject : InjectorToggleMode.Draw;
|
_toggleState = _injectOnly ? InjectorToggleMode.Inject : InjectorToggleMode.Draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
//Make sure we have the attacking entity
|
//Make sure we have the attacking entity
|
||||||
if (eventArgs.Target == null || !_internalContents.Injector)
|
if (eventArgs.Target == null || !Owner.TryGetComponent(out SolutionComponent? solution) || !solution.Injector)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
}
|
}
|
||||||
else //Handle injecting into bloodstream
|
else //Handle injecting into bloodstream
|
||||||
{
|
{
|
||||||
if (targetEntity.TryGetComponent(out BloodstreamComponent bloodstream) &&
|
if (targetEntity.TryGetComponent(out BloodstreamComponent? bloodstream) &&
|
||||||
_toggleState == InjectorToggleMode.Inject)
|
_toggleState == InjectorToggleMode.Inject)
|
||||||
{
|
{
|
||||||
TryInjectIntoBloodstream(bloodstream, eventArgs.User);
|
TryInjectIntoBloodstream(bloodstream, eventArgs.User);
|
||||||
@@ -155,7 +155,8 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
|
|
||||||
private void TryInjectIntoBloodstream(BloodstreamComponent targetBloodstream, IEntity user)
|
private void TryInjectIntoBloodstream(BloodstreamComponent targetBloodstream, IEntity user)
|
||||||
{
|
{
|
||||||
if (_internalContents.CurrentVolume == 0)
|
if (!Owner.TryGetComponent(out SolutionComponent? solution) ||
|
||||||
|
solution.CurrentVolume == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -170,7 +171,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Move units from attackSolution to targetSolution
|
//Move units from attackSolution to targetSolution
|
||||||
var removedSolution = _internalContents.SplitSolution(realTransferAmount);
|
var removedSolution = solution.SplitSolution(realTransferAmount);
|
||||||
if (!targetBloodstream.TryTransferSolution(removedSolution))
|
if (!targetBloodstream.TryTransferSolution(removedSolution))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -183,7 +184,8 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
|
|
||||||
private void TryInject(SolutionComponent targetSolution, IEntity user)
|
private void TryInject(SolutionComponent targetSolution, IEntity user)
|
||||||
{
|
{
|
||||||
if (_internalContents.CurrentVolume == 0)
|
if (!Owner.TryGetComponent(out SolutionComponent? solution) ||
|
||||||
|
solution.CurrentVolume == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -198,7 +200,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Move units from attackSolution to targetSolution
|
//Move units from attackSolution to targetSolution
|
||||||
var removedSolution = _internalContents.SplitSolution(realTransferAmount);
|
var removedSolution = solution.SplitSolution(realTransferAmount);
|
||||||
if (!targetSolution.TryAddSolution(removedSolution))
|
if (!targetSolution.TryAddSolution(removedSolution))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -211,7 +213,8 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
|
|
||||||
private void TryDraw(SolutionComponent targetSolution, IEntity user)
|
private void TryDraw(SolutionComponent targetSolution, IEntity user)
|
||||||
{
|
{
|
||||||
if (_internalContents.EmptyVolume == 0)
|
if (!Owner.TryGetComponent(out SolutionComponent? solution) ||
|
||||||
|
solution.EmptyVolume == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -227,7 +230,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
|
|
||||||
//Move units from attackSolution to targetSolution
|
//Move units from attackSolution to targetSolution
|
||||||
var removedSolution = targetSolution.SplitSolution(realTransferAmount);
|
var removedSolution = targetSolution.SplitSolution(realTransferAmount);
|
||||||
if (!_internalContents.TryAddSolution(removedSolution))
|
if (!solution.TryAddSolution(removedSolution))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -239,7 +242,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
|
|
||||||
public override ComponentState GetComponentState()
|
public override ComponentState GetComponentState()
|
||||||
{
|
{
|
||||||
return new InjectorComponentState(_internalContents.CurrentVolume, _internalContents.MaxVolume, _toggleState);
|
Owner.TryGetComponent(out SolutionComponent? solution);
|
||||||
|
|
||||||
|
var currentVolume = solution?.CurrentVolume ?? ReagentUnit.Zero;
|
||||||
|
var maxVolume = solution?.MaxVolume ?? ReagentUnit.Zero;
|
||||||
|
|
||||||
|
return new InjectorComponentState(currentVolume, maxVolume, _toggleState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.GUI;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
@@ -38,14 +39,11 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
[ComponentReference(typeof(IInteractUsing))]
|
[ComponentReference(typeof(IInteractUsing))]
|
||||||
public class ReagentDispenserComponent : SharedReagentDispenserComponent, IActivate, IInteractUsing, ISolutionChange
|
public class ReagentDispenserComponent : SharedReagentDispenserComponent, IActivate, IInteractUsing, ISolutionChange
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
[ViewVariables] private BoundUserInterface _userInterface;
|
[ViewVariables] private ContainerSlot _beakerContainer = default!;
|
||||||
[ViewVariables] private ContainerSlot _beakerContainer;
|
[ViewVariables] private string _packPrototypeId = "";
|
||||||
[ViewVariables] private string _packPrototypeId;
|
|
||||||
|
|
||||||
[ViewVariables] private bool HasBeaker => _beakerContainer.ContainedEntity != null;
|
[ViewVariables] private bool HasBeaker => _beakerContainer.ContainedEntity != null;
|
||||||
[ViewVariables] private ReagentUnit _dispenseAmount = ReagentUnit.New(10);
|
[ViewVariables] private ReagentUnit _dispenseAmount = ReagentUnit.New(10);
|
||||||
@@ -53,9 +51,14 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private SolutionComponent Solution => _beakerContainer.ContainedEntity.GetComponent<SolutionComponent>();
|
private SolutionComponent Solution => _beakerContainer.ContainedEntity.GetComponent<SolutionComponent>();
|
||||||
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private bool Powered => _powerReceiver.Powered;
|
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(ReagentDispenserUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the serializer how to save/load this components yaml prototype.
|
/// Shows the serializer how to save/load this components yaml prototype.
|
||||||
@@ -75,14 +78,19 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(ReagentDispenserUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
_beakerContainer =
|
_beakerContainer =
|
||||||
ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-reagentContainerContainer", Owner);
|
ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-reagentContainerContainer", Owner);
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
|
||||||
_powerReceiver.OnPowerStateChanged += OnPowerChanged;
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
|
{
|
||||||
|
receiver.OnPowerStateChanged += OnPowerChanged;
|
||||||
|
}
|
||||||
|
|
||||||
InitializeFromPrototype();
|
InitializeFromPrototype();
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
@@ -108,7 +116,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPowerChanged(object sender, PowerStateEventArgs e)
|
private void OnPowerChanged(object? sender, PowerStateEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
@@ -120,6 +128,11 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// <param name="obj">A user interface message from the client.</param>
|
/// <param name="obj">A user interface message from the client.</param>
|
||||||
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
{
|
{
|
||||||
|
if (obj.Session.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var msg = (UiButtonPressedMessage) obj.Message;
|
var msg = (UiButtonPressedMessage) obj.Message;
|
||||||
var needsPower = msg.Button switch
|
var needsPower = msg.Button switch
|
||||||
{
|
{
|
||||||
@@ -175,7 +188,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="playerEntity">The player entity.</param>
|
/// <param name="playerEntity">The player entity.</param>
|
||||||
/// <returns>Returns true if the entity can use the dispenser, and false if it cannot.</returns>
|
/// <returns>Returns true if the entity can use the dispenser, and false if it cannot.</returns>
|
||||||
private bool PlayerCanUseDispenser(IEntity playerEntity, bool needsPower = true)
|
private bool PlayerCanUseDispenser(IEntity? playerEntity, bool needsPower = true)
|
||||||
{
|
{
|
||||||
//Need player entity to check if they are still able to use the dispenser
|
//Need player entity to check if they are still able to use the dispenser
|
||||||
if (playerEntity == null)
|
if (playerEntity == null)
|
||||||
@@ -211,7 +224,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
private void UpdateUserInterface()
|
private void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
var state = GetUserInterfaceState();
|
var state = GetUserInterfaceState();
|
||||||
_userInterface.SetState(state);
|
UserInterface?.SetState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -265,12 +278,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
||||||
void IActivate.Activate(ActivateEventArgs args)
|
void IActivate.Activate(ActivateEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.User.TryGetComponent(out IActorComponent actor))
|
if (!args.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.User.TryGetComponent(out IHandsComponent hands))
|
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
_localizationManager.GetString("You have no hands."));
|
_localizationManager.GetString("You have no hands."));
|
||||||
@@ -280,7 +293,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
var activeHandEntity = hands.GetActiveHand?.Owner;
|
var activeHandEntity = hands.GetActiveHand?.Owner;
|
||||||
if (activeHandEntity == null)
|
if (activeHandEntity == null)
|
||||||
{
|
{
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,13 +306,20 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
|
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.User.TryGetComponent(out IHandsComponent hands))
|
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
_localizationManager.GetString("You have no hands."));
|
_localizationManager.GetString("You have no hands."));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hands.GetActiveHand == null)
|
||||||
|
{
|
||||||
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
|
Loc.GetString("You have nothing on your hand."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var activeHandEntity = hands.GetActiveHand.Owner;
|
var activeHandEntity = hands.GetActiveHand.Owner;
|
||||||
if (activeHandEntity.TryGetComponent<SolutionComponent>(out var solution))
|
if (activeHandEntity.TryGetComponent<SolutionComponent>(out var solution))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -11,28 +12,27 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class TransformableContainerComponent : Component, ISolutionChange
|
public class TransformableContainerComponent : Component, ISolutionChange
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "TransformableContainer";
|
public override string Name => "TransformableContainer";
|
||||||
|
|
||||||
private bool _transformed = false;
|
private SpriteSpecifier? _initialSprite;
|
||||||
public bool Transformed { get => _transformed; }
|
private string _initialName = default!;
|
||||||
|
private string _initialDescription = default!;
|
||||||
|
private ReagentPrototype? _currentReagent;
|
||||||
|
|
||||||
private SpriteSpecifier _initialSprite;
|
public bool Transformed { get; private set; }
|
||||||
private string _initialName;
|
|
||||||
private string _initialDescription;
|
|
||||||
private SpriteComponent _sprite;
|
|
||||||
|
|
||||||
private ReagentPrototype _currentReagent;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_sprite = Owner.GetComponent<SpriteComponent>();
|
if (Owner.TryGetComponent(out SpriteComponent? sprite) &&
|
||||||
_initialSprite = new SpriteSpecifier.Rsi(new ResourcePath(_sprite.BaseRSIPath), "icon");
|
sprite.BaseRSIPath != null)
|
||||||
|
{
|
||||||
|
_initialSprite = new SpriteSpecifier.Rsi(new ResourcePath(sprite.BaseRSIPath), "icon");
|
||||||
|
}
|
||||||
|
|
||||||
_initialName = Owner.Name;
|
_initialName = Owner.Name;
|
||||||
_initialDescription = Owner.Description;
|
_initialDescription = Owner.Description;
|
||||||
}
|
}
|
||||||
@@ -40,14 +40,20 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
Owner.GetComponent<SolutionComponent>().Capabilities |= SolutionCaps.FitsInDispenser;;
|
Owner.GetComponent<SolutionComponent>().Capabilities |= SolutionCaps.FitsInDispenser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CancelTransformation()
|
public void CancelTransformation()
|
||||||
{
|
{
|
||||||
_currentReagent = null;
|
_currentReagent = null;
|
||||||
_transformed = false;
|
Transformed = false;
|
||||||
_sprite.LayerSetSprite(0, _initialSprite);
|
|
||||||
|
if (Owner.TryGetComponent(out SpriteComponent? sprite) &&
|
||||||
|
_initialSprite != null)
|
||||||
|
{
|
||||||
|
sprite.LayerSetSprite(0, _initialSprite);
|
||||||
|
}
|
||||||
|
|
||||||
Owner.Name = _initialName;
|
Owner.Name = _initialName;
|
||||||
Owner.Description = _initialDescription;
|
Owner.Description = _initialDescription;
|
||||||
}
|
}
|
||||||
@@ -76,11 +82,16 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
!string.IsNullOrWhiteSpace(proto.SpriteReplacementPath))
|
!string.IsNullOrWhiteSpace(proto.SpriteReplacementPath))
|
||||||
{
|
{
|
||||||
var spriteSpec = new SpriteSpecifier.Rsi(new ResourcePath("Objects/Drinks/" + proto.SpriteReplacementPath),"icon");
|
var spriteSpec = new SpriteSpecifier.Rsi(new ResourcePath("Objects/Drinks/" + proto.SpriteReplacementPath),"icon");
|
||||||
_sprite.LayerSetSprite(0, spriteSpec);
|
|
||||||
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
|
{
|
||||||
|
sprite?.LayerSetSprite(0, spriteSpec);
|
||||||
|
}
|
||||||
|
|
||||||
Owner.Name = proto.Name + " glass";
|
Owner.Name = proto.Name + " glass";
|
||||||
Owner.Description = proto.Description;
|
Owner.Description = proto.Description;
|
||||||
_currentReagent = proto;
|
_currentReagent = proto;
|
||||||
_transformed = true;
|
Transformed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.GameObjects.Components.Command;
|
using Content.Shared.GameObjects.Components.Command;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -8,6 +9,7 @@ using Robust.Server.Interfaces.Player;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Command
|
namespace Content.Server.GameObjects.Components.Command
|
||||||
{
|
{
|
||||||
@@ -15,22 +17,27 @@ namespace Content.Server.GameObjects.Components.Command
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent, IActivate
|
public class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent, IActivate
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||||
[Dependency] private IEntitySystemManager _entitySystemManager;
|
|
||||||
#pragma warning restore 649
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
|
||||||
private bool Powered => _powerReceiver.Powered;
|
|
||||||
private RoundEndSystem RoundEndSystem => _entitySystemManager.GetEntitySystem<RoundEndSystem>();
|
private RoundEndSystem RoundEndSystem => _entitySystemManager.GetEntitySystem<RoundEndSystem>();
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(CommunicationsConsoleUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(CommunicationsConsoleUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
{
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
RoundEndSystem.OnRoundEndCountdownStarted += UpdateBoundInterface;
|
RoundEndSystem.OnRoundEndCountdownStarted += UpdateBoundInterface;
|
||||||
RoundEndSystem.OnRoundEndCountdownCancelled += UpdateBoundInterface;
|
RoundEndSystem.OnRoundEndCountdownCancelled += UpdateBoundInterface;
|
||||||
@@ -39,7 +46,7 @@ namespace Content.Server.GameObjects.Components.Command
|
|||||||
|
|
||||||
private void UpdateBoundInterface()
|
private void UpdateBoundInterface()
|
||||||
{
|
{
|
||||||
_userInterface.SetState(new CommunicationsConsoleInterfaceState(RoundEndSystem.ExpectedCountdownEnd));
|
UserInterface?.SetState(new CommunicationsConsoleInterfaceState(RoundEndSystem.ExpectedCountdownEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
@@ -58,12 +65,12 @@ namespace Content.Server.GameObjects.Components.Command
|
|||||||
|
|
||||||
public void OpenUserInterface(IPlayerSession session)
|
public void OpenUserInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Powered)
|
if (!Powered)
|
||||||
|
|||||||
@@ -28,10 +28,8 @@ namespace Content.Server.GameObjects.Components.Conveyor
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class ConveyorComponent : Component, IInteractUsing
|
public class ConveyorComponent : Component, IInteractUsing
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "Conveyor";
|
public override string Name => "Conveyor";
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.GameObjects.Components.Damage;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -27,12 +28,6 @@ namespace Content.Server.GameObjects.Components.Damage
|
|||||||
serializer.DataField(ref _tools, "tools", new List<ToolQuality>());
|
serializer.DataField(ref _tools, "tools", new List<ToolQuality>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
Owner.EnsureComponent<DestructibleComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (eventArgs.Using.TryGetComponent<ToolComponent>(out var tool))
|
if (eventArgs.Using.TryGetComponent<ToolComponent>(out var tool))
|
||||||
@@ -56,7 +51,7 @@ namespace Content.Server.GameObjects.Components.Damage
|
|||||||
|
|
||||||
protected bool CallDamage(InteractUsingEventArgs eventArgs, ToolComponent tool)
|
protected bool CallDamage(InteractUsingEventArgs eventArgs, ToolComponent tool)
|
||||||
{
|
{
|
||||||
if (eventArgs.Target.TryGetComponent<DestructibleComponent>(out var damageable))
|
if (eventArgs.Target.TryGetComponent<IDamageableComponent>(out var damageable))
|
||||||
{
|
{
|
||||||
damageable.ChangeDamage(tool.HasQuality(ToolQuality.Welding)
|
damageable.ChangeDamage(tool.HasQuality(ToolQuality.Welding)
|
||||||
? DamageType.Heat
|
? DamageType.Heat
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Interfaces;
|
#nullable enable
|
||||||
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -25,22 +26,24 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
[ComponentReference(typeof(IDisposalTubeComponent))]
|
[ComponentReference(typeof(IDisposalTubeComponent))]
|
||||||
public class DisposalRouterComponent : DisposalJunctionComponent, IActivate
|
public class DisposalRouterComponent : DisposalJunctionComponent, IActivate
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
public override string Name => "DisposalRouter";
|
public override string Name => "DisposalRouter";
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private BoundUserInterface _userInterface;
|
private readonly HashSet<string> _tags = new HashSet<string>();
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private HashSet<string> _tags;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool Anchored =>
|
public bool Anchored =>
|
||||||
!Owner.TryGetComponent(out CollidableComponent collidable) ||
|
!Owner.TryGetComponent(out ICollidableComponent? collidable) ||
|
||||||
collidable.Anchored;
|
collidable.Anchored;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(DisposalRouterUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override Direction NextDirection(DisposalHolderComponent holder)
|
public override Direction NextDirection(DisposalHolderComponent holder)
|
||||||
{
|
{
|
||||||
var directions = ConnectableDirections();
|
var directions = ConnectableDirections();
|
||||||
@@ -53,15 +56,14 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
return Owner.Transform.LocalRotation.GetDir();
|
return Owner.Transform.LocalRotation.GetDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(DisposalRouterUiKey.Key);
|
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
|
||||||
|
|
||||||
_tags = new HashSet<string>();
|
if (UserInterface != null)
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
@@ -73,6 +75,11 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
/// <param name="obj">A user interface message from the client.</param>
|
/// <param name="obj">A user interface message from the client.</param>
|
||||||
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
{
|
{
|
||||||
|
if (obj.Session.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var msg = (UiActionMessage) obj.Message;
|
var msg = (UiActionMessage) obj.Message;
|
||||||
|
|
||||||
if (!PlayerCanUseDisposalTagger(obj.Session.AttachedEntity))
|
if (!PlayerCanUseDisposalTagger(obj.Session.AttachedEntity))
|
||||||
@@ -112,10 +119,10 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets component data to be used to update the user interface client-side.
|
/// Gets component data to be used to update the user interface client-side.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Returns a <see cref="SharedDisposalRouterComponent.DisposalRouterBoundUserInterfaceState"/></returns>
|
/// <returns>Returns a <see cref="DisposalRouterUserInterfaceState"/></returns>
|
||||||
private DisposalRouterUserInterfaceState GetUserInterfaceState()
|
private DisposalRouterUserInterfaceState GetUserInterfaceState()
|
||||||
{
|
{
|
||||||
if(_tags == null || _tags.Count <= 0)
|
if(_tags.Count <= 0)
|
||||||
{
|
{
|
||||||
return new DisposalRouterUserInterfaceState("");
|
return new DisposalRouterUserInterfaceState("");
|
||||||
}
|
}
|
||||||
@@ -136,7 +143,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
private void UpdateUserInterface()
|
private void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
var state = GetUserInterfaceState();
|
var state = GetUserInterfaceState();
|
||||||
_userInterface.SetState(state);
|
UserInterface?.SetState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClickSound()
|
private void ClickSound()
|
||||||
@@ -150,12 +157,12 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
||||||
void IActivate.Activate(ActivateEventArgs args)
|
void IActivate.Activate(ActivateEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.User.TryGetComponent(out IActorComponent actor))
|
if (!args.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.User.TryGetComponent(out IHandsComponent hands))
|
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
Loc.GetString("You have no hands."));
|
Loc.GetString("You have no hands."));
|
||||||
@@ -166,13 +173,13 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
if (activeHandEntity == null)
|
if (activeHandEntity == null)
|
||||||
{
|
{
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Interfaces;
|
#nullable enable
|
||||||
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -23,35 +24,38 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
[ComponentReference(typeof(IDisposalTubeComponent))]
|
[ComponentReference(typeof(IDisposalTubeComponent))]
|
||||||
public class DisposalTaggerComponent : DisposalTransitComponent, IActivate
|
public class DisposalTaggerComponent : DisposalTransitComponent, IActivate
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
public override string Name => "DisposalTagger";
|
public override string Name => "DisposalTagger";
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
private string _tag = "";
|
private string _tag = "";
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool Anchored =>
|
public bool Anchored =>
|
||||||
!Owner.TryGetComponent(out CollidableComponent collidable) ||
|
!Owner.TryGetComponent(out CollidableComponent? collidable) ||
|
||||||
collidable.Anchored;
|
collidable.Anchored;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(DisposalTaggerUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override Direction NextDirection(DisposalHolderComponent holder)
|
public override Direction NextDirection(DisposalHolderComponent holder)
|
||||||
{
|
{
|
||||||
holder.Tags.Add(_tag);
|
holder.Tags.Add(_tag);
|
||||||
return base.NextDirection(holder);
|
return base.NextDirection(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(DisposalTaggerUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
@@ -81,7 +85,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="playerEntity">The player entity.</param>
|
/// <param name="playerEntity">The player entity.</param>
|
||||||
/// <returns>Returns true if the entity can use the configuration interface, and false if it cannot.</returns>
|
/// <returns>Returns true if the entity can use the configuration interface, and false if it cannot.</returns>
|
||||||
private bool PlayerCanUseDisposalTagger(IEntity playerEntity)
|
private bool PlayerCanUseDisposalTagger(IEntity? playerEntity)
|
||||||
{
|
{
|
||||||
//Need player entity to check if they are still able to use the configuration interface
|
//Need player entity to check if they are still able to use the configuration interface
|
||||||
if (playerEntity == null)
|
if (playerEntity == null)
|
||||||
@@ -98,7 +102,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets component data to be used to update the user interface client-side.
|
/// Gets component data to be used to update the user interface client-side.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Returns a <see cref="SharedDisposalTaggerComponent.DisposalTaggerBoundUserInterfaceState"/></returns>
|
/// <returns>Returns a <see cref="DisposalTaggerUserInterfaceState"/></returns>
|
||||||
private DisposalTaggerUserInterfaceState GetUserInterfaceState()
|
private DisposalTaggerUserInterfaceState GetUserInterfaceState()
|
||||||
{
|
{
|
||||||
return new DisposalTaggerUserInterfaceState(_tag);
|
return new DisposalTaggerUserInterfaceState(_tag);
|
||||||
@@ -107,7 +111,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
private void UpdateUserInterface()
|
private void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
var state = GetUserInterfaceState();
|
var state = GetUserInterfaceState();
|
||||||
_userInterface.SetState(state);
|
UserInterface?.SetState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClickSound()
|
private void ClickSound()
|
||||||
@@ -121,12 +125,12 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
|
||||||
void IActivate.Activate(ActivateEventArgs args)
|
void IActivate.Activate(ActivateEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.User.TryGetComponent(out IActorComponent actor))
|
if (!args.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.User.TryGetComponent(out IHandsComponent hands))
|
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||||
Loc.GetString("You have no hands."));
|
Loc.GetString("You have no hands."));
|
||||||
@@ -137,14 +141,14 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
if (activeHandEntity == null)
|
if (activeHandEntity == null)
|
||||||
{
|
{
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
[ComponentReference(typeof(IInteractUsing))]
|
[ComponentReference(typeof(IInteractUsing))]
|
||||||
public class DisposalUnitComponent : SharedDisposalUnitComponent, IInteractHand, IInteractUsing, IDragDropOn
|
public class DisposalUnitComponent : SharedDisposalUnitComponent, IInteractHand, IInteractUsing, IDragDropOn
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "DisposalUnit";
|
public override string Name => "DisposalUnit";
|
||||||
|
|
||||||
@@ -81,9 +79,6 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
|
|
||||||
[ViewVariables] public IReadOnlyList<IEntity> ContainedEntities => _container.ContainedEntities;
|
[ViewVariables] public IReadOnlyList<IEntity> ContainedEntities => _container.ContainedEntities;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private BoundUserInterface _userInterface = default!;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool Powered =>
|
public bool Powered =>
|
||||||
!Owner.TryGetComponent(out PowerReceiverComponent? receiver) ||
|
!Owner.TryGetComponent(out PowerReceiverComponent? receiver) ||
|
||||||
@@ -115,6 +110,13 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(DisposalUnitUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public bool CanInsert(IEntity entity)
|
public bool CanInsert(IEntity entity)
|
||||||
{
|
{
|
||||||
if (!Anchored)
|
if (!Anchored)
|
||||||
@@ -161,7 +163,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
|
|
||||||
if (entity.TryGetComponent(out IActorComponent? actor))
|
if (entity.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
_userInterface.Close(actor.playerSession);
|
UserInterface?.Close(actor.playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateVisualState();
|
UpdateVisualState();
|
||||||
@@ -291,10 +293,10 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
private void UpdateInterface()
|
private void UpdateInterface()
|
||||||
{
|
{
|
||||||
var state = GetInterfaceState();
|
var state = GetInterfaceState();
|
||||||
_userInterface.SetState(state);
|
UserInterface?.SetState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool PlayerCanUse(IEntity player)
|
private bool PlayerCanUse(IEntity? player)
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
@@ -472,9 +474,11 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_container = ContainerManagerComponent.Ensure<Container>(Name, Owner);
|
_container = ContainerManagerComponent.Ensure<Container>(Name, Owner);
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(DisposalUnitUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateInterface();
|
UpdateInterface();
|
||||||
}
|
}
|
||||||
@@ -513,7 +517,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
_container.ForceRemove(entity);
|
_container.ForceRemove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
|
|
||||||
_automaticEngageToken?.Cancel();
|
_automaticEngageToken?.Cancel();
|
||||||
_automaticEngageToken = null;
|
_automaticEngageToken = null;
|
||||||
@@ -571,7 +575,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
@@ -34,10 +35,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly TimeSpan PowerWiresTimeout = TimeSpan.FromSeconds(5.0);
|
private static readonly TimeSpan PowerWiresTimeout = TimeSpan.FromSeconds(5.0);
|
||||||
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
private CancellationTokenSource _powerWiresPulsedTimerCancel = new CancellationTokenSource();
|
||||||
private WiresComponent _wires;
|
|
||||||
|
|
||||||
private CancellationTokenSource _powerWiresPulsedTimerCancel;
|
|
||||||
|
|
||||||
private bool _powerWiresPulsed;
|
private bool _powerWiresPulsed;
|
||||||
|
|
||||||
@@ -89,13 +87,15 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
private void UpdateWiresStatus()
|
private void UpdateWiresStatus()
|
||||||
{
|
{
|
||||||
|
WiresComponent? wires;
|
||||||
var powerLight = new StatusLightData(Color.Yellow, StatusLightState.On, "POWR");
|
var powerLight = new StatusLightData(Color.Yellow, StatusLightState.On, "POWR");
|
||||||
if (PowerWiresPulsed)
|
if (PowerWiresPulsed)
|
||||||
{
|
{
|
||||||
powerLight = new StatusLightData(Color.Yellow, StatusLightState.BlinkingFast, "POWR");
|
powerLight = new StatusLightData(Color.Yellow, StatusLightState.BlinkingFast, "POWR");
|
||||||
}
|
}
|
||||||
else if (_wires.IsWireCut(Wires.MainPower) &&
|
else if (Owner.TryGetComponent(out wires) &&
|
||||||
_wires.IsWireCut(Wires.BackupPower))
|
wires.IsWireCut(Wires.MainPower) &&
|
||||||
|
wires.IsWireCut(Wires.BackupPower))
|
||||||
{
|
{
|
||||||
powerLight = new StatusLightData(Color.Red, StatusLightState.On, "POWR");
|
powerLight = new StatusLightData(Color.Red, StatusLightState.On, "POWR");
|
||||||
}
|
}
|
||||||
@@ -114,12 +114,17 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
var safetyStatus =
|
var safetyStatus =
|
||||||
new StatusLightData(Color.Red, Safety ? StatusLightState.On : StatusLightState.Off, "SAFE");
|
new StatusLightData(Color.Red, Safety ? StatusLightState.On : StatusLightState.Off, "SAFE");
|
||||||
|
|
||||||
_wires.SetStatus(AirlockWireStatus.PowerIndicator, powerLight);
|
if (!Owner.TryGetComponent(out wires))
|
||||||
_wires.SetStatus(AirlockWireStatus.BoltIndicator, boltStatus);
|
{
|
||||||
_wires.SetStatus(AirlockWireStatus.BoltLightIndicator, boltLightsStatus);
|
return;
|
||||||
_wires.SetStatus(AirlockWireStatus.AIControlIndicator, new StatusLightData(Color.Purple, StatusLightState.BlinkingSlow, "AICT"));
|
}
|
||||||
_wires.SetStatus(AirlockWireStatus.TimingIndicator, timingStatus);
|
|
||||||
_wires.SetStatus(AirlockWireStatus.SafetyIndicator, safetyStatus);
|
wires.SetStatus(AirlockWireStatus.PowerIndicator, powerLight);
|
||||||
|
wires.SetStatus(AirlockWireStatus.BoltIndicator, boltStatus);
|
||||||
|
wires.SetStatus(AirlockWireStatus.BoltLightIndicator, boltLightsStatus);
|
||||||
|
wires.SetStatus(AirlockWireStatus.AIControlIndicator, new StatusLightData(Color.Purple, StatusLightState.BlinkingSlow, "AICT"));
|
||||||
|
wires.SetStatus(AirlockWireStatus.TimingIndicator, timingStatus);
|
||||||
|
wires.SetStatus(AirlockWireStatus.SafetyIndicator, safetyStatus);
|
||||||
/*
|
/*
|
||||||
_wires.SetStatus(6, powerLight);
|
_wires.SetStatus(6, powerLight);
|
||||||
_wires.SetStatus(7, powerLight);
|
_wires.SetStatus(7, powerLight);
|
||||||
@@ -131,14 +136,30 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
private void UpdatePowerCutStatus()
|
private void UpdatePowerCutStatus()
|
||||||
{
|
{
|
||||||
_powerReceiver.PowerDisabled = PowerWiresPulsed ||
|
if (!Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
_wires.IsWireCut(Wires.MainPower) ||
|
{
|
||||||
_wires.IsWireCut(Wires.BackupPower);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PowerWiresPulsed)
|
||||||
|
{
|
||||||
|
receiver.PowerDisabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Owner.TryGetComponent(out WiresComponent? wires))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
receiver.PowerDisabled =
|
||||||
|
wires.IsWireCut(Wires.MainPower) ||
|
||||||
|
wires.IsWireCut(Wires.BackupPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateBoltLightStatus()
|
private void UpdateBoltLightStatus()
|
||||||
{
|
{
|
||||||
if (Owner.TryGetComponent(out AppearanceComponent appearance))
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
{
|
{
|
||||||
appearance.SetData(DoorVisuals.BoltLights, BoltLightsVisible);
|
appearance.SetData(DoorVisuals.BoltLights, BoltLightsVisible);
|
||||||
}
|
}
|
||||||
@@ -150,7 +171,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
{
|
{
|
||||||
base.State = value;
|
base.State = value;
|
||||||
// Only show the maintenance panel if the airlock is closed
|
// Only show the maintenance panel if the airlock is closed
|
||||||
_wires.IsPanelVisible = value != DoorState.Open;
|
if (Owner.TryGetComponent(out WiresComponent? wires))
|
||||||
|
{
|
||||||
|
wires.IsPanelVisible = value != DoorState.Open;
|
||||||
|
}
|
||||||
// If the door is closed, we should look if the bolt was locked while closing
|
// If the door is closed, we should look if the bolt was locked while closing
|
||||||
UpdateBoltLightStatus();
|
UpdateBoltLightStatus();
|
||||||
}
|
}
|
||||||
@@ -159,29 +183,32 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
|
||||||
_wires = Owner.GetComponent<WiresComponent>();
|
|
||||||
|
|
||||||
_powerReceiver.OnPowerStateChanged += PowerDeviceOnOnPowerStateChanged;
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
if (Owner.TryGetComponent(out AppearanceComponent appearance))
|
|
||||||
{
|
{
|
||||||
appearance.SetData(DoorVisuals.Powered, _powerReceiver.Powered);
|
receiver.OnPowerStateChanged += PowerDeviceOnOnPowerStateChanged;
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
|
||||||
|
appearance.SetData(DoorVisuals.Powered, receiver.Powered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
if (Owner.TryGetComponent(out _powerReceiver))
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
{
|
{
|
||||||
_powerReceiver.OnPowerStateChanged -= PowerDeviceOnOnPowerStateChanged;
|
receiver.OnPowerStateChanged -= PowerDeviceOnOnPowerStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PowerDeviceOnOnPowerStateChanged(object sender, PowerStateEventArgs e)
|
private void PowerDeviceOnOnPowerStateChanged(object? sender, PowerStateEventArgs e)
|
||||||
{
|
{
|
||||||
if (Owner.TryGetComponent(out AppearanceComponent appearance))
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
{
|
{
|
||||||
appearance.SetData(DoorVisuals.Powered, e.Powered);
|
appearance.SetData(DoorVisuals.Powered, e.Powered);
|
||||||
}
|
}
|
||||||
@@ -192,11 +219,12 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
protected override void ActivateImpl(ActivateEventArgs args)
|
protected override void ActivateImpl(ActivateEventArgs args)
|
||||||
{
|
{
|
||||||
if (_wires.IsPanelOpen)
|
if (Owner.TryGetComponent(out WiresComponent? wires) &&
|
||||||
|
wires.IsPanelOpen)
|
||||||
{
|
{
|
||||||
if (args.User.TryGetComponent(out IActorComponent actor))
|
if (args.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
_wires.OpenInterface(actor.playerSession);
|
wires.OpenInterface(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -276,8 +304,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
case Wires.MainPower:
|
case Wires.MainPower:
|
||||||
case Wires.BackupPower:
|
case Wires.BackupPower:
|
||||||
PowerWiresPulsed = true;
|
PowerWiresPulsed = true;
|
||||||
_powerWiresPulsedTimerCancel?.Cancel();
|
_powerWiresPulsedTimerCancel.Cancel();
|
||||||
_powerWiresPulsedTimerCancel = new CancellationTokenSource();
|
|
||||||
Timer.Spawn(PowerWiresTimeout,
|
Timer.Spawn(PowerWiresTimeout,
|
||||||
() => PowerWiresPulsed = false,
|
() => PowerWiresPulsed = false,
|
||||||
_powerWiresPulsedTimerCancel.Token);
|
_powerWiresPulsedTimerCancel.Token);
|
||||||
@@ -381,7 +408,8 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
private bool IsPowered()
|
private bool IsPowered()
|
||||||
{
|
{
|
||||||
return _powerReceiver.Powered;
|
return !Owner.TryGetComponent(out PowerReceiverComponent? receiver)
|
||||||
|
|| receiver.Powered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
@@ -392,11 +420,12 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
if (tool.HasQuality(ToolQuality.Cutting)
|
if (tool.HasQuality(ToolQuality.Cutting)
|
||||||
|| tool.HasQuality(ToolQuality.Multitool))
|
|| tool.HasQuality(ToolQuality.Multitool))
|
||||||
{
|
{
|
||||||
if (_wires.IsPanelOpen)
|
if (Owner.TryGetComponent(out WiresComponent? wires)
|
||||||
|
&& wires.IsPanelOpen)
|
||||||
{
|
{
|
||||||
if (eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
_wires.OpenInterface(actor.playerSession);
|
wires.OpenInterface(actor.playerSession);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Content.Server.GameObjects.Components.Access;
|
using Content.Server.GameObjects.Components.Access;
|
||||||
@@ -44,10 +45,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
protected const float AutoCloseDelay = 5;
|
protected const float AutoCloseDelay = 5;
|
||||||
protected float CloseSpeed = AutoCloseDelay;
|
protected float CloseSpeed = AutoCloseDelay;
|
||||||
|
|
||||||
private AirtightComponent airtightComponent;
|
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
|
||||||
private ICollidableComponent _collidableComponent;
|
|
||||||
private AppearanceComponent _appearance;
|
|
||||||
private CancellationTokenSource _cancellationTokenSource;
|
|
||||||
|
|
||||||
private static readonly TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.3f);
|
private static readonly TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.3f);
|
||||||
private static readonly TimeSpan CloseTimeTwo = TimeSpan.FromSeconds(0.9f);
|
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);
|
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()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
_cancellationTokenSource?.Cancel();
|
_cancellationTokenSource?.Cancel();
|
||||||
_collidableComponent = null;
|
|
||||||
_appearance = null;
|
|
||||||
|
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
@@ -104,7 +90,6 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
ActivateImpl(eventArgs);
|
ActivateImpl(eventArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICollideBehavior.CollideWith(IEntity entity)
|
void ICollideBehavior.CollideWith(IEntity entity)
|
||||||
{
|
{
|
||||||
if (State != DoorState.Closed)
|
if (State != DoorState.Closed)
|
||||||
@@ -135,8 +120,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
private void SetAppearance(DoorVisualState state)
|
private void SetAppearance(DoorVisualState state)
|
||||||
{
|
{
|
||||||
if (_appearance != null || Owner.TryGetComponent(out _appearance))
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
_appearance.SetData(DoorVisuals.VisualState, state);
|
{
|
||||||
|
appearance.SetData(DoorVisuals.VisualState, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool CanOpen()
|
public virtual bool CanOpen()
|
||||||
@@ -147,7 +134,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
public bool CanOpen(IEntity user)
|
public bool CanOpen(IEntity user)
|
||||||
{
|
{
|
||||||
if (!CanOpen()) return false;
|
if (!CanOpen()) return false;
|
||||||
if (!Owner.TryGetComponent(out AccessReader accessReader))
|
if (!Owner.TryGetComponent(out AccessReader? accessReader))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -165,7 +152,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
Open();
|
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,
|
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Effects/bang.ogg", Owner,
|
||||||
AudioParams.Default.WithVolume(-2));
|
AudioParams.Default.WithVolume(-2));
|
||||||
@@ -181,15 +168,22 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
State = DoorState.Opening;
|
State = DoorState.Opening;
|
||||||
SetAppearance(DoorVisualState.Opening);
|
SetAppearance(DoorVisualState.Opening);
|
||||||
if (_occludes && Owner.TryGetComponent(out OccluderComponent occluder))
|
if (_occludes && Owner.TryGetComponent(out OccluderComponent? occluder))
|
||||||
{
|
{
|
||||||
occluder.Enabled = false;
|
occluder.Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer.Spawn(OpenTimeOne, async () =>
|
Timer.Spawn(OpenTimeOne, async () =>
|
||||||
{
|
{
|
||||||
airtightComponent.AirBlocked = false;
|
if (Owner.TryGetComponent(out AirtightComponent? airtight))
|
||||||
_collidableComponent.Hard = false;
|
{
|
||||||
|
airtight.AirBlocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out ICollidableComponent? collidable))
|
||||||
|
{
|
||||||
|
collidable.Hard = false;
|
||||||
|
}
|
||||||
|
|
||||||
await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token);
|
await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token);
|
||||||
|
|
||||||
@@ -208,7 +202,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
public bool CanClose(IEntity user)
|
public bool CanClose(IEntity user)
|
||||||
{
|
{
|
||||||
if (!CanClose()) return false;
|
if (!CanClose()) return false;
|
||||||
if (!Owner.TryGetComponent(out AccessReader accessReader))
|
if (!Owner.TryGetComponent(out AccessReader? accessReader))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -229,18 +223,22 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
private void CheckCrush()
|
private void CheckCrush()
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out ICollidableComponent? body))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if collides with something
|
// Check if collides with something
|
||||||
var collidesWith = _collidableComponent.GetCollidingEntities(Vector2.Zero, false);
|
var collidesWith = body.GetCollidingEntities(Vector2.Zero, false);
|
||||||
if (collidesWith.Count() != 0)
|
if (collidesWith.Count() != 0)
|
||||||
{
|
{
|
||||||
// Crush
|
// Crush
|
||||||
bool hitSomeone = false;
|
bool hitSomeone = false;
|
||||||
foreach (var e in collidesWith)
|
foreach (var e in collidesWith)
|
||||||
{
|
{
|
||||||
if (!e.TryGetComponent(out StunnableComponent stun)
|
if (!e.TryGetComponent(out StunnableComponent? stun)
|
||||||
|| !e.TryGetComponent(out IDamageableComponent damage)
|
|| !e.TryGetComponent(out IDamageableComponent? damage)
|
||||||
|| !e.TryGetComponent(out ICollidableComponent otherBody)
|
|| !e.TryGetComponent(out ICollidableComponent? otherBody))
|
||||||
|| !Owner.TryGetComponent(out ICollidableComponent body))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB);
|
var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB);
|
||||||
@@ -264,7 +262,8 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
public bool Close()
|
public bool Close()
|
||||||
{
|
{
|
||||||
bool shouldCheckCrush = false;
|
bool shouldCheckCrush = false;
|
||||||
if (_collidableComponent.IsColliding(Vector2.Zero, false))
|
|
||||||
|
if (Owner.TryGetComponent(out ICollidableComponent? collidable) && collidable.IsColliding(Vector2.Zero, false))
|
||||||
{
|
{
|
||||||
if (Safety)
|
if (Safety)
|
||||||
return false;
|
return false;
|
||||||
@@ -276,7 +275,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
State = DoorState.Closing;
|
State = DoorState.Closing;
|
||||||
OpenTimeCounter = 0;
|
OpenTimeCounter = 0;
|
||||||
SetAppearance(DoorVisualState.Closing);
|
SetAppearance(DoorVisualState.Closing);
|
||||||
if (_occludes && Owner.TryGetComponent(out OccluderComponent occluder))
|
if (_occludes && Owner.TryGetComponent(out OccluderComponent? occluder))
|
||||||
{
|
{
|
||||||
occluder.Enabled = true;
|
occluder.Enabled = true;
|
||||||
}
|
}
|
||||||
@@ -288,8 +287,15 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
CheckCrush();
|
CheckCrush();
|
||||||
}
|
}
|
||||||
|
|
||||||
airtightComponent.AirBlocked = true;
|
if (Owner.TryGetComponent(out AirtightComponent? airtight))
|
||||||
_collidableComponent.Hard = true;
|
{
|
||||||
|
airtight.AirBlocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out ICollidableComponent? body))
|
||||||
|
{
|
||||||
|
body.Hard = true;
|
||||||
|
}
|
||||||
|
|
||||||
await Timer.Delay(CloseTimeTwo, _cancellationTokenSource.Token);
|
await Timer.Delay(CloseTimeTwo, _cancellationTokenSource.Token);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
@@ -19,23 +20,27 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class BucketComponent : Component, IInteractUsing
|
public class BucketComponent : Component, IInteractUsing
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "Bucket";
|
public override string Name => "Bucket";
|
||||||
|
|
||||||
public ReagentUnit MaxVolume
|
public ReagentUnit MaxVolume
|
||||||
{
|
{
|
||||||
get => _contents.MaxVolume;
|
get => Owner.TryGetComponent(out SolutionComponent? solution) ? solution.MaxVolume : ReagentUnit.Zero;
|
||||||
set => _contents.MaxVolume = value;
|
set
|
||||||
|
{
|
||||||
|
if (Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
solution.MaxVolume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReagentUnit CurrentVolume => _contents.CurrentVolume;
|
public ReagentUnit CurrentVolume => Owner.TryGetComponent(out SolutionComponent? solution)
|
||||||
|
? solution.CurrentVolume
|
||||||
|
: ReagentUnit.Zero;
|
||||||
|
|
||||||
private SolutionComponent _contents;
|
private string? _sound;
|
||||||
|
|
||||||
private string _sound;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
@@ -47,15 +52,20 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_contents = Owner.GetComponent<SolutionComponent>();
|
Owner.EnsureComponent<SolutionComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGiveToMop(MopComponent mopComponent)
|
private bool TryGiveToMop(MopComponent mopComponent)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out SolutionComponent? contents))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Let's fill 'er up
|
// Let's fill 'er up
|
||||||
// If this is called the mop should be empty but just in case we'll do Max - Current
|
// 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 transferAmount = ReagentUnit.Min(mopComponent.MaxVolume - mopComponent.CurrentVolume, CurrentVolume);
|
||||||
var solution = _contents.SplitSolution(transferAmount);
|
var solution = contents.SplitSolution(transferAmount);
|
||||||
if (!mopComponent.Contents.TryAddSolution(solution) || mopComponent.CurrentVolume == 0)
|
if (!mopComponent.Contents.TryAddSolution(solution) || mopComponent.CurrentVolume == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -73,7 +83,12 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
|
|
||||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.Using.TryGetComponent(out MopComponent mopComponent))
|
if (!Owner.TryGetComponent(out SolutionComponent? contents))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eventArgs.Using.TryGetComponent(out MopComponent? mopComponent))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -97,7 +112,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
}
|
}
|
||||||
|
|
||||||
var solution = mopComponent.Contents.SplitSolution(transferAmount);
|
var solution = mopComponent.Contents.SplitSolution(transferAmount);
|
||||||
if (!_contents.TryAddSolution(solution))
|
if (!contents.TryAddSolution(solution))
|
||||||
{
|
{
|
||||||
//This really shouldn't happen
|
//This really shouldn't happen
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|||||||
@@ -126,18 +126,25 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
_contents.Initialize();
|
_contents.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
_snapGrid = Owner.GetComponent<SnapGridComponent>();
|
_snapGrid = Owner.EnsureComponent<SnapGridComponent>();
|
||||||
|
|
||||||
// Smaller than 1m^3 for now but realistically this shouldn't be hit
|
// Smaller than 1m^3 for now but realistically this shouldn't be hit
|
||||||
MaxVolume = ReagentUnit.New(1000);
|
MaxVolume = ReagentUnit.New(1000);
|
||||||
|
|
||||||
// Random sprite state set server-side so it's consistent across all clients
|
// Random sprite state set server-side so it's consistent across all clients
|
||||||
_spriteComponent = Owner.GetComponent<SpriteComponent>();
|
_spriteComponent = Owner.EnsureComponent<SpriteComponent>();
|
||||||
|
|
||||||
var robustRandom = IoCManager.Resolve<IRobustRandom>();
|
var robustRandom = IoCManager.Resolve<IRobustRandom>();
|
||||||
var randomVariant = robustRandom.Next(0, _spriteVariants - 1);
|
var randomVariant = robustRandom.Next(0, _spriteVariants - 1);
|
||||||
|
|
||||||
|
if (_spriteComponent.BaseRSIPath != null)
|
||||||
|
{
|
||||||
var baseName = new ResourcePath(_spriteComponent.BaseRSIPath).FilenameWithoutExtension;
|
var baseName = new ResourcePath(_spriteComponent.BaseRSIPath).FilenameWithoutExtension;
|
||||||
|
|
||||||
_spriteComponent.LayerSetState(0, $"{baseName}-{randomVariant}"); // TODO: Remove hardcode
|
_spriteComponent.LayerSetState(0, $"{baseName}-{randomVariant}"); // TODO: Remove hardcode
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateAppearance should get called soon after this so shouldn't need to call Dirty() here
|
// UpdateAppearance should get called soon after this so shouldn't need to call Dirty() here
|
||||||
|
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
|
|||||||
@@ -16,10 +16,9 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
class SprayComponent : Component, IAfterInteract
|
class SprayComponent : Component, IAfterInteract
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
public override string Name => "Spray";
|
public override string Name => "Spray";
|
||||||
|
|
||||||
private ReagentUnit _transferAmount;
|
private ReagentUnit _transferAmount;
|
||||||
|
|||||||
@@ -37,9 +37,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
[ComponentReference(typeof(ISharedHandsComponent))]
|
[ComponentReference(typeof(ISharedHandsComponent))]
|
||||||
public class HandsComponent : SharedHandsComponent, IHandsComponent, IBodyPartAdded, IBodyPartRemoved
|
public class HandsComponent : SharedHandsComponent, IHandsComponent, IBodyPartAdded, IBodyPartRemoved
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private string? _activeHand;
|
private string? _activeHand;
|
||||||
private uint _nextHand;
|
private uint _nextHand;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_inventory = Owner.GetComponent<InventoryComponent>();
|
_inventory = Owner.EnsureComponent<InventoryComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IInventoryController.CanEquip(Slots slot, IEntity entity, bool flagsCheck, out string reason)
|
bool IInventoryController.CanEquip(Slots slot, IEntity entity, bool flagsCheck, out string reason)
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.GameObjects.EntitySystems.DoAfter;
|
using Content.Server.GameObjects.EntitySystems.DoAfter;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Shared.GameObjects.Components.GUI;
|
using Content.Shared.GameObjects.Components.GUI;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
@@ -16,7 +15,6 @@ using Robust.Shared.GameObjects.Systems;
|
|||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||||
|
|
||||||
@@ -25,27 +23,33 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class StrippableComponent : SharedStrippableComponent, IDragDrop
|
public sealed class StrippableComponent : SharedStrippableComponent, IDragDrop
|
||||||
{
|
{
|
||||||
[Dependency] private IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
|
|
||||||
public const float StripDelay = 2f;
|
public const float StripDelay = 2f;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private BoundUserInterface _userInterface;
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
private InventoryComponent _inventoryComponent;
|
ui.TryGetBoundUserInterface(StrippingUiKey.Key, out var boundUi)
|
||||||
private HandsComponent _handsComponent;
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(StrippingUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += HandleUserInterfaceMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += HandleUserInterfaceMessage;
|
||||||
|
}
|
||||||
|
|
||||||
_inventoryComponent = Owner.GetComponent<InventoryComponent>();
|
Owner.EnsureComponent<InventoryComponent>();
|
||||||
_handsComponent = Owner.GetComponent<HandsComponent>();
|
Owner.EnsureComponent<HandsComponent>();
|
||||||
|
|
||||||
_inventoryComponent.OnItemChanged += UpdateSubscribed;
|
if (Owner.TryGetComponent(out InventoryComponent? inventory))
|
||||||
|
{
|
||||||
|
inventory.OnItemChanged += UpdateSubscribed;
|
||||||
|
}
|
||||||
|
|
||||||
// Initial update.
|
// Initial update.
|
||||||
UpdateSubscribed();
|
UpdateSubscribed();
|
||||||
@@ -53,10 +57,15 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
|
|
||||||
private void UpdateSubscribed()
|
private void UpdateSubscribed()
|
||||||
{
|
{
|
||||||
|
if (UserInterface == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var inventory = GetInventorySlots();
|
var inventory = GetInventorySlots();
|
||||||
var hands = GetHandSlots();
|
var hands = GetHandSlots();
|
||||||
|
|
||||||
_userInterface.SetState(new StrippingBoundUserInterfaceState(inventory, hands));
|
UserInterface.SetState(new StrippingBoundUserInterfaceState(inventory, hands));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanDragDrop(DragDropEventArgs eventArgs)
|
public bool CanDragDrop(DragDropEventArgs eventArgs)
|
||||||
@@ -67,7 +76,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
|
|
||||||
public bool DragDrop(DragDropEventArgs eventArgs)
|
public bool DragDrop(DragDropEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor)) return false;
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor)) return false;
|
||||||
|
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
return true;
|
return true;
|
||||||
@@ -77,9 +86,14 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
{
|
{
|
||||||
var dictionary = new Dictionary<Slots, string>();
|
var dictionary = new Dictionary<Slots, string>();
|
||||||
|
|
||||||
foreach (var slot in _inventoryComponent.Slots)
|
if (!Owner.TryGetComponent(out InventoryComponent? inventory))
|
||||||
{
|
{
|
||||||
dictionary[slot] = _inventoryComponent.GetSlotItem(slot)?.Owner.Name ?? "None";
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var slot in inventory.Slots)
|
||||||
|
{
|
||||||
|
dictionary[slot] = inventory.GetSlotItem(slot)?.Owner.Name ?? "None";
|
||||||
}
|
}
|
||||||
|
|
||||||
return dictionary;
|
return dictionary;
|
||||||
@@ -89,9 +103,14 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
{
|
{
|
||||||
var dictionary = new Dictionary<string, string>();
|
var dictionary = new Dictionary<string, string>();
|
||||||
|
|
||||||
foreach (var hand in _handsComponent.Hands)
|
if (!Owner.TryGetComponent(out HandsComponent? hands))
|
||||||
{
|
{
|
||||||
dictionary[hand] = _handsComponent.GetItem(hand)?.Owner.Name ?? "None";
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var hand in hands.Hands)
|
||||||
|
{
|
||||||
|
dictionary[hand] = hands.GetItem(hand)?.Owner.Name ?? "None";
|
||||||
}
|
}
|
||||||
|
|
||||||
return dictionary;
|
return dictionary;
|
||||||
@@ -99,7 +118,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
|
|
||||||
private void OpenUserInterface(IPlayerSession session)
|
private void OpenUserInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -336,7 +355,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
private void HandleUserInterfaceMessage(ServerBoundUserInterfaceMessage obj)
|
private void HandleUserInterfaceMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
{
|
{
|
||||||
var user = obj.Session.AttachedEntity;
|
var user = obj.Session.AttachedEntity;
|
||||||
if (user == null || !(user.TryGetComponent(out HandsComponent userHands))) return;
|
if (user == null || !(user.TryGetComponent(out HandsComponent? userHands))) return;
|
||||||
|
|
||||||
var placingItem = userHands.GetActiveHand != null;
|
var placingItem = userHands.GetActiveHand != null;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Threading.Tasks;
|
#nullable enable
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.Damage;
|
using Content.Server.GameObjects.Components.Damage;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Shared.GameObjects.Components.Gravity;
|
using Content.Shared.GameObjects.Components.Gravity;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
@@ -22,11 +22,6 @@ namespace Content.Server.GameObjects.Components.Gravity
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class GravityGeneratorComponent : SharedGravityGeneratorComponent, IInteractUsing, IBreakAct, IInteractHand
|
public class GravityGeneratorComponent : SharedGravityGeneratorComponent, IInteractUsing, IBreakAct, IInteractHand
|
||||||
{
|
{
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
|
||||||
|
|
||||||
private SpriteComponent _sprite;
|
|
||||||
|
|
||||||
private bool _switchedOn;
|
private bool _switchedOn;
|
||||||
|
|
||||||
@@ -34,7 +29,7 @@ namespace Content.Server.GameObjects.Components.Gravity
|
|||||||
|
|
||||||
private GravityGeneratorStatus _status;
|
private GravityGeneratorStatus _status;
|
||||||
|
|
||||||
public bool Powered => _powerReceiver.Powered;
|
public bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
|
|
||||||
public bool SwitchedOn => _switchedOn;
|
public bool SwitchedOn => _switchedOn;
|
||||||
|
|
||||||
@@ -64,15 +59,21 @@ namespace Content.Server.GameObjects.Components.Gravity
|
|||||||
|
|
||||||
public override string Name => "GravityGenerator";
|
public override string Name => "GravityGenerator";
|
||||||
|
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(GravityGeneratorUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
if (UserInterface != null)
|
||||||
.GetBoundUserInterface(GravityGeneratorUiKey.Key);
|
{
|
||||||
_userInterface.OnReceiveMessage += HandleUIMessage;
|
UserInterface.OnReceiveMessage += HandleUIMessage;
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
}
|
||||||
_sprite = Owner.GetComponent<SpriteComponent>();
|
|
||||||
_switchedOn = true;
|
_switchedOn = true;
|
||||||
_intact = true;
|
_intact = true;
|
||||||
_status = GravityGeneratorStatus.On;
|
_status = GravityGeneratorStatus.On;
|
||||||
@@ -101,7 +102,7 @@ namespace Content.Server.GameObjects.Components.Gravity
|
|||||||
|
|
||||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.Using.TryGetComponent(out WelderComponent tool))
|
if (!eventArgs.Using.TryGetComponent(out WelderComponent? tool))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!await tool.UseTool(eventArgs.User, Owner, 2f, ToolQuality.Welding, 5f))
|
if (!await tool.UseTool(eventArgs.User, Owner, 2f, ToolQuality.Welding, 5f))
|
||||||
@@ -150,7 +151,7 @@ namespace Content.Server.GameObjects.Components.Gravity
|
|||||||
switch (message.Message)
|
switch (message.Message)
|
||||||
{
|
{
|
||||||
case GeneratorStatusRequestMessage _:
|
case GeneratorStatusRequestMessage _:
|
||||||
_userInterface.SetState(new GeneratorState(Status == GravityGeneratorStatus.On));
|
UserInterface?.SetState(new GeneratorState(Status == GravityGeneratorStatus.On));
|
||||||
break;
|
break;
|
||||||
case SwitchGeneratorMessage msg:
|
case SwitchGeneratorMessage msg:
|
||||||
_switchedOn = msg.On;
|
_switchedOn = msg.On;
|
||||||
@@ -163,35 +164,51 @@ namespace Content.Server.GameObjects.Components.Gravity
|
|||||||
|
|
||||||
private void OpenUserInterface(IPlayerSession playerSession)
|
private void OpenUserInterface(IPlayerSession playerSession)
|
||||||
{
|
{
|
||||||
_userInterface.Open(playerSession);
|
UserInterface?.Open(playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MakeBroken()
|
private void MakeBroken()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.Broken;
|
_status = GravityGeneratorStatus.Broken;
|
||||||
_sprite.LayerSetState(0, "broken");
|
|
||||||
_sprite.LayerSetVisible(1, false);
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
|
{
|
||||||
|
sprite.LayerSetState(0, "broken");
|
||||||
|
sprite.LayerSetVisible(1, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MakeUnpowered()
|
private void MakeUnpowered()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.Unpowered;
|
_status = GravityGeneratorStatus.Unpowered;
|
||||||
_sprite.LayerSetState(0, "off");
|
|
||||||
_sprite.LayerSetVisible(1, false);
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
|
{
|
||||||
|
sprite.LayerSetState(0, "off");
|
||||||
|
sprite.LayerSetVisible(1, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MakeOff()
|
private void MakeOff()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.Off;
|
_status = GravityGeneratorStatus.Off;
|
||||||
_sprite.LayerSetState(0, "off");
|
|
||||||
_sprite.LayerSetVisible(1, false);
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
|
{
|
||||||
|
sprite.LayerSetState(0, "off");
|
||||||
|
sprite.LayerSetVisible(1, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MakeOn()
|
private void MakeOn()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.On;
|
_status = GravityGeneratorStatus.On;
|
||||||
_sprite.LayerSetState(0, "on");
|
|
||||||
_sprite.LayerSetVisible(1, true);
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
|
{
|
||||||
|
sprite.LayerSetState(0, "on");
|
||||||
|
sprite.LayerSetVisible(1, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
@@ -34,12 +35,8 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
IUse,
|
IUse,
|
||||||
IThrown
|
IThrown
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
|
||||||
|
|
||||||
[Dependency] private readonly IGameTiming _gameTiming;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private static readonly TimeSpan OneSecAgo = TimeSpan.FromSeconds(-1);
|
private static readonly TimeSpan OneSecAgo = TimeSpan.FromSeconds(-1);
|
||||||
|
|
||||||
@@ -47,7 +44,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
/// The client channel currently playing the instrument, or null if there's none.
|
/// The client channel currently playing the instrument, or null if there's none.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private IPlayerSession _instrumentPlayer;
|
private IPlayerSession? _instrumentPlayer;
|
||||||
|
|
||||||
private bool _handheld;
|
private bool _handheld;
|
||||||
|
|
||||||
@@ -72,9 +69,6 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private int _midiEventCount = 0;
|
private int _midiEventCount = 0;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the instrument is an item which can be held or not.
|
/// Whether the instrument is an item which can be held or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -95,7 +89,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPlayerSession InstrumentPlayer
|
public IPlayerSession? InstrumentPlayer
|
||||||
{
|
{
|
||||||
get => _instrumentPlayer;
|
get => _instrumentPlayer;
|
||||||
private set
|
private set
|
||||||
@@ -108,11 +102,18 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
_instrumentPlayer = value;
|
_instrumentPlayer = value;
|
||||||
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_instrumentPlayer.PlayerStatusChanged += OnPlayerStatusChanged;
|
_instrumentPlayer!.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPlayerStatusChanged(object sender, SessionStatusEventArgs e)
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(InstrumentUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
|
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Session != _instrumentPlayer || e.NewStatus != SessionStatus.Disconnected) return;
|
if (e.Session != _instrumentPlayer || e.NewStatus != SessionStatus.Disconnected) return;
|
||||||
InstrumentPlayer = null;
|
InstrumentPlayer = null;
|
||||||
@@ -122,8 +123,11 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(InstrumentUiKey.Key);
|
|
||||||
_userInterface.OnClosed += UserInterfaceOnClosed;
|
if (UserInterface != null)
|
||||||
|
{
|
||||||
|
UserInterface.OnClosed += UserInterfaceOnClosed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
@@ -137,14 +141,14 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
return new InstrumentState(Playing, _lastSequencerTick);
|
return new InstrumentState(Playing, _lastSequencerTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession? session = null)
|
||||||
{
|
{
|
||||||
base.HandleNetworkMessage(message, channel, session);
|
base.HandleNetworkMessage(message, channel, session);
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case InstrumentMidiEventMessage midiEventMsg:
|
case InstrumentMidiEventMessage midiEventMsg:
|
||||||
if (!Playing || session != _instrumentPlayer) return;
|
if (!Playing || session != _instrumentPlayer || InstrumentPlayer == null) return;
|
||||||
|
|
||||||
var send = true;
|
var send = true;
|
||||||
|
|
||||||
@@ -231,7 +235,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
Clean();
|
Clean();
|
||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
InstrumentPlayer = null;
|
InstrumentPlayer = null;
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Thrown(ThrownEventArgs eventArgs)
|
public void Thrown(ThrownEventArgs eventArgs)
|
||||||
@@ -239,7 +243,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
Clean();
|
Clean();
|
||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
InstrumentPlayer = null;
|
InstrumentPlayer = null;
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandSelected(HandSelectedEventArgs eventArgs)
|
public void HandSelected(HandSelectedEventArgs eventArgs)
|
||||||
@@ -255,12 +259,12 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
{
|
{
|
||||||
Clean();
|
Clean();
|
||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate(ActivateEventArgs eventArgs)
|
public void Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (Handheld || !eventArgs.User.TryGetComponent(out IActorComponent actor)) return;
|
if (Handheld || !eventArgs.User.TryGetComponent(out IActorComponent? actor)) return;
|
||||||
|
|
||||||
if (InstrumentPlayer != null) return;
|
if (InstrumentPlayer != null) return;
|
||||||
|
|
||||||
@@ -270,7 +274,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
|
|
||||||
public bool UseEntity(UseEntityEventArgs eventArgs)
|
public bool UseEntity(UseEntityEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor)) return false;
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor)) return false;
|
||||||
|
|
||||||
if (InstrumentPlayer == actor.playerSession)
|
if (InstrumentPlayer == actor.playerSession)
|
||||||
{
|
{
|
||||||
@@ -291,7 +295,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
|
|
||||||
private void OpenUserInterface(IPlayerSession session)
|
private void OpenUserInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float delta)
|
public override void Update(float delta)
|
||||||
@@ -302,7 +306,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
{
|
{
|
||||||
InstrumentPlayer = null;
|
InstrumentPlayer = null;
|
||||||
Clean();
|
Clean();
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_batchesDropped >= MaxMidiBatchDropped
|
if ((_batchesDropped >= MaxMidiBatchDropped
|
||||||
@@ -314,9 +318,9 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
Playing = false;
|
Playing = false;
|
||||||
|
|
||||||
_userInterface.CloseAll();
|
UserInterface?.CloseAll();
|
||||||
|
|
||||||
if (mob.TryGetComponent(out StunnableComponent stun))
|
if (mob != null && mob.TryGetComponent(out StunnableComponent? stun))
|
||||||
{
|
{
|
||||||
stun.Stun(1);
|
stun.Stun(1);
|
||||||
Clean();
|
Clean();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
#nullable enable
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.GUI;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Items.Clothing;
|
using Content.Server.GameObjects.Components.Items.Clothing;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
@@ -29,25 +30,20 @@ namespace Content.Server.GameObjects.Components.Interactable
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
internal sealed class HandheldLightComponent : SharedHandheldLightComponent, IUse, IExamine, IInteractUsing, IMapInit
|
internal sealed class HandheldLightComponent : SharedHandheldLightComponent, IUse, IExamine, IInteractUsing, IMapInit
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly ISharedNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly ISharedNotifyManager _notifyManager;
|
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)] public float Wattage { get; set; } = 10;
|
[ViewVariables(VVAccess.ReadWrite)] public float Wattage { get; set; } = 10;
|
||||||
[ViewVariables] private ContainerSlot _cellContainer;
|
[ViewVariables] private ContainerSlot _cellContainer = default!;
|
||||||
private PointLightComponent _pointLight;
|
|
||||||
private SpriteComponent _spriteComponent;
|
|
||||||
private ClothingComponent _clothingComponent;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private BatteryComponent Cell
|
private BatteryComponent? Cell
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_cellContainer.ContainedEntity == null) return null;
|
if (_cellContainer.ContainedEntity == null) return null;
|
||||||
|
|
||||||
_cellContainer.ContainedEntity.TryGetComponent(out BatteryComponent cell);
|
_cellContainer.ContainedEntity.TryGetComponent(out BatteryComponent? cell);
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,11 +94,10 @@ namespace Content.Server.GameObjects.Components.Interactable
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_pointLight = Owner.GetComponent<PointLightComponent>();
|
Owner.EnsureComponent<PointLightComponent>();
|
||||||
_spriteComponent = Owner.GetComponent<SpriteComponent>();
|
|
||||||
Owner.TryGetComponent(out _clothingComponent);
|
|
||||||
_cellContainer =
|
_cellContainer =
|
||||||
ContainerManagerComponent.Ensure<ContainerSlot>("flashlight_cell_container", Owner, out _);
|
ContainerManagerComponent.Ensure<ContainerSlot>("flashlight_cell_container", Owner, out _);
|
||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,11 +174,19 @@ namespace Content.Server.GameObjects.Components.Interactable
|
|||||||
|
|
||||||
private void SetState(bool on)
|
private void SetState(bool on)
|
||||||
{
|
{
|
||||||
_spriteComponent.LayerSetVisible(1, on);
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
_pointLight.Enabled = on;
|
|
||||||
if (_clothingComponent != null)
|
|
||||||
{
|
{
|
||||||
_clothingComponent.ClothingEquippedPrefix = on ? "On" : "Off";
|
sprite.LayerSetVisible(1, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out PointLightComponent? light))
|
||||||
|
{
|
||||||
|
light.Enabled = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out ClothingComponent? clothing))
|
||||||
|
{
|
||||||
|
clothing.ClothingEquippedPrefix = on ? "On" : "Off";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +214,7 @@ namespace Content.Server.GameObjects.Components.Interactable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.TryGetComponent(out HandsComponent hands))
|
if (!user.TryGetComponent(out HandsComponent? hands))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,8 @@ namespace Content.Server.GameObjects.Components.Interactable
|
|||||||
[ComponentReference(typeof(IToolComponent))]
|
[ComponentReference(typeof(IToolComponent))]
|
||||||
public class WelderComponent : ToolComponent, IExamine, IUse, ISuicideAct, ISolutionChange
|
public class WelderComponent : ToolComponent, IExamine, IUse, ISuicideAct, ISolutionChange
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "Welder";
|
public override string Name => "Welder";
|
||||||
public override uint? NetID => ContentNetIDs.WELDER;
|
public override uint? NetID => ContentNetIDs.WELDER;
|
||||||
|
|||||||
@@ -21,10 +21,8 @@ namespace Content.Server.GameObjects.Components.Items
|
|||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
public override string Name => "FloorTile";
|
public override string Name => "FloorTile";
|
||||||
private StackComponent _stack;
|
|
||||||
private string _outputTile;
|
private string _outputTile;
|
||||||
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
base.ExposeData(serializer);
|
base.ExposeData(serializer);
|
||||||
@@ -34,18 +32,20 @@ namespace Content.Server.GameObjects.Components.Items
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_stack = Owner.GetComponent<StackComponent>();
|
Owner.EnsureComponent<StackComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AfterInteract(AfterInteractEventArgs eventArgs)
|
public void AfterInteract(AfterInteractEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
if (!Owner.TryGetComponent(out StackComponent stack)) return;
|
||||||
|
|
||||||
var attacked = eventArgs.Target;
|
var attacked = eventArgs.Target;
|
||||||
var mapGrid = _mapManager.GetGrid(eventArgs.ClickLocation.GridID);
|
var mapGrid = _mapManager.GetGrid(eventArgs.ClickLocation.GridID);
|
||||||
var tile = mapGrid.GetTileRef(eventArgs.ClickLocation);
|
var tile = mapGrid.GetTileRef(eventArgs.ClickLocation);
|
||||||
var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];
|
var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];
|
||||||
|
|
||||||
if (tileDef.IsSubFloor && attacked == null && _stack.Use(1))
|
if (tileDef.IsSubFloor && attacked == null && stack.Use(1))
|
||||||
{
|
{
|
||||||
var desiredTile = _tileDefinitionManager[_outputTile];
|
var desiredTile = _tileDefinitionManager[_outputTile];
|
||||||
mapGrid.SetTile(eventArgs.ClickLocation, new Tile(desiredTile.TileId));
|
mapGrid.SetTile(eventArgs.ClickLocation, new Tile(desiredTile.TileId));
|
||||||
|
|||||||
@@ -37,10 +37,8 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
public class ServerStorageComponent : SharedStorageComponent, IInteractUsing, IUse, IActivate, IStorageComponent, IDestroyAct, IExAct,
|
public class ServerStorageComponent : SharedStorageComponent, IInteractUsing, IUse, IActivate, IStorageComponent, IDestroyAct, IExAct,
|
||||||
IDragDrop
|
IDragDrop
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private const string LoggerName = "Storage";
|
private const string LoggerName = "Storage";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -39,25 +40,19 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class MicrowaveComponent : SharedMicrowaveComponent, IActivate, IInteractUsing, ISolutionChange, ISuicideAct
|
public class MicrowaveComponent : SharedMicrowaveComponent, IActivate, IInteractUsing, ISolutionChange, ISuicideAct
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager;
|
[Dependency] private readonly RecipeManager _recipeManager = default!;
|
||||||
[Dependency] private readonly RecipeManager _recipeManager;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
#region YAMLSERIALIZE
|
#region YAMLSERIALIZE
|
||||||
private int _cookTimeDefault;
|
private int _cookTimeDefault;
|
||||||
private int _cookTimeMultiplier; //For upgrades and stuff I guess?
|
private int _cookTimeMultiplier; //For upgrades and stuff I guess?
|
||||||
private string _badRecipeName;
|
private string _badRecipeName = "";
|
||||||
private string _startCookingSound;
|
private string _startCookingSound = "";
|
||||||
private string _cookingCompleteSound;
|
private string _cookingCompleteSound = "";
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region VIEWVARIABLES
|
[ViewVariables]
|
||||||
[ViewVariables]
|
|
||||||
private SolutionComponent _solution;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private bool _busy = false;
|
private bool _busy = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -67,20 +62,23 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private uint _currentCookTimerTime = 1;
|
private uint _currentCookTimerTime = 1;
|
||||||
#endregion
|
|
||||||
|
|
||||||
private bool _powered => _powerReceiver.Powered;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private bool _hasContents => _solution.ReagentList.Count > 0 || _storage.ContainedEntities.Count > 0;
|
private bool _hasContents => Owner.TryGetComponent(out SolutionComponent? solution) && (solution.ReagentList.Count > 0 || _storage.ContainedEntities.Count > 0);
|
||||||
private bool _uiDirty = true;
|
private bool _uiDirty = true;
|
||||||
private bool _lostPower = false;
|
private bool _lostPower = false;
|
||||||
private int _currentCookTimeButtonIndex = 0;
|
private int _currentCookTimeButtonIndex = 0;
|
||||||
|
|
||||||
void ISolutionChange.SolutionChanged(SolutionChangeEventArgs eventArgs) => _uiDirty = true;
|
void ISolutionChange.SolutionChanged(SolutionChangeEventArgs eventArgs) => _uiDirty = true;
|
||||||
private AudioSystem _audioSystem;
|
private AudioSystem _audioSystem = default!;
|
||||||
private AppearanceComponent _appearance;
|
private Container _storage = default!;
|
||||||
private PowerReceiverComponent _powerReceiver;
|
|
||||||
private BoundUserInterface _userInterface;
|
[ViewVariables]
|
||||||
private Container _storage;
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(MicrowaveUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
@@ -95,22 +93,21 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_solution ??= Owner.TryGetComponent(out SolutionComponent solutionComponent)
|
|
||||||
? solutionComponent
|
Owner.EnsureComponent<SolutionComponent>();
|
||||||
: Owner.AddComponent<SolutionComponent>();
|
|
||||||
|
|
||||||
_storage = ContainerManagerComponent.Ensure<Container>("microwave_entity_container", Owner, out var existed);
|
_storage = ContainerManagerComponent.Ensure<Container>("microwave_entity_container", Owner, out var existed);
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
|
||||||
_audioSystem = EntitySystem.Get<AudioSystem>();
|
_audioSystem = EntitySystem.Get<AudioSystem>();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(MicrowaveUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
||||||
{
|
{
|
||||||
if (!_powered || _busy)
|
if (!Powered || _busy)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -158,13 +155,13 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
public void OnUpdate()
|
public void OnUpdate()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!_powered)
|
if (!Powered)
|
||||||
{
|
{
|
||||||
//TODO:If someone cuts power currently, microwave magically keeps going. FIX IT!
|
//TODO:If someone cuts power currently, microwave magically keeps going. FIX IT!
|
||||||
SetAppearance(MicrowaveVisualState.Idle);
|
SetAppearance(MicrowaveVisualState.Idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_busy && !_powered)
|
if (_busy && !Powered)
|
||||||
{
|
{
|
||||||
//we lost power while we were cooking/busy!
|
//we lost power while we were cooking/busy!
|
||||||
_lostPower = true;
|
_lostPower = true;
|
||||||
@@ -174,11 +171,11 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
_uiDirty = true;
|
_uiDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_uiDirty)
|
if (_uiDirty && Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
{
|
{
|
||||||
_userInterface.SetState(new MicrowaveUpdateUserInterfaceState
|
UserInterface?.SetState(new MicrowaveUpdateUserInterfaceState
|
||||||
(
|
(
|
||||||
_solution.Solution.Contents.ToArray(),
|
solution.Solution.Contents.ToArray(),
|
||||||
_storage.ContainedEntities.Select(item => item.Uid).ToArray(),
|
_storage.ContainedEntities.Select(item => item.Uid).ToArray(),
|
||||||
_busy,
|
_busy,
|
||||||
_currentCookTimeButtonIndex,
|
_currentCookTimeButtonIndex,
|
||||||
@@ -190,26 +187,26 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
|
|
||||||
private void SetAppearance(MicrowaveVisualState state)
|
private void SetAppearance(MicrowaveVisualState state)
|
||||||
{
|
{
|
||||||
if (_appearance != null || Owner.TryGetComponent(out _appearance))
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
{
|
{
|
||||||
_appearance.SetData(PowerDeviceVisuals.VisualState, state);
|
appearance.SetData(PowerDeviceVisuals.VisualState, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor) || !_powered)
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor) || !Powered)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_uiDirty = true;
|
_uiDirty = true;
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!_powered)
|
if (!Powered)
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||||
Loc.GetString("It has no power!"));
|
Loc.GetString("It has no power!"));
|
||||||
@@ -232,8 +229,13 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//Get transfer amount. May be smaller than _transferAmount if not enough room
|
//Get transfer amount. May be smaller than _transferAmount if not enough room
|
||||||
var realTransferAmount = ReagentUnit.Min(attackPourable.TransferAmount, _solution.EmptyVolume);
|
var realTransferAmount = ReagentUnit.Min(attackPourable.TransferAmount, solution.EmptyVolume);
|
||||||
if (realTransferAmount <= 0) //Special message if container is full
|
if (realTransferAmount <= 0) //Special message if container is full
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||||
@@ -243,7 +245,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
|
|
||||||
//Move units from attackSolution to targetSolution
|
//Move units from attackSolution to targetSolution
|
||||||
var removedSolution = attackSolution.SplitSolution(realTransferAmount);
|
var removedSolution = attackSolution.SplitSolution(realTransferAmount);
|
||||||
if (!_solution.TryAddSolution(removedSolution))
|
if (!solution.TryAddSolution(removedSolution))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -280,6 +282,11 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
var solidsDict = new Dictionary<string, int>();
|
var solidsDict = new Dictionary<string, int>();
|
||||||
foreach(var item in _storage.ContainedEntities)
|
foreach(var item in _storage.ContainedEntities)
|
||||||
{
|
{
|
||||||
|
if (item.Prototype == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(solidsDict.ContainsKey(item.Prototype.ID))
|
if(solidsDict.ContainsKey(item.Prototype.ID))
|
||||||
{
|
{
|
||||||
solidsDict[item.Prototype.ID]++;
|
solidsDict[item.Prototype.ID]++;
|
||||||
@@ -303,7 +310,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check recipes
|
// Check recipes
|
||||||
FoodRecipePrototype recipeToCook = null;
|
FoodRecipePrototype? recipeToCook = null;
|
||||||
foreach (var r in _recipeManager.Recipes.Where(r => CanSatisfyRecipe(r, solidsDict) == MicrowaveSuccessState.RecipePass))
|
foreach (var r in _recipeManager.Recipes.Where(r => CanSatisfyRecipe(r, solidsDict) == MicrowaveSuccessState.RecipePass))
|
||||||
{
|
{
|
||||||
recipeToCook = r;
|
recipeToCook = r;
|
||||||
@@ -330,7 +337,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
{
|
{
|
||||||
if (goodMeal)
|
if (goodMeal)
|
||||||
{
|
{
|
||||||
SubtractContents(recipeToCook);
|
SubtractContents(recipeToCook!);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -357,12 +364,18 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
|
|
||||||
private void VaporizeReagents()
|
private void VaporizeReagents()
|
||||||
{
|
{
|
||||||
_solution.RemoveAllSolution();
|
if (Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
solution.RemoveAllSolution();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VaporizeReagentQuantity(Solution.ReagentQuantity reagentQuantity)
|
private void VaporizeReagentQuantity(Solution.ReagentQuantity reagentQuantity)
|
||||||
{
|
{
|
||||||
_solution.TryRemoveReagent(reagentQuantity.ReagentId, reagentQuantity.Quantity);
|
if (Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
solution?.TryRemoveReagent(reagentQuantity.ReagentId, reagentQuantity.Quantity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VaporizeSolids()
|
private void VaporizeSolids()
|
||||||
@@ -395,9 +408,14 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
|
|
||||||
private void SubtractContents(FoodRecipePrototype recipe)
|
private void SubtractContents(FoodRecipePrototype recipe)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach(var recipeReagent in recipe.IngredientsReagents)
|
foreach(var recipeReagent in recipe.IngredientsReagents)
|
||||||
{
|
{
|
||||||
_solution.TryRemoveReagent(recipeReagent.Key, ReagentUnit.New(recipeReagent.Value));
|
solution?.TryRemoveReagent(recipeReagent.Key, ReagentUnit.New(recipeReagent.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var recipeSolid in recipe.IngredientsSolids)
|
foreach (var recipeSolid in recipe.IngredientsSolids)
|
||||||
@@ -406,6 +424,11 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
{
|
{
|
||||||
foreach (var item in _storage.ContainedEntities)
|
foreach (var item in _storage.ContainedEntities)
|
||||||
{
|
{
|
||||||
|
if (item.Prototype == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.Prototype.ID == recipeSolid.Key)
|
if (item.Prototype.ID == recipeSolid.Key)
|
||||||
{
|
{
|
||||||
_storage.Remove(item);
|
_storage.Remove(item);
|
||||||
@@ -420,9 +443,14 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
|
|
||||||
private MicrowaveSuccessState CanSatisfyRecipe(FoodRecipePrototype recipe, Dictionary<string,int> solids)
|
private MicrowaveSuccessState CanSatisfyRecipe(FoodRecipePrototype recipe, Dictionary<string,int> solids)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
return MicrowaveSuccessState.RecipeFail;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var reagent in recipe.IngredientsReagents)
|
foreach (var reagent in recipe.IngredientsReagents)
|
||||||
{
|
{
|
||||||
if (!_solution.ContainsReagent(reagent.Key, out var amount))
|
if (!solution.ContainsReagent(reagent.Key, out var amount))
|
||||||
{
|
{
|
||||||
return MicrowaveSuccessState.RecipeFail;
|
return MicrowaveSuccessState.RecipeFail;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.Components.Mobs;
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -8,6 +9,7 @@ using Robust.Server.Interfaces.GameObjects;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components
|
namespace Content.Server.GameObjects.Components
|
||||||
{
|
{
|
||||||
@@ -15,19 +17,41 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class MagicMirrorComponent : SharedMagicMirrorComponent, IActivate
|
public class MagicMirrorComponent : SharedMagicMirrorComponent, IActivate
|
||||||
{
|
{
|
||||||
private BoundUserInterface _userInterface;
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(MagicMirrorUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(MagicMirrorUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
if (UserInterface != null)
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage -= OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
private static void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
{
|
{
|
||||||
if (!obj.Session.AttachedEntity.TryGetComponent(out HumanoidAppearanceComponent looks))
|
if (obj.Session.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!obj.Session.AttachedEntity.TryGetComponent(out HumanoidAppearanceComponent? looks))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -70,23 +94,23 @@ namespace Content.Server.GameObjects.Components
|
|||||||
|
|
||||||
public void Activate(ActivateEventArgs eventArgs)
|
public void Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eventArgs.User.TryGetComponent(out HumanoidAppearanceComponent looks))
|
if (!eventArgs.User.TryGetComponent(out HumanoidAppearanceComponent? looks))
|
||||||
{
|
{
|
||||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("You can't have any hair!"));
|
Owner.PopupMessage(eventArgs.User, Loc.GetString("You can't have any hair!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
|
|
||||||
var msg = new MagicMirrorInitialDataMessage(looks.Appearance.HairColor, looks.Appearance.FacialHairColor, looks.Appearance.HairStyleName,
|
var msg = new MagicMirrorInitialDataMessage(looks.Appearance.HairColor, looks.Appearance.FacialHairColor, looks.Appearance.HairStyleName,
|
||||||
looks.Appearance.FacialHairStyleName);
|
looks.Appearance.FacialHairStyleName);
|
||||||
|
|
||||||
_userInterface.SendMessage(msg, actor.playerSession);
|
UserInterface?.SendMessage(msg, actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
@@ -16,6 +17,7 @@ using Robust.Shared.Interfaces.GameObjects;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Medical
|
namespace Content.Server.GameObjects.Components.Medical
|
||||||
{
|
{
|
||||||
@@ -23,29 +25,34 @@ namespace Content.Server.GameObjects.Components.Medical
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class MedicalScannerComponent : SharedMedicalScannerComponent, IActivate
|
public class MedicalScannerComponent : SharedMedicalScannerComponent, IActivate
|
||||||
{
|
{
|
||||||
private AppearanceComponent _appearance;
|
private ContainerSlot _bodyContainer = default!;
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
private ContainerSlot _bodyContainer;
|
|
||||||
private readonly Vector2 _ejectOffset = new Vector2(-0.5f, 0f);
|
private readonly Vector2 _ejectOffset = new Vector2(-0.5f, 0f);
|
||||||
public bool IsOccupied => _bodyContainer.ContainedEntity != null;
|
public bool IsOccupied => _bodyContainer.ContainedEntity != null;
|
||||||
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
[ViewVariables]
|
||||||
private bool Powered => _powerReceiver.Powered;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(MedicalScannerUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
if (UserInterface != null)
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
{
|
||||||
.GetBoundUserInterface(MedicalScannerUiKey.Key);
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
}
|
||||||
_bodyContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-bodyContainer", Owner);
|
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
|
||||||
|
|
||||||
//TODO: write this so that it checks for a change in power events and acts accordingly.
|
_bodyContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-bodyContainer", Owner);
|
||||||
|
|
||||||
|
// TODO: write this so that it checks for a change in power events and acts accordingly.
|
||||||
var newState = GetUserInterfaceState();
|
var newState = GetUserInterfaceState();
|
||||||
_userInterface.SetState(newState);
|
UserInterface?.SetState(newState);
|
||||||
|
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
@@ -62,11 +69,15 @@ namespace Content.Server.GameObjects.Components.Medical
|
|||||||
var body = _bodyContainer.ContainedEntity;
|
var body = _bodyContainer.ContainedEntity;
|
||||||
if (body == null)
|
if (body == null)
|
||||||
{
|
{
|
||||||
_appearance.SetData(MedicalScannerVisuals.Status, MedicalScannerStatus.Open);
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
appearance?.SetData(MedicalScannerVisuals.Status, MedicalScannerStatus.Open);
|
||||||
|
};
|
||||||
|
|
||||||
return EmptyUIState;
|
return EmptyUIState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!body.TryGetComponent(out IDamageableComponent damageable) ||
|
if (!body.TryGetComponent(out IDamageableComponent? damageable) ||
|
||||||
damageable.CurrentDamageState == DamageState.Dead)
|
damageable.CurrentDamageState == DamageState.Dead)
|
||||||
{
|
{
|
||||||
return EmptyUIState;
|
return EmptyUIState;
|
||||||
@@ -86,7 +97,7 @@ namespace Content.Server.GameObjects.Components.Medical
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newState = GetUserInterfaceState();
|
var newState = GetUserInterfaceState();
|
||||||
_userInterface.SetState(newState);
|
UserInterface?.SetState(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MedicalScannerStatus GetStatusFromDamageState(DamageState damageState)
|
private MedicalScannerStatus GetStatusFromDamageState(DamageState damageState)
|
||||||
@@ -115,12 +126,15 @@ namespace Content.Server.GameObjects.Components.Medical
|
|||||||
|
|
||||||
private void UpdateAppearance()
|
private void UpdateAppearance()
|
||||||
{
|
{
|
||||||
_appearance.SetData(MedicalScannerVisuals.Status, GetStatus());
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
appearance.SetData(MedicalScannerVisuals.Status, GetStatus());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate(ActivateEventArgs args)
|
public void Activate(ActivateEventArgs args)
|
||||||
{
|
{
|
||||||
if (!args.User.TryGetComponent(out IActorComponent actor))
|
if (!args.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -128,7 +142,7 @@ namespace Content.Server.GameObjects.Components.Medical
|
|||||||
if (!Powered)
|
if (!Powered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Verb]
|
[Verb]
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ namespace Content.Server.GameObjects.Components.Mining
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
var spriteComponent = Owner.GetComponent<SpriteComponent>();
|
|
||||||
|
var spriteComponent = Owner.EnsureComponent<SpriteComponent>();
|
||||||
spriteComponent.LayerSetState(0, _random.Pick(SpriteStates));
|
spriteComponent.LayerSetState(0, _random.Pick(SpriteStates));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.EntitySystems.AI;
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.EntitySystems.AI;
|
||||||
using Content.Shared.GameObjects.Components.Movement;
|
using Content.Shared.GameObjects.Components.Movement;
|
||||||
using Robust.Server.AI;
|
using Robust.Server.AI;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -14,23 +15,23 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
[RegisterComponent, ComponentReference(typeof(IMoverComponent))]
|
[RegisterComponent, ComponentReference(typeof(IMoverComponent))]
|
||||||
public class AiControllerComponent : Component, IMoverComponent
|
public class AiControllerComponent : Component, IMoverComponent
|
||||||
{
|
{
|
||||||
private string _logicName;
|
private string? _logicName;
|
||||||
private float _visionRadius;
|
private float _visionRadius;
|
||||||
|
|
||||||
public override string Name => "AiController";
|
public override string Name => "AiController";
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public string LogicName
|
public string? LogicName
|
||||||
{
|
{
|
||||||
get => _logicName;
|
get => _logicName;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_logicName = value;
|
_logicName = value;
|
||||||
Processor = null;
|
Processor = null!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AiLogicProcessor Processor { get; set; }
|
public AiLogicProcessor? Processor { get; set; }
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float VisionRadius
|
public float VisionRadius
|
||||||
@@ -45,8 +46,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
// This component requires a collidable component.
|
// This component requires a collidable component.
|
||||||
if (!Owner.HasComponent<ICollidableComponent>())
|
Owner.EnsureComponent<CollidableComponent>();
|
||||||
Owner.AddComponent<CollidableComponent>();
|
|
||||||
|
|
||||||
EntitySystem.Get<AiSystem>().ProcessorInitialize(this);
|
EntitySystem.Get<AiSystem>().ProcessorInitialize(this);
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Owner.TryGetComponent(out MovementSpeedModifierComponent component))
|
if (Owner.TryGetComponent(out MovementSpeedModifierComponent? component))
|
||||||
{
|
{
|
||||||
return component.CurrentWalkSpeed;
|
return component.CurrentWalkSpeed;
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Owner.TryGetComponent(out MovementSpeedModifierComponent component))
|
if (Owner.TryGetComponent(out MovementSpeedModifierComponent? component))
|
||||||
{
|
{
|
||||||
return component.CurrentSprintSpeed;
|
return component.CurrentSprintSpeed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,10 +24,8 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
[ComponentReference(typeof(IClimbable))]
|
[ComponentReference(typeof(IClimbable))]
|
||||||
public class ClimbableComponent : SharedClimbableComponent, IDragDropOn
|
public class ClimbableComponent : SharedClimbableComponent, IDragDropOn
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The range from which this entity can be climbed.
|
/// The range from which this entity can be climbed.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Shared.GameObjects.Components.Movement;
|
using Content.Shared.GameObjects.Components.Movement;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -18,9 +19,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class ServerPortalComponent : SharedPortalComponent
|
public class ServerPortalComponent : SharedPortalComponent
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||||
[Dependency] private readonly IServerEntityManager _serverEntityManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
// Potential improvements: Different sounds,
|
// Potential improvements: Different sounds,
|
||||||
// Add Gateways
|
// Add Gateways
|
||||||
@@ -28,15 +27,14 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
// Put portal above most other things layer-wise
|
// Put portal above most other things layer-wise
|
||||||
// Add telefragging (get entities on connecting portal and force brute damage)
|
// Add telefragging (get entities on connecting portal and force brute damage)
|
||||||
|
|
||||||
private AppearanceComponent _appearanceComponent;
|
private IEntity? _connectingTeleporter;
|
||||||
private IEntity _connectingTeleporter;
|
|
||||||
private PortalState _state = PortalState.Pending;
|
private PortalState _state = PortalState.Pending;
|
||||||
[ViewVariables(VVAccess.ReadWrite)] private float _individualPortalCooldown;
|
[ViewVariables(VVAccess.ReadWrite)] private float _individualPortalCooldown;
|
||||||
[ViewVariables] private float _overallPortalCooldown;
|
[ViewVariables] private float _overallPortalCooldown;
|
||||||
[ViewVariables] private bool _onCooldown;
|
[ViewVariables] private bool _onCooldown;
|
||||||
[ViewVariables] private string _departureSound;
|
[ViewVariables] private string _departureSound = "";
|
||||||
[ViewVariables] private string _arrivalSound;
|
[ViewVariables] private string _arrivalSound = "";
|
||||||
public List<IEntity> immuneEntities = new List<IEntity>(); // K
|
public readonly List<IEntity> ImmuneEntities = new List<IEntity>(); // K
|
||||||
[ViewVariables(VVAccess.ReadWrite)] private float _aliveTime;
|
[ViewVariables(VVAccess.ReadWrite)] private float _aliveTime;
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
@@ -52,12 +50,6 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
serializer.DataField(ref _arrivalSound, "arrival_sound", "/Audio/Effects/teleport_arrival.ogg");
|
serializer.DataField(ref _arrivalSound, "arrival_sound", "/Audio/Effects/teleport_arrival.ogg");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
_appearanceComponent = Owner.GetComponent<AppearanceComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAdd()
|
public override void OnAdd()
|
||||||
{
|
{
|
||||||
// This will blow up an entity it's attached to
|
// This will blow up an entity it's attached to
|
||||||
@@ -74,13 +66,6 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
_appearanceComponent = null;
|
|
||||||
|
|
||||||
base.OnRemove();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanBeConnected()
|
public bool CanBeConnected()
|
||||||
{
|
{
|
||||||
if (_connectingTeleporter == null)
|
if (_connectingTeleporter == null)
|
||||||
@@ -108,23 +93,24 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
}
|
}
|
||||||
|
|
||||||
_state = targetState;
|
_state = targetState;
|
||||||
if (_appearanceComponent != null)
|
|
||||||
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
{
|
{
|
||||||
_appearanceComponent.SetData(PortalVisuals.State, _state);
|
appearance.SetData(PortalVisuals.State, _state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void releaseCooldown(IEntity entity)
|
private void ReleaseCooldown(IEntity entity)
|
||||||
{
|
{
|
||||||
if (immuneEntities.Contains(entity))
|
if (ImmuneEntities.Contains(entity))
|
||||||
{
|
{
|
||||||
immuneEntities.Remove(entity);
|
ImmuneEntities.Remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_connectingTeleporter != null &&
|
if (_connectingTeleporter != null &&
|
||||||
_connectingTeleporter.TryGetComponent<ServerPortalComponent>(out var otherPortal))
|
_connectingTeleporter.TryGetComponent<ServerPortalComponent>(out var otherPortal))
|
||||||
{
|
{
|
||||||
otherPortal.immuneEntities.Remove(entity);
|
otherPortal.ImmuneEntities.Remove(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +128,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
private bool IsEntityPortable(IEntity entity)
|
private bool IsEntityPortable(IEntity entity)
|
||||||
{
|
{
|
||||||
// TODO: Check if it's slotted etc. Otherwise the slot item itself gets ported.
|
// TODO: Check if it's slotted etc. Otherwise the slot item itself gets ported.
|
||||||
if (!immuneEntities.Contains(entity) && entity.HasComponent<TeleportableComponent>())
|
if (!ImmuneEntities.Contains(entity) && entity.HasComponent<TeleportableComponent>())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -192,7 +178,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
|
|
||||||
public void TryPortalEntity(IEntity entity)
|
public void TryPortalEntity(IEntity entity)
|
||||||
{
|
{
|
||||||
if (immuneEntities.Contains(entity) || _connectingTeleporter == null)
|
if (ImmuneEntities.Contains(entity) || _connectingTeleporter == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -208,9 +194,9 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
soundPlayer.PlayAtCoords(_arrivalSound, entity.Transform.GridPosition);
|
soundPlayer.PlayAtCoords(_arrivalSound, entity.Transform.GridPosition);
|
||||||
TryChangeState(PortalState.RecentlyTeleported);
|
TryChangeState(PortalState.RecentlyTeleported);
|
||||||
// To stop spam teleporting. Could potentially look at adding a timer to flush this from the portal
|
// To stop spam teleporting. Could potentially look at adding a timer to flush this from the portal
|
||||||
immuneEntities.Add(entity);
|
ImmuneEntities.Add(entity);
|
||||||
_connectingTeleporter.GetComponent<ServerPortalComponent>().immuneEntities.Add(entity);
|
_connectingTeleporter.GetComponent<ServerPortalComponent>().ImmuneEntities.Add(entity);
|
||||||
Timer.Spawn(TimeSpan.FromSeconds(_individualPortalCooldown), () => releaseCooldown(entity));
|
Timer.Spawn(TimeSpan.FromSeconds(_individualPortalCooldown), () => ReleaseCooldown(entity));
|
||||||
StartCooldown();
|
StartCooldown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Shared.GameObjects.Components.Movement;
|
using Content.Shared.GameObjects.Components.Movement;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -24,11 +25,10 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class ServerTeleporterComponent : Component, IAfterInteract
|
public class ServerTeleporterComponent : Component, IAfterInteract
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IMapManager _mapManager;
|
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||||
[Dependency] private readonly IServerEntityManager _serverEntityManager;
|
[Dependency] private readonly IRobustRandom _spreadRandom = default!;
|
||||||
[Dependency] private readonly IRobustRandom _spreadRandom;
|
|
||||||
#pragma warning restore 649
|
|
||||||
// TODO: Look at MapManager.Map for Beacons to get all entities on grid
|
// TODO: Look at MapManager.Map for Beacons to get all entities on grid
|
||||||
public ItemTeleporterState State => _state;
|
public ItemTeleporterState State => _state;
|
||||||
|
|
||||||
@@ -39,15 +39,13 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
[ViewVariables] private int _range;
|
[ViewVariables] private int _range;
|
||||||
[ViewVariables] private ItemTeleporterState _state;
|
[ViewVariables] private ItemTeleporterState _state;
|
||||||
[ViewVariables] private TeleporterType _teleporterType;
|
[ViewVariables] private TeleporterType _teleporterType;
|
||||||
[ViewVariables] private string _departureSound;
|
[ViewVariables] private string _departureSound = "";
|
||||||
[ViewVariables] private string _arrivalSound;
|
[ViewVariables] private string _arrivalSound = "";
|
||||||
[ViewVariables] private string _cooldownSound;
|
[ViewVariables] private string? _cooldownSound;
|
||||||
// If the direct OR random teleport will try to avoid hitting collidables
|
// If the direct OR random teleport will try to avoid hitting collidables
|
||||||
[ViewVariables] private bool _avoidCollidable;
|
[ViewVariables] private bool _avoidCollidable;
|
||||||
[ViewVariables] private float _portalAliveTime;
|
[ViewVariables] private float _portalAliveTime;
|
||||||
|
|
||||||
private AppearanceComponent _appearanceComponent;
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
base.ExposeData(serializer);
|
base.ExposeData(serializer);
|
||||||
@@ -63,22 +61,20 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
serializer.DataField(ref _portalAliveTime, "portal_alive_time", 5.0f); // TODO: Change this to 0 before PR?
|
serializer.DataField(ref _portalAliveTime, "portal_alive_time", 5.0f); // TODO: Change this to 0 before PR?
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
_appearanceComponent = null;
|
|
||||||
|
|
||||||
base.OnRemove();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetState(ItemTeleporterState newState)
|
private void SetState(ItemTeleporterState newState)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newState == ItemTeleporterState.Cooldown)
|
if (newState == ItemTeleporterState.Cooldown)
|
||||||
{
|
{
|
||||||
_appearanceComponent.SetData(TeleporterVisuals.VisualState, TeleporterVisualState.Charging);
|
appearance.SetData(TeleporterVisuals.VisualState, TeleporterVisualState.Charging);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_appearanceComponent.SetData(TeleporterVisuals.VisualState, TeleporterVisualState.Ready);
|
appearance.SetData(TeleporterVisuals.VisualState, TeleporterVisualState.Ready);
|
||||||
}
|
}
|
||||||
_state = newState;
|
_state = newState;
|
||||||
}
|
}
|
||||||
@@ -149,12 +145,11 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_appearanceComponent = Owner.GetComponent<AppearanceComponent>();
|
|
||||||
_state = ItemTeleporterState.Off;
|
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
_state = ItemTeleporterState.Off;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool emptySpace(IEntity user, Vector2 target)
|
private bool EmptySpace(IEntity user, Vector2 target)
|
||||||
{
|
{
|
||||||
// TODO: Check the user's spot? Upside is no stacking TPs but downside is they can't unstuck themselves from walls.
|
// TODO: Check the user's spot? Upside is no stacking TPs but downside is they can't unstuck themselves from walls.
|
||||||
foreach (var entity in _serverEntityManager.GetEntitiesIntersecting(user.Transform.MapID, target))
|
foreach (var entity in _serverEntityManager.GetEntitiesIntersecting(user.Transform.MapID, target))
|
||||||
@@ -167,7 +162,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 randomEmptySpot(IEntity user, int range)
|
private Vector2 RandomEmptySpot(IEntity user, int range)
|
||||||
{
|
{
|
||||||
Vector2 targetVector = user.Transform.GridPosition.Position;
|
Vector2 targetVector = user.Transform.GridPosition.Position;
|
||||||
// Definitely a better way to do this
|
// Definitely a better way to do this
|
||||||
@@ -176,7 +171,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
var randomRange = _spreadRandom.Next(0, range);
|
var randomRange = _spreadRandom.Next(0, range);
|
||||||
var angle = Angle.FromDegrees(_spreadRandom.Next(0, 359));
|
var angle = Angle.FromDegrees(_spreadRandom.Next(0, 359));
|
||||||
targetVector = user.Transform.GridPosition.Position + angle.ToVec() * randomRange;
|
targetVector = user.Transform.GridPosition.Position + angle.ToVec() * randomRange;
|
||||||
if (emptySpace(user, targetVector))
|
if (EmptySpace(user, targetVector))
|
||||||
{
|
{
|
||||||
return targetVector;
|
return targetVector;
|
||||||
}
|
}
|
||||||
@@ -200,7 +195,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
Vector2 targetVector;
|
Vector2 targetVector;
|
||||||
if (_avoidCollidable)
|
if (_avoidCollidable)
|
||||||
{
|
{
|
||||||
targetVector = randomEmptySpot(user, _range);
|
targetVector = RandomEmptySpot(user, _range);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -227,7 +222,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
public void Teleport(IEntity user, Vector2 vector)
|
public void Teleport(IEntity user, Vector2 vector)
|
||||||
{
|
{
|
||||||
// Messy maybe?
|
// Messy maybe?
|
||||||
GridCoordinates targetGrid = new GridCoordinates(vector, user.Transform.GridID);
|
var targetGrid = new GridCoordinates(vector, user.Transform.GridID);
|
||||||
var soundPlayer = EntitySystem.Get<AudioSystem>();
|
var soundPlayer = EntitySystem.Get<AudioSystem>();
|
||||||
|
|
||||||
// If portals use those, otherwise just move em over
|
// If portals use those, otherwise just move em over
|
||||||
@@ -240,11 +235,12 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
|
|
||||||
// Arrival portal
|
// Arrival portal
|
||||||
var arrivalPortal = _serverEntityManager.SpawnEntity("Portal", targetGrid);
|
var arrivalPortal = _serverEntityManager.SpawnEntity("Portal", targetGrid);
|
||||||
arrivalPortal.TryGetComponent<ServerPortalComponent>(out var arrivalComponent);
|
if (arrivalPortal.TryGetComponent<ServerPortalComponent>(out var arrivalComponent))
|
||||||
|
{
|
||||||
// Connect. TODO: If the OnUpdate in ServerPortalComponent is changed this may need to change as well.
|
// Connect. TODO: If the OnUpdate in ServerPortalComponent is changed this may need to change as well.
|
||||||
arrivalComponent.TryConnectPortal(departurePortal);
|
arrivalComponent.TryConnectPortal(departurePortal);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Departure
|
// Departure
|
||||||
|
|||||||
@@ -22,10 +22,8 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
[ComponentReference(typeof(IMoverComponent))]
|
[ComponentReference(typeof(IMoverComponent))]
|
||||||
internal class ShuttleControllerComponent : Component, IMoverComponent
|
internal class ShuttleControllerComponent : Component, IMoverComponent
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private bool _movingUp;
|
private bool _movingUp;
|
||||||
private bool _movingDown;
|
private bool _movingDown;
|
||||||
|
|||||||
@@ -48,7 +48,12 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
|
|||||||
|
|
||||||
public void AddApc(ApcComponent apc)
|
public void AddApc(ApcComponent apc)
|
||||||
{
|
{
|
||||||
_apcBatteries.Add(apc, apc.Battery);
|
if (!apc.Owner.TryGetComponent(out BatteryComponent battery))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_apcBatteries.Add(apc, battery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveApc(ApcComponent apc)
|
public void RemoveApc(ApcComponent apc)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components.Body.Digestive;
|
using Content.Server.GameObjects.Components.Body.Digestive;
|
||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
@@ -25,24 +26,30 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
[ComponentReference(typeof(IAfterInteract))]
|
[ComponentReference(typeof(IAfterInteract))]
|
||||||
public class FoodComponent : Component, IUse, IAfterInteract
|
public class FoodComponent : Component, IUse, IAfterInteract
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystem;
|
|
||||||
#pragma warning restore 649
|
|
||||||
public override string Name => "Food";
|
public override string Name => "Food";
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables] private string _useSound = "";
|
||||||
private string _useSound;
|
[ViewVariables] private string? _trashPrototype;
|
||||||
[ViewVariables]
|
[ViewVariables] private ReagentUnit _transferAmount;
|
||||||
private string _trashPrototype;
|
|
||||||
[ViewVariables]
|
|
||||||
private SolutionComponent _contents;
|
|
||||||
[ViewVariables]
|
|
||||||
private ReagentUnit _transferAmount;
|
|
||||||
private UtensilType _utensilsNeeded;
|
private UtensilType _utensilsNeeded;
|
||||||
|
|
||||||
public int UsesRemaining => _contents.CurrentVolume == 0
|
[ViewVariables]
|
||||||
?
|
public int UsesRemaining
|
||||||
0 : Math.Max(1, (int)Math.Ceiling((_contents.CurrentVolume / _transferAmount).Float()));
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return solution.CurrentVolume == 0
|
||||||
|
? 0
|
||||||
|
: Math.Max(1, (int)Math.Ceiling((solution.CurrentVolume / _transferAmount).Float()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
@@ -60,7 +67,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
{
|
{
|
||||||
var types = new List<UtensilType>();
|
var types = new List<UtensilType>();
|
||||||
|
|
||||||
foreach (UtensilType type in Enum.GetValues(typeof(UtensilType)))
|
foreach (var type in (UtensilType[]) Enum.GetValues(typeof(UtensilType)))
|
||||||
{
|
{
|
||||||
if ((_utensilsNeeded & type) != 0)
|
if ((_utensilsNeeded & type) != 0)
|
||||||
{
|
{
|
||||||
@@ -75,8 +82,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_contents = Owner.GetComponent<SolutionComponent>();
|
Owner.EnsureComponent<SolutionComponent>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
|
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
|
||||||
@@ -101,8 +107,13 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
TryUseFood(eventArgs.User, eventArgs.Target);
|
TryUseFood(eventArgs.User, eventArgs.Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool TryUseFood(IEntity user, IEntity target, UtensilComponent utensilUsed = null)
|
public virtual bool TryUseFood(IEntity? user, IEntity? target, UtensilComponent? utensilUsed = null)
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out SolutionComponent? solution))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -116,7 +127,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
|
|
||||||
var trueTarget = target ?? user;
|
var trueTarget = target ?? user;
|
||||||
|
|
||||||
if (!trueTarget.TryGetComponent(out StomachComponent stomach))
|
if (!trueTarget.TryGetComponent(out StomachComponent? stomach))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -130,11 +141,11 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
utensils = new List<UtensilComponent>();
|
utensils = new List<UtensilComponent>();
|
||||||
var types = UtensilType.None;
|
var types = UtensilType.None;
|
||||||
|
|
||||||
if (user.TryGetComponent(out HandsComponent hands))
|
if (user.TryGetComponent(out HandsComponent? hands))
|
||||||
{
|
{
|
||||||
foreach (var item in hands.GetAllHeldItems())
|
foreach (var item in hands.GetAllHeldItems())
|
||||||
{
|
{
|
||||||
if (!item.Owner.TryGetComponent(out UtensilComponent utensil))
|
if (!item.Owner.TryGetComponent(out UtensilComponent? utensil))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -156,11 +167,11 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var transferAmount = ReagentUnit.Min(_transferAmount, _contents.CurrentVolume);
|
var transferAmount = ReagentUnit.Min(_transferAmount, solution.CurrentVolume);
|
||||||
var split = _contents.SplitSolution(transferAmount);
|
var split = solution.SplitSolution(transferAmount);
|
||||||
if (!stomach.TryTransferSolution(split))
|
if (!stomach.TryTransferSolution(split))
|
||||||
{
|
{
|
||||||
_contents.TryAddSolution(split);
|
solution.TryAddSolution(split);
|
||||||
trueTarget.PopupMessage(user, Loc.GetString("You can't eat any more!"));
|
trueTarget.PopupMessage(user, Loc.GetString("You can't eat any more!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -194,13 +205,13 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
var finisher = Owner.EntityManager.SpawnEntity(_trashPrototype, position);
|
var finisher = Owner.EntityManager.SpawnEntity(_trashPrototype, position);
|
||||||
|
|
||||||
// If the user is holding the item
|
// If the user is holding the item
|
||||||
if (user.TryGetComponent(out HandsComponent handsComponent) &&
|
if (user.TryGetComponent(out HandsComponent? handsComponent) &&
|
||||||
handsComponent.IsHolding(Owner))
|
handsComponent.IsHolding(Owner))
|
||||||
{
|
{
|
||||||
Owner.Delete();
|
Owner.Delete();
|
||||||
|
|
||||||
// Put the trash in the user's hand
|
// Put the trash in the user's hand
|
||||||
if (finisher.TryGetComponent(out ItemComponent item) &&
|
if (finisher.TryGetComponent(out ItemComponent? item) &&
|
||||||
handsComponent.CanPutInHand(item))
|
handsComponent.CanPutInHand(item))
|
||||||
{
|
{
|
||||||
handsComponent.PutInHand(item);
|
handsComponent.PutInHand(item);
|
||||||
|
|||||||
@@ -37,21 +37,24 @@ namespace Content.Server.GameObjects.Components.PDA
|
|||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
|
|
||||||
[ViewVariables] private Container _idSlot = default!;
|
[ViewVariables] private Container _idSlot = default!;
|
||||||
[ViewVariables] private PointLightComponent _pdaLight = default!;
|
|
||||||
[ViewVariables] private bool _lightOn;
|
[ViewVariables] private bool _lightOn;
|
||||||
[ViewVariables] private BoundUserInterface _interface = default!;
|
|
||||||
[ViewVariables] private string _startingIdCard = default!;
|
[ViewVariables] private string _startingIdCard = default!;
|
||||||
[ViewVariables] public bool IdSlotEmpty => _idSlot.ContainedEntities.Count < 1;
|
[ViewVariables] public bool IdSlotEmpty => _idSlot.ContainedEntities.Count < 1;
|
||||||
[ViewVariables] public string? OwnerName { get; private set; }
|
[ViewVariables] public string? OwnerName { get; private set; }
|
||||||
|
|
||||||
[ViewVariables] public IdCardComponent? ContainedID { get; private set; }
|
[ViewVariables] public IdCardComponent? ContainedID { get; private set; }
|
||||||
|
|
||||||
[ViewVariables] private AppearanceComponent _appearance = default!;
|
|
||||||
|
|
||||||
[ViewVariables] private UplinkAccount? _syndicateUplinkAccount;
|
[ViewVariables] private UplinkAccount? _syndicateUplinkAccount;
|
||||||
|
|
||||||
[ViewVariables] private readonly PdaAccessSet _accessSet;
|
[ViewVariables] private readonly PdaAccessSet _accessSet;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(PDAUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public PDAComponent()
|
public PDAComponent()
|
||||||
{
|
{
|
||||||
_accessSet = new PdaAccessSet(this);
|
_accessSet = new PdaAccessSet(this);
|
||||||
@@ -67,11 +70,12 @@ namespace Content.Server.GameObjects.Components.PDA
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_idSlot = ContainerManagerComponent.Ensure<Container>("pda_entity_container", Owner, out var existed);
|
_idSlot = ContainerManagerComponent.Ensure<Container>("pda_entity_container", Owner, out var existed);
|
||||||
_pdaLight = Owner.GetComponent<PointLightComponent>();
|
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
if (UserInterface != null)
|
||||||
_interface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
{
|
||||||
.GetBoundUserInterface(PDAUiKey.Key);
|
UserInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||||
_interface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
}
|
||||||
|
|
||||||
var idCard = _entityManager.SpawnEntity(_startingIdCard, Owner.Transform.GridPosition);
|
var idCard = _entityManager.SpawnEntity(_startingIdCard, Owner.Transform.GridPosition);
|
||||||
var idCardComponent = idCard.GetComponent<IdCardComponent>();
|
var idCardComponent = idCard.GetComponent<IdCardComponent>();
|
||||||
_idSlot.Insert(idCardComponent.Owner);
|
_idSlot.Insert(idCardComponent.Owner);
|
||||||
@@ -129,11 +133,11 @@ namespace Content.Server.GameObjects.Components.PDA
|
|||||||
var accData = new UplinkAccountData(_syndicateUplinkAccount.AccountHolder,
|
var accData = new UplinkAccountData(_syndicateUplinkAccount.AccountHolder,
|
||||||
_syndicateUplinkAccount.Balance);
|
_syndicateUplinkAccount.Balance);
|
||||||
var listings = _uplinkManager.FetchListings.ToArray();
|
var listings = _uplinkManager.FetchListings.ToArray();
|
||||||
_interface.SetState(new PDAUpdateState(_lightOn, ownerInfo, accData, listings));
|
UserInterface?.SetState(new PDAUpdateState(_lightOn, ownerInfo, accData, listings));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_interface.SetState(new PDAUpdateState(_lightOn, ownerInfo));
|
UserInterface?.SetState(new PDAUpdateState(_lightOn, ownerInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePDAAppearance();
|
UpdatePDAAppearance();
|
||||||
@@ -141,7 +145,10 @@ namespace Content.Server.GameObjects.Components.PDA
|
|||||||
|
|
||||||
private void UpdatePDAAppearance()
|
private void UpdatePDAAppearance()
|
||||||
{
|
{
|
||||||
_appearance?.SetData(PDAVisuals.FlashlightLit, _lightOn);
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
appearance.SetData(PDAVisuals.FlashlightLit, _lightOn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
@@ -169,7 +176,7 @@ namespace Content.Server.GameObjects.Components.PDA
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_interface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
UpdatePDAAppearance();
|
UpdatePDAAppearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +187,7 @@ namespace Content.Server.GameObjects.Components.PDA
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_interface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
UpdatePDAAppearance();
|
UpdatePDAAppearance();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -217,8 +224,13 @@ namespace Content.Server.GameObjects.Components.PDA
|
|||||||
|
|
||||||
private void ToggleLight()
|
private void ToggleLight()
|
||||||
{
|
{
|
||||||
|
if (!Owner.TryGetComponent(out PointLightComponent? light))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_lightOn = !_lightOn;
|
_lightOn = !_lightOn;
|
||||||
_pdaLight.Enabled = _lightOn;
|
light.Enabled = _lightOn;
|
||||||
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Items/flashlight_toggle.ogg", Owner);
|
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Items/flashlight_toggle.ogg", Owner);
|
||||||
UpdatePDAUserInterface();
|
UpdatePDAUserInterface();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
#nullable enable
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -13,24 +14,30 @@ namespace Content.Server.GameObjects.Components.Paper
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class PaperComponent : SharedPaperComponent, IExamine, IInteractUsing, IUse
|
public class PaperComponent : SharedPaperComponent, IExamine, IInteractUsing, IUse
|
||||||
{
|
{
|
||||||
|
private string _content = "";
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
private string _content;
|
|
||||||
private PaperAction _mode;
|
private PaperAction _mode;
|
||||||
|
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(PaperUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(PaperUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
{
|
||||||
_content = "";
|
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
_mode = PaperAction.Read;
|
_mode = PaperAction.Read;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
private void UpdateUserInterface()
|
private void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
_userInterface.SetState(new PaperBoundUserInterfaceState(_content, _mode));
|
UserInterface?.SetState(new PaperBoundUserInterfaceState(_content, _mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Examine(FormattedMessage message, bool inDetailsRange)
|
public void Examine(FormattedMessage message, bool inDetailsRange)
|
||||||
@@ -43,11 +50,12 @@ namespace Content.Server.GameObjects.Components.Paper
|
|||||||
|
|
||||||
public bool UseEntity(UseEntityEventArgs eventArgs)
|
public bool UseEntity(UseEntityEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_mode = PaperAction.Read;
|
_mode = PaperAction.Read;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +67,7 @@ namespace Content.Server.GameObjects.Components.Paper
|
|||||||
|
|
||||||
_content += msg.Text + '\n';
|
_content += msg.Text + '\n';
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out SpriteComponent sprite))
|
if (Owner.TryGetComponent(out SpriteComponent? sprite))
|
||||||
{
|
{
|
||||||
sprite.LayerSetState(1, "paper_words");
|
sprite.LayerSetState(1, "paper_words");
|
||||||
}
|
}
|
||||||
@@ -71,12 +79,12 @@ namespace Content.Server.GameObjects.Components.Paper
|
|||||||
{
|
{
|
||||||
if (!eventArgs.Using.HasComponent<WriteComponent>())
|
if (!eventArgs.Using.HasComponent<WriteComponent>())
|
||||||
return false;
|
return false;
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_mode = PaperAction.Write;
|
_mode = PaperAction.Write;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
|
using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
|
||||||
using Content.Server.GameObjects.Components.Power.PowerNetComponents;
|
using Content.Server.GameObjects.Components.Power.PowerNetComponents;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
@@ -20,17 +21,12 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class ApcComponent : BaseApcNetComponent, IActivate
|
public class ApcComponent : BaseApcNetComponent, IActivate
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
public override string Name => "Apc";
|
public override string Name => "Apc";
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public BatteryComponent Battery { get; private set; }
|
|
||||||
|
|
||||||
public bool MainBreakerEnabled { get; private set; } = true;
|
public bool MainBreakerEnabled { get; private set; } = true;
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
|
|
||||||
private AppearanceComponent _appearance;
|
|
||||||
|
|
||||||
private ApcChargeState _lastChargeState;
|
private ApcChargeState _lastChargeState;
|
||||||
|
|
||||||
private TimeSpan _lastChargeStateChange;
|
private TimeSpan _lastChargeStateChange;
|
||||||
@@ -39,7 +35,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
|||||||
|
|
||||||
private TimeSpan _lastExternalPowerStateChange;
|
private TimeSpan _lastExternalPowerStateChange;
|
||||||
|
|
||||||
private float _lastCharge = 0f;
|
private float _lastCharge;
|
||||||
|
|
||||||
private TimeSpan _lastChargeChange;
|
private TimeSpan _lastChargeChange;
|
||||||
|
|
||||||
@@ -49,17 +45,27 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
|||||||
|
|
||||||
private const int VisualsChangeDelay = 1;
|
private const int VisualsChangeDelay = 1;
|
||||||
|
|
||||||
#pragma warning disable 649
|
[ViewVariables]
|
||||||
[Dependency] private readonly IGameTiming _gameTiming;
|
private BoundUserInterface? UserInterface =>
|
||||||
#pragma warning restore 649
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(ApcUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
|
public BatteryComponent? Battery => Owner.TryGetComponent(out BatteryComponent? batteryComponent) ? batteryComponent : null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
Battery = Owner.GetComponent<BatteryComponent>();
|
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
Owner.EnsureComponent<BatteryComponent>();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(ApcUiKey.Key);
|
Owner.EnsureComponent<PowerConsumerComponent>();
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
|
||||||
|
if (UserInterface != null)
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,15 +96,23 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
|||||||
{
|
{
|
||||||
_lastChargeState = newState;
|
_lastChargeState = newState;
|
||||||
_lastChargeStateChange = _gameTiming.CurTime;
|
_lastChargeStateChange = _gameTiming.CurTime;
|
||||||
_appearance.SetData(ApcVisuals.ChargeState, newState);
|
|
||||||
}
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
var newCharge = Battery.CurrentCharge;
|
|
||||||
if (newCharge != _lastCharge && _lastChargeChange + TimeSpan.FromSeconds(VisualsChangeDelay) < _gameTiming.CurTime)
|
|
||||||
{
|
{
|
||||||
_lastCharge = newCharge;
|
appearance.SetData(ApcVisuals.ChargeState, newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Owner.TryGetComponent(out BatteryComponent? battery);
|
||||||
|
|
||||||
|
var newCharge = battery?.CurrentCharge;
|
||||||
|
if (newCharge != null && newCharge != _lastCharge && _lastChargeChange + TimeSpan.FromSeconds(VisualsChangeDelay) < _gameTiming.CurTime)
|
||||||
|
{
|
||||||
|
_lastCharge = newCharge.Value;
|
||||||
_lastChargeChange = _gameTiming.CurTime;
|
_lastChargeChange = _gameTiming.CurTime;
|
||||||
_uiDirty = true;
|
_uiDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var extPowerState = CalcExtPowerState();
|
var extPowerState = CalcExtPowerState();
|
||||||
if (extPowerState != _lastExternalPowerState && _lastExternalPowerStateChange + TimeSpan.FromSeconds(VisualsChangeDelay) < _gameTiming.CurTime)
|
if (extPowerState != _lastExternalPowerState && _lastExternalPowerStateChange + TimeSpan.FromSeconds(VisualsChangeDelay) < _gameTiming.CurTime)
|
||||||
{
|
{
|
||||||
@@ -106,21 +120,33 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
|||||||
_lastExternalPowerStateChange = _gameTiming.CurTime;
|
_lastExternalPowerStateChange = _gameTiming.CurTime;
|
||||||
_uiDirty = true;
|
_uiDirty = true;
|
||||||
}
|
}
|
||||||
if (_uiDirty)
|
|
||||||
|
if (_uiDirty && battery != null && newCharge != null)
|
||||||
{
|
{
|
||||||
_userInterface.SetState(new ApcBoundInterfaceState(MainBreakerEnabled, extPowerState, newCharge / Battery.MaxCharge));
|
UserInterface?.SetState(new ApcBoundInterfaceState(MainBreakerEnabled, extPowerState, newCharge.Value / battery.MaxCharge));
|
||||||
_uiDirty = false;
|
_uiDirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApcChargeState CalcChargeState()
|
private ApcChargeState CalcChargeState()
|
||||||
{
|
{
|
||||||
var chargeFraction = Battery.CurrentCharge / Battery.MaxCharge;
|
if (!Owner.TryGetComponent(out BatteryComponent? battery))
|
||||||
|
{
|
||||||
|
return ApcChargeState.Lack;
|
||||||
|
}
|
||||||
|
|
||||||
|
var chargeFraction = battery.CurrentCharge / battery.MaxCharge;
|
||||||
|
|
||||||
if (chargeFraction > HighPowerThreshold)
|
if (chargeFraction > HighPowerThreshold)
|
||||||
{
|
{
|
||||||
return ApcChargeState.Full;
|
return ApcChargeState.Full;
|
||||||
}
|
}
|
||||||
var consumer = Owner.GetComponent<PowerConsumerComponent>();
|
|
||||||
|
if (!Owner.TryGetComponent(out PowerConsumerComponent? consumer))
|
||||||
|
{
|
||||||
|
return ApcChargeState.Full;
|
||||||
|
}
|
||||||
|
|
||||||
if (consumer.DrawRate == consumer.ReceivedPower)
|
if (consumer.DrawRate == consumer.ReceivedPower)
|
||||||
{
|
{
|
||||||
return ApcChargeState.Charging;
|
return ApcChargeState.Charging;
|
||||||
@@ -133,7 +159,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
|||||||
|
|
||||||
private ApcExternalPowerState CalcExtPowerState()
|
private ApcExternalPowerState CalcExtPowerState()
|
||||||
{
|
{
|
||||||
if (!Owner.TryGetComponent(out BatteryStorageComponent batteryStorage))
|
if (!Owner.TryGetComponent(out BatteryStorageComponent? batteryStorage))
|
||||||
{
|
{
|
||||||
return ApcExternalPowerState.None;
|
return ApcExternalPowerState.None;
|
||||||
}
|
}
|
||||||
@@ -154,11 +180,12 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
|||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_userInterface.Open(actor.playerSession);
|
|
||||||
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.GUI;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
@@ -24,19 +25,14 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
public abstract class BaseCharger : Component, IActivate, IInteractUsing
|
public abstract class BaseCharger : Component, IActivate, IInteractUsing
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private BatteryComponent _heldBattery;
|
private BatteryComponent? _heldBattery;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private ContainerSlot _container;
|
private ContainerSlot _container = default!;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private CellChargerStatus _status;
|
private CellChargerStatus _status;
|
||||||
|
|
||||||
private AppearanceComponent _appearanceComponent;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private int _chargeRate;
|
private int _chargeRate;
|
||||||
|
|
||||||
@@ -53,16 +49,25 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
|
||||||
|
Owner.EnsureComponent<PowerReceiverComponent>();
|
||||||
_container = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-powerCellContainer", Owner);
|
_container = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-powerCellContainer", Owner);
|
||||||
_appearanceComponent = Owner.GetComponent<AppearanceComponent>();
|
|
||||||
// Default state in the visualizer is OFF, so when this gets powered on during initialization it will generally show empty
|
// Default state in the visualizer is OFF, so when this gets powered on during initialization it will generally show empty
|
||||||
_powerReceiver.OnPowerStateChanged += PowerUpdate;
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
|
{
|
||||||
|
receiver.OnPowerStateChanged += PowerUpdate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
_powerReceiver.OnPowerStateChanged -= PowerUpdate;
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
|
{
|
||||||
|
receiver.OnPowerStateChanged -= PowerUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
_heldBattery = null;
|
||||||
|
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,12 +102,12 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
|
|
||||||
_container.Remove(heldItem);
|
_container.Remove(heldItem);
|
||||||
_heldBattery = null;
|
_heldBattery = null;
|
||||||
if (user.TryGetComponent(out HandsComponent handsComponent))
|
if (user.TryGetComponent(out HandsComponent? handsComponent))
|
||||||
{
|
{
|
||||||
handsComponent.PutInHandOrDrop(heldItem.GetComponent<ItemComponent>());
|
handsComponent.PutInHandOrDrop(heldItem.GetComponent<ItemComponent>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (heldItem.TryGetComponent(out ServerBatteryBarrelComponent batteryBarrelComponent))
|
if (heldItem.TryGetComponent(out ServerBatteryBarrelComponent? batteryBarrelComponent))
|
||||||
{
|
{
|
||||||
batteryBarrelComponent.UpdateAppearance();
|
batteryBarrelComponent.UpdateAppearance();
|
||||||
}
|
}
|
||||||
@@ -110,7 +115,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PowerUpdate(object sender, PowerStateEventArgs eventArgs)
|
private void PowerUpdate(object? sender, PowerStateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
@@ -125,7 +130,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
data.Visibility = VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
if (!user.TryGetComponent(out HandsComponent? handsComponent))
|
||||||
{
|
{
|
||||||
data.Visibility = VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
return;
|
return;
|
||||||
@@ -143,7 +148,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
|
|
||||||
protected override void Activate(IEntity user, BaseCharger component)
|
protected override void Activate(IEntity user, BaseCharger component)
|
||||||
{
|
{
|
||||||
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
if (!user.TryGetComponent(out HandsComponent? handsComponent))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -186,7 +191,8 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
|
|
||||||
private CellChargerStatus GetStatus()
|
private CellChargerStatus GetStatus()
|
||||||
{
|
{
|
||||||
if (!_powerReceiver.Powered)
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver) &&
|
||||||
|
!receiver.Powered)
|
||||||
{
|
{
|
||||||
return CellChargerStatus.Off;
|
return CellChargerStatus.Off;
|
||||||
}
|
}
|
||||||
@@ -227,34 +233,39 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
{
|
{
|
||||||
// Not called UpdateAppearance just because it messes with the load
|
// Not called UpdateAppearance just because it messes with the load
|
||||||
var status = GetStatus();
|
var status = GetStatus();
|
||||||
if (_status == status)
|
if (_status == status ||
|
||||||
|
!Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_status = status;
|
_status = status;
|
||||||
|
Owner.TryGetComponent(out AppearanceComponent? appearance);
|
||||||
|
|
||||||
switch (_status)
|
switch (_status)
|
||||||
{
|
{
|
||||||
// Update load just in case
|
// Update load just in case
|
||||||
case CellChargerStatus.Off:
|
case CellChargerStatus.Off:
|
||||||
_powerReceiver.Load = 0;
|
receiver.Load = 0;
|
||||||
_appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Off);
|
appearance?.SetData(CellVisual.Light, CellChargerStatus.Off);
|
||||||
break;
|
break;
|
||||||
case CellChargerStatus.Empty:
|
case CellChargerStatus.Empty:
|
||||||
_powerReceiver.Load = 0;
|
receiver.Load = 0;
|
||||||
_appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Empty); ;
|
appearance?.SetData(CellVisual.Light, CellChargerStatus.Empty);
|
||||||
break;
|
break;
|
||||||
case CellChargerStatus.Charging:
|
case CellChargerStatus.Charging:
|
||||||
_powerReceiver.Load = (int) (_chargeRate / _transferEfficiency);
|
receiver.Load = (int) (_chargeRate / _transferEfficiency);
|
||||||
_appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Charging);
|
appearance?.SetData(CellVisual.Light, CellChargerStatus.Charging);
|
||||||
break;
|
break;
|
||||||
case CellChargerStatus.Charged:
|
case CellChargerStatus.Charged:
|
||||||
_powerReceiver.Load = 0;
|
receiver.Load = 0;
|
||||||
_appearanceComponent?.SetData(CellVisual.Light, CellChargerStatus.Charged);
|
appearance?.SetData(CellVisual.Light, CellChargerStatus.Charged);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
_appearanceComponent?.SetData(CellVisual.Occupied, _container.ContainedEntity != null);
|
|
||||||
|
appearance?.SetData(CellVisual.Occupied, _container.ContainedEntity != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnUpdate(float frameTime) //todo: make single system for this
|
public void OnUpdate(float frameTime) //todo: make single system for this
|
||||||
@@ -268,10 +279,17 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
|
|
||||||
private void TransferPower(float frameTime)
|
private void TransferPower(float frameTime)
|
||||||
{
|
{
|
||||||
if (!_powerReceiver.Powered)
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver) &&
|
||||||
|
!receiver.Powered)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_heldBattery == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_heldBattery.CurrentCharge += _chargeRate * frameTime;
|
_heldBattery.CurrentCharge += _chargeRate * frameTime;
|
||||||
// Just so the sprite won't be set to 99.99999% visibility
|
// Just so the sprite won't be set to 99.99999% visibility
|
||||||
if (_heldBattery.MaxCharge - _heldBattery.CurrentCharge < 0.01)
|
if (_heldBattery.MaxCharge - _heldBattery.CurrentCharge < 0.01)
|
||||||
|
|||||||
@@ -108,7 +108,11 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
|
|
||||||
public void UpdateColor()
|
public void UpdateColor()
|
||||||
{
|
{
|
||||||
var sprite = Owner.GetComponent<SpriteComponent>();
|
if (!Owner.TryGetComponent(out SpriteComponent sprite))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sprite.Color = Color;
|
sprite.Color = Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -225,14 +225,18 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
Owner.GetComponent<PowerReceiverComponent>().OnPowerStateChanged += UpdateLight;
|
Owner.EnsureComponent<PowerReceiverComponent>().OnPowerStateChanged += UpdateLight;
|
||||||
|
|
||||||
_lightBulbContainer = ContainerManagerComponent.Ensure<ContainerSlot>("light_bulb", Owner);
|
_lightBulbContainer = ContainerManagerComponent.Ensure<ContainerSlot>("light_bulb", Owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
Owner.GetComponent<PowerReceiverComponent>().OnPowerStateChanged -= UpdateLight;
|
if (Owner.TryGetComponent(out PowerReceiverComponent receiver))
|
||||||
|
{
|
||||||
|
receiver.OnPowerStateChanged -= UpdateLight;
|
||||||
|
}
|
||||||
|
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,9 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
public override string Name => "PowerCell";
|
public override string Name => "PowerCell";
|
||||||
|
|
||||||
private AppearanceComponent _appearance;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
|
||||||
CurrentCharge = MaxCharge;
|
CurrentCharge = MaxCharge;
|
||||||
UpdateVisuals();
|
UpdateVisuals();
|
||||||
}
|
}
|
||||||
@@ -31,7 +28,10 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
|
|
||||||
private void UpdateVisuals()
|
private void UpdateVisuals()
|
||||||
{
|
{
|
||||||
_appearance?.SetData(PowerCellVisuals.ChargeLevel, CurrentCharge / MaxCharge);
|
if (Owner.TryGetComponent(out AppearanceComponent appearance))
|
||||||
|
{
|
||||||
|
appearance.SetData(PowerCellVisuals.ChargeLevel, CurrentCharge / MaxCharge);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_battery = Owner.GetComponent<BatteryComponent>();
|
|
||||||
_supplier = Owner.GetComponent<PowerSupplierComponent>();
|
_battery = Owner.EnsureComponent<BatteryComponent>();
|
||||||
|
_supplier = Owner.EnsureComponent<PowerSupplierComponent>();
|
||||||
UpdateSupplyRate();
|
UpdateSupplyRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_battery = Owner.GetComponent<BatteryComponent>();
|
|
||||||
Consumer = Owner.GetComponent<PowerConsumerComponent>();
|
_battery = Owner.EnsureComponent<BatteryComponent>();
|
||||||
|
Consumer = Owner.EnsureComponent<PowerConsumerComponent>();
|
||||||
UpdateDrawRate();
|
UpdateDrawRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using Content.Shared.Utility;
|
using Content.Shared.Utility;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -16,13 +17,11 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class SmesComponent : Component
|
public class SmesComponent : Component
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
public override string Name => "Smes";
|
public override string Name => "Smes";
|
||||||
|
|
||||||
private BatteryComponent _battery;
|
private int _lastChargeLevel;
|
||||||
|
|
||||||
private AppearanceComponent _appearance;
|
|
||||||
|
|
||||||
private int _lastChargeLevel = 0;
|
|
||||||
|
|
||||||
private TimeSpan _lastChargeLevelChange;
|
private TimeSpan _lastChargeLevelChange;
|
||||||
|
|
||||||
@@ -32,15 +31,12 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
|
|
||||||
private const int VisualsChangeDelay = 1;
|
private const int VisualsChangeDelay = 1;
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameTiming _gameTiming;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_battery = Owner.GetComponent<BatteryComponent>();
|
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
Owner.EnsureComponent<BatteryComponent>();
|
||||||
|
Owner.EnsureComponent<AppearanceComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnUpdate()
|
public void OnUpdate()
|
||||||
@@ -50,7 +46,11 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
{
|
{
|
||||||
_lastChargeLevel = newLevel;
|
_lastChargeLevel = newLevel;
|
||||||
_lastChargeLevelChange = _gameTiming.CurTime;
|
_lastChargeLevelChange = _gameTiming.CurTime;
|
||||||
_appearance.SetData(SmesVisuals.LastChargeLevel, newLevel);
|
|
||||||
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
appearance.SetData(SmesVisuals.LastChargeLevel, newLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newChargeState = GetNewChargeState();
|
var newChargeState = GetNewChargeState();
|
||||||
@@ -58,13 +58,22 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
{
|
{
|
||||||
_lastChargeState = newChargeState;
|
_lastChargeState = newChargeState;
|
||||||
_lastChargeStateChange = _gameTiming.CurTime;
|
_lastChargeStateChange = _gameTiming.CurTime;
|
||||||
_appearance.SetData(SmesVisuals.LastChargeState, newChargeState);
|
|
||||||
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
appearance.SetData(SmesVisuals.LastChargeState, newChargeState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetNewChargeLevel()
|
private int GetNewChargeLevel()
|
||||||
{
|
{
|
||||||
return ContentHelpers.RoundToLevels(_battery.CurrentCharge, _battery.MaxCharge, 6);
|
if (!Owner.TryGetComponent(out BatteryComponent? battery))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ContentHelpers.RoundToLevels(battery.CurrentCharge, battery.MaxCharge, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChargeState GetNewChargeState()
|
private ChargeState GetNewChargeState()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -7,6 +8,7 @@ using Robust.Server.Interfaces.GameObjects;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
||||||
{
|
{
|
||||||
@@ -14,28 +16,34 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class SolarControlConsoleComponent : SharedSolarControlConsoleComponent, IActivate
|
public class SolarControlConsoleComponent : SharedSolarControlConsoleComponent, IActivate
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||||
[Dependency] private IEntitySystemManager _entitySystemManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
private PowerSolarSystem _powerSolarSystem = default!;
|
||||||
private PowerReceiverComponent _powerReceiver;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private PowerSolarSystem _powerSolarSystem;
|
|
||||||
private bool Powered => _powerReceiver.Powered;
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(SolarControlConsoleUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(SolarControlConsoleUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
{
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
UserInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
Owner.EnsureComponent<PowerReceiverComponent>();
|
||||||
_powerSolarSystem = _entitySystemManager.GetEntitySystem<PowerSolarSystem>();
|
_powerSolarSystem = _entitySystemManager.GetEntitySystem<PowerSolarSystem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateUIState()
|
public void UpdateUIState()
|
||||||
{
|
{
|
||||||
_userInterface.SetState(new SolarControlConsoleBoundInterfaceState(_powerSolarSystem.TargetPanelRotation, _powerSolarSystem.TargetPanelVelocity, _powerSolarSystem.TotalPanelPower, _powerSolarSystem.TowardsSun));
|
UserInterface?.SetState(new SolarControlConsoleBoundInterfaceState(_powerSolarSystem.TargetPanelRotation, _powerSolarSystem.TargetPanelVelocity, _powerSolarSystem.TotalPanelPower, _powerSolarSystem.TowardsSun));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
@@ -57,7 +65,7 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -69,7 +77,7 @@ namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
|
|||||||
|
|
||||||
// always update the UI immediately before opening, just in case
|
// always update the UI immediately before opening, just in case
|
||||||
UpdateUIState();
|
UpdateUIState();
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,17 +15,16 @@ namespace Content.Server.GameObjects.Components.Projectiles
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
if (!Owner.HasComponent<ExplosiveComponent>())
|
|
||||||
{
|
Owner.EnsureComponent<ExplosiveComponent>();
|
||||||
Logger.Error("ExplosiveProjectiles need an ExplosiveComponent");
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICollideBehavior.CollideWith(IEntity entity)
|
void ICollideBehavior.CollideWith(IEntity entity)
|
||||||
{
|
{
|
||||||
var explosiveComponent = Owner.GetComponent<ExplosiveComponent>();
|
if (Owner.TryGetComponent(out ExplosiveComponent explosive))
|
||||||
explosiveComponent.Explosion();
|
{
|
||||||
|
explosive.Explosion();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Projectile should handle the deleting
|
// Projectile should handle the deleting
|
||||||
|
|||||||
@@ -31,10 +31,7 @@ namespace Content.Server.GameObjects.Components.Projectiles
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
// Shouldn't be using this without a ProjectileComponent because it will just immediately collide with thrower
|
// Shouldn't be using this without a ProjectileComponent because it will just immediately collide with thrower
|
||||||
if (!Owner.HasComponent<ProjectileComponent>())
|
Owner.EnsureComponent<ProjectileComponent>();
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICollideBehavior.CollideWith(IEntity entity)
|
void ICollideBehavior.CollideWith(IEntity entity)
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
class RadioComponent : Component, IUse, IListen
|
class RadioComponent : Component, IUse, IListen
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "Radio";
|
public override string Name => "Radio";
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,7 @@ namespace Content.Server.GameObjects.Components.Recycling
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class RecyclerComponent : Component, ICollideBehavior
|
public class RecyclerComponent : Component, ICollideBehavior
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "Recycler";
|
public override string Name => "Recycler";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -25,15 +26,12 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
{
|
{
|
||||||
public const int VolumePerSheet = 3750;
|
public const int VolumePerSheet = 3750;
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public Queue<LatheRecipePrototype> Queue { get; } = new Queue<LatheRecipePrototype>();
|
public Queue<LatheRecipePrototype> Queue { get; } = new Queue<LatheRecipePrototype>();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool Producing { get; private set; } = false;
|
public bool Producing { get; private set; }
|
||||||
|
|
||||||
private AppearanceComponent _appearance;
|
|
||||||
private LatheState _state = LatheState.Base;
|
private LatheState _state = LatheState.Base;
|
||||||
|
|
||||||
protected virtual LatheState State
|
protected virtual LatheState State
|
||||||
@@ -42,19 +40,26 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
set => _state = value;
|
set => _state = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LatheRecipePrototype _producingRecipe = null;
|
private LatheRecipePrototype? _producingRecipe;
|
||||||
private PowerReceiverComponent _powerReceiver;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private bool Powered => _powerReceiver.Powered;
|
|
||||||
|
|
||||||
private static readonly TimeSpan InsertionTime = TimeSpan.FromSeconds(0.9f);
|
private static readonly TimeSpan InsertionTime = TimeSpan.FromSeconds(0.9f);
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(LatheUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(LatheUiKey.Key);
|
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
if (UserInterface != null)
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
{
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
||||||
@@ -66,28 +71,28 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
{
|
{
|
||||||
case LatheQueueRecipeMessage msg:
|
case LatheQueueRecipeMessage msg:
|
||||||
_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe);
|
_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe);
|
||||||
if (recipe != null)
|
if (recipe != null!)
|
||||||
for (var i = 0; i < msg.Quantity; i++)
|
for (var i = 0; i < msg.Quantity; i++)
|
||||||
{
|
{
|
||||||
Queue.Enqueue(recipe);
|
Queue.Enqueue(recipe);
|
||||||
_userInterface.SendMessage(new LatheFullQueueMessage(GetIDQueue()));
|
UserInterface?.SendMessage(new LatheFullQueueMessage(GetIdQueue()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LatheSyncRequestMessage msg:
|
case LatheSyncRequestMessage _:
|
||||||
if (!Owner.TryGetComponent(out MaterialStorageComponent storage)) return;
|
if (!Owner.HasComponent<MaterialStorageComponent>()) return;
|
||||||
_userInterface.SendMessage(new LatheFullQueueMessage(GetIDQueue()));
|
UserInterface?.SendMessage(new LatheFullQueueMessage(GetIdQueue()));
|
||||||
if (_producingRecipe != null)
|
if (_producingRecipe != null)
|
||||||
_userInterface.SendMessage(new LatheProducingRecipeMessage(_producingRecipe.ID));
|
UserInterface?.SendMessage(new LatheProducingRecipeMessage(_producingRecipe.ID));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LatheServerSelectionMessage msg:
|
case LatheServerSelectionMessage _:
|
||||||
if (!Owner.TryGetComponent(out ResearchClientComponent researchClient)) return;
|
if (!Owner.TryGetComponent(out ResearchClientComponent? researchClient)) return;
|
||||||
researchClient.OpenUserInterface(message.Session);
|
researchClient.OpenUserInterface(message.Session);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LatheServerSyncMessage msg:
|
case LatheServerSyncMessage _:
|
||||||
if (!Owner.TryGetComponent(out TechnologyDatabaseComponent database)
|
if (!Owner.TryGetComponent(out TechnologyDatabaseComponent? database)
|
||||||
|| !Owner.TryGetComponent(out ProtolatheDatabaseComponent protoDatabase)) return;
|
|| !Owner.TryGetComponent(out ProtolatheDatabaseComponent? protoDatabase)) return;
|
||||||
|
|
||||||
if (database.SyncWithServer())
|
if (database.SyncWithServer())
|
||||||
protoDatabase.Sync();
|
protoDatabase.Sync();
|
||||||
@@ -103,9 +108,9 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Producing || !CanProduce(recipe) || !Owner.TryGetComponent(out MaterialStorageComponent storage)) return false;
|
if (Producing || !CanProduce(recipe) || !Owner.TryGetComponent(out MaterialStorageComponent? storage)) return false;
|
||||||
|
|
||||||
_userInterface.SendMessage(new LatheFullQueueMessage(GetIDQueue()));
|
UserInterface?.SendMessage(new LatheFullQueueMessage(GetIdQueue()));
|
||||||
|
|
||||||
Producing = true;
|
Producing = true;
|
||||||
_producingRecipe = recipe;
|
_producingRecipe = recipe;
|
||||||
@@ -116,7 +121,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
storage.RemoveMaterial(material, amount);
|
storage.RemoveMaterial(material, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.SendMessage(new LatheProducingRecipeMessage(recipe.ID));
|
UserInterface?.SendMessage(new LatheProducingRecipeMessage(recipe.ID));
|
||||||
|
|
||||||
State = LatheState.Producing;
|
State = LatheState.Producing;
|
||||||
SetAppearance(LatheVisualState.Producing);
|
SetAppearance(LatheVisualState.Producing);
|
||||||
@@ -126,7 +131,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
Producing = false;
|
Producing = false;
|
||||||
_producingRecipe = null;
|
_producingRecipe = null;
|
||||||
Owner.EntityManager.SpawnEntity(recipe.Result, Owner.Transform.GridPosition);
|
Owner.EntityManager.SpawnEntity(recipe.Result, Owner.Transform.GridPosition);
|
||||||
_userInterface.SendMessage(new LatheStoppedProducingRecipeMessage());
|
UserInterface?.SendMessage(new LatheStoppedProducingRecipeMessage());
|
||||||
State = LatheState.Base;
|
State = LatheState.Base;
|
||||||
SetAppearance(LatheVisualState.Idle);
|
SetAppearance(LatheVisualState.Idle);
|
||||||
});
|
});
|
||||||
@@ -136,12 +141,12 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
|
|
||||||
public void OpenUserInterface(IPlayerSession session)
|
public void OpenUserInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
if (!Powered)
|
if (!Powered)
|
||||||
{
|
{
|
||||||
@@ -153,12 +158,12 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
|
|
||||||
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!Owner.TryGetComponent(out MaterialStorageComponent storage)
|
if (!Owner.TryGetComponent(out MaterialStorageComponent? storage)
|
||||||
|| !eventArgs.Using.TryGetComponent(out MaterialComponent material)) return false;
|
|| !eventArgs.Using.TryGetComponent(out MaterialComponent? material)) return false;
|
||||||
|
|
||||||
var multiplier = 1;
|
var multiplier = 1;
|
||||||
|
|
||||||
if (eventArgs.Using.TryGetComponent(out StackComponent stack)) multiplier = stack.Count;
|
if (eventArgs.Using.TryGetComponent(out StackComponent? stack)) multiplier = stack.Count;
|
||||||
|
|
||||||
var totalAmount = 0;
|
var totalAmount = 0;
|
||||||
|
|
||||||
@@ -205,11 +210,13 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
|
|
||||||
private void SetAppearance(LatheVisualState state)
|
private void SetAppearance(LatheVisualState state)
|
||||||
{
|
{
|
||||||
if (_appearance != null || Owner.TryGetComponent(out _appearance))
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
_appearance.SetData(PowerDeviceVisuals.VisualState, state);
|
{
|
||||||
|
appearance.SetData(PowerDeviceVisuals.VisualState, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Queue<string> GetIDQueue()
|
private Queue<string> GetIdQueue()
|
||||||
{
|
{
|
||||||
var queue = new Queue<string>();
|
var queue = new Queue<string>();
|
||||||
foreach (var recipePrototype in Queue)
|
foreach (var recipePrototype in Queue)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
using Content.Shared.GameObjects.Components.Research;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
@@ -14,20 +15,21 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class ResearchClientComponent : SharedResearchClientComponent, IActivate
|
public class ResearchClientComponent : SharedResearchClientComponent, IActivate
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||||
|
|
||||||
// TODO: Create GUI for changing RD server.
|
// TODO: Create GUI for changing RD server.
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
private BoundUserInterface _userInterface;
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(ResearchClientUiKey.Key, out var boundUi)
|
||||||
#pragma warning disable 649
|
? boundUi
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
: null;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public bool ConnectedToServer => Server != null;
|
public bool ConnectedToServer => Server != null;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
public ResearchServerComponent Server { get; set; }
|
public ResearchServerComponent? Server { get; set; }
|
||||||
|
|
||||||
public bool RegisterServer(ResearchServerComponent server)
|
public bool RegisterServer(ResearchServerComponent? server)
|
||||||
{
|
{
|
||||||
var result = server != null && server.RegisterClient(this);
|
var result = server != null && server.RegisterClient(this);
|
||||||
return result;
|
return result;
|
||||||
@@ -41,23 +43,28 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
// For now it just registers on the first server it can find.
|
// For now it just registers on the first server it can find.
|
||||||
var servers = _entitySystemManager.GetEntitySystem<ResearchSystem>().Servers;
|
var servers = _entitySystemManager.GetEntitySystem<ResearchSystem>().Servers;
|
||||||
if(servers.Count > 0)
|
|
||||||
|
if (servers.Count > 0)
|
||||||
RegisterServer(servers[0]);
|
RegisterServer(servers[0]);
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(ResearchClientUiKey.Key);
|
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
if (UserInterface != null)
|
||||||
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenUserInterface(IPlayerSession session)
|
public void OpenUserInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
@@ -65,7 +72,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
|
|
||||||
public void UpdateUserInterface()
|
public void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
_userInterface?.SetState(GetNewUiState());
|
UserInterface?.SetState(GetNewUiState());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResearchClientBoundInterfaceState GetNewUiState()
|
private ResearchClientBoundInterfaceState GetNewUiState()
|
||||||
@@ -73,7 +80,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
var rd = _entitySystemManager.GetEntitySystem<ResearchSystem>();
|
var rd = _entitySystemManager.GetEntitySystem<ResearchSystem>();
|
||||||
|
|
||||||
return new ResearchClientBoundInterfaceState(rd.Servers.Count, rd.GetServerNames(),
|
return new ResearchClientBoundInterfaceState(rd.Servers.Count, rd.GetServerNames(),
|
||||||
rd.GetServerIds(), ConnectedToServer ? Server.Id : -1);
|
rd.GetServerIds(), ConnectedToServer ? Server!.Id : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage msg)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage msg)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
#nullable enable
|
||||||
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
using Content.Shared.GameObjects.Components.Research;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -14,6 +15,7 @@ using Robust.Shared.Interfaces.Random;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Research
|
namespace Content.Server.GameObjects.Components.Research
|
||||||
{
|
{
|
||||||
@@ -21,31 +23,38 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class ResearchConsoleComponent : SharedResearchConsoleComponent, IActivate
|
public class ResearchConsoleComponent : SharedResearchConsoleComponent, IActivate
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
#pragma warning disable 649
|
private const string SoundCollectionName = "keyboard";
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
|
||||||
[Dependency] private readonly IRobustRandom _random;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private BoundUserInterface _userInterface;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private ResearchClientComponent _client;
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
|
||||||
private const string _soundCollectionName = "keyboard";
|
|
||||||
|
|
||||||
private bool Powered => _powerReceiver.Powered;
|
[ViewVariables]
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(ResearchConsoleUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(ResearchConsoleUiKey.Key);
|
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
if (UserInterface != null)
|
||||||
_client = Owner.GetComponent<ResearchClientComponent>();
|
{
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
Owner.EnsureComponent<ResearchClientComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage message)
|
||||||
{
|
{
|
||||||
if (!Owner.TryGetComponent(out TechnologyDatabaseComponent database)) return;
|
if (!Owner.TryGetComponent(out TechnologyDatabaseComponent? database))
|
||||||
|
return;
|
||||||
|
if (!Owner.TryGetComponent(out ResearchClientComponent? client))
|
||||||
|
return;
|
||||||
if (!Powered)
|
if (!Powered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -54,8 +63,9 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
case ConsoleUnlockTechnologyMessage msg:
|
case ConsoleUnlockTechnologyMessage msg:
|
||||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||||
if (!protoMan.TryIndex(msg.Id, out TechnologyPrototype tech)) break;
|
if (!protoMan.TryIndex(msg.Id, out TechnologyPrototype tech)) break;
|
||||||
if(!_client.Server.CanUnlockTechnology(tech)) break;
|
if (client.Server == null) break;
|
||||||
if (_client.Server.UnlockTechnology(tech))
|
if (!client.Server.CanUnlockTechnology(tech)) break;
|
||||||
|
if (client.Server.UnlockTechnology(tech))
|
||||||
{
|
{
|
||||||
database.SyncWithServer();
|
database.SyncWithServer();
|
||||||
database.Dirty();
|
database.Dirty();
|
||||||
@@ -64,13 +74,12 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ConsoleServerSyncMessage msg:
|
case ConsoleServerSyncMessage _:
|
||||||
database.SyncWithServer();
|
database.SyncWithServer();
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ConsoleServerSelectionMessage msg:
|
case ConsoleServerSelectionMessage _:
|
||||||
if (!Owner.TryGetComponent(out ResearchClientComponent client)) break;
|
|
||||||
client.OpenUserInterface(message.Session);
|
client.OpenUserInterface(message.Session);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -81,13 +90,17 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateUserInterface()
|
public void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
_userInterface.SetState(GetNewUiState());
|
UserInterface?.SetState(GetNewUiState());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResearchConsoleBoundInterfaceState GetNewUiState()
|
private ResearchConsoleBoundInterfaceState GetNewUiState()
|
||||||
{
|
{
|
||||||
var points = _client.ConnectedToServer ? _client.Server.Point : 0;
|
if (!Owner.TryGetComponent(out ResearchClientComponent? client) ||
|
||||||
var pointsPerSecond = _client.ConnectedToServer ? _client.Server.PointsPerSecond : 0;
|
client.Server == null)
|
||||||
|
return new ResearchConsoleBoundInterfaceState(default, default);
|
||||||
|
|
||||||
|
var points = client.ConnectedToServer ? client.Server.Point : 0;
|
||||||
|
var pointsPerSecond = client.ConnectedToServer ? client.Server.PointsPerSecond : 0;
|
||||||
|
|
||||||
return new ResearchConsoleBoundInterfaceState(points, pointsPerSecond);
|
return new ResearchConsoleBoundInterfaceState(points, pointsPerSecond);
|
||||||
}
|
}
|
||||||
@@ -98,12 +111,12 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
/// <param name="session">Session where the UI will be shown</param>
|
/// <param name="session">Session where the UI will be shown</param>
|
||||||
public void OpenUserInterface(IPlayerSession session)
|
public void OpenUserInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
if (!Powered)
|
if (!Powered)
|
||||||
{
|
{
|
||||||
@@ -112,17 +125,14 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
|
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
PlayKeyboardSound();
|
PlayKeyboardSound();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayKeyboardSound()
|
private void PlayKeyboardSound()
|
||||||
{
|
{
|
||||||
var soundCollection = _prototypeManager.Index<SoundCollectionPrototype>(_soundCollectionName);
|
var soundCollection = _prototypeManager.Index<SoundCollectionPrototype>(SoundCollectionName);
|
||||||
var file = _random.Pick(soundCollection.PickFiles);
|
var file = _random.Pick(soundCollection.PickFiles);
|
||||||
var audioSystem = EntitySystem.Get<AudioSystem>();
|
var audioSystem = EntitySystem.Get<AudioSystem>();
|
||||||
audioSystem.PlayFromEntity(file,Owner,AudioParams.Default);
|
audioSystem.PlayFromEntity(file,Owner,AudioParams.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
Id = ServerCount++;
|
Id = ServerCount++;
|
||||||
EntitySystem.Get<ResearchSystem>()?.RegisterServer(this);
|
EntitySystem.Get<ResearchSystem>()?.RegisterServer(this);
|
||||||
Database = Owner.GetComponent<TechnologyDatabaseComponent>();
|
Database = Owner.EnsureComponent<TechnologyDatabaseComponent>();
|
||||||
Owner.TryGetComponent(out _powerReceiver);
|
Owner.TryGetComponent(out _powerReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ namespace Content.Server.GameObjects.Components.Rotatable
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class FlippableComponent : Component
|
public class FlippableComponent : Component
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "Flippable";
|
public override string Name => "Flippable";
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
|
||||||
using Content.Shared.GameObjects.Components.VendingMachines;
|
using Content.Shared.GameObjects.Components.VendingMachines;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
@@ -29,27 +29,28 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
|||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class VendingMachineComponent : SharedVendingMachineComponent, IActivate, IExamine, IBreakAct, IWires
|
public class VendingMachineComponent : SharedVendingMachineComponent, IActivate, IExamine, IBreakAct, IWires
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random;
|
|
||||||
#pragma warning restore 649
|
|
||||||
private AppearanceComponent _appearance;
|
|
||||||
private BoundUserInterface _userInterface;
|
|
||||||
private PowerReceiverComponent _powerReceiver;
|
|
||||||
|
|
||||||
private bool _ejecting = false;
|
private bool _ejecting;
|
||||||
private TimeSpan _animationDuration = TimeSpan.Zero;
|
private TimeSpan _animationDuration = TimeSpan.Zero;
|
||||||
private string _packPrototypeId;
|
private string _packPrototypeId = "";
|
||||||
private string _description;
|
private string? _description;
|
||||||
private string _spriteName;
|
private string _spriteName = "";
|
||||||
|
|
||||||
private bool Powered => _powerReceiver.Powered;
|
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||||
private bool _broken = false;
|
private bool _broken;
|
||||||
|
|
||||||
private string _soundVend;
|
private string _soundVend = "";
|
||||||
|
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(VendingMachineUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public void Activate(ActivateEventArgs eventArgs)
|
public void Activate(ActivateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if(!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if(!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -62,7 +63,7 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
|||||||
wires.OpenInterface(actor.playerSession);
|
wires.OpenInterface(actor.playerSession);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
_userInterface.Open(actor.playerSession);
|
UserInterface?.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,25 +107,32 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
if (UserInterface != null)
|
||||||
.GetBoundUserInterface(VendingMachineUiKey.Key);
|
{
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
|
}
|
||||||
_powerReceiver.OnPowerStateChanged += UpdatePower;
|
|
||||||
TrySetVisualState(_powerReceiver.Powered ? VendingMachineVisualState.Normal : VendingMachineVisualState.Off);
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
|
{
|
||||||
|
receiver.OnPowerStateChanged += UpdatePower;
|
||||||
|
TrySetVisualState(receiver.Powered ? VendingMachineVisualState.Normal : VendingMachineVisualState.Off);
|
||||||
|
}
|
||||||
|
|
||||||
InitializeFromPrototype();
|
InitializeFromPrototype();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
_appearance = null;
|
if (Owner.TryGetComponent(out PowerReceiverComponent? receiver))
|
||||||
_powerReceiver.OnPowerStateChanged -= UpdatePower;
|
{
|
||||||
_powerReceiver = null;
|
receiver.OnPowerStateChanged -= UpdatePower;
|
||||||
|
}
|
||||||
|
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePower(object sender, PowerStateEventArgs args)
|
private void UpdatePower(object? sender, PowerStateEventArgs args)
|
||||||
{
|
{
|
||||||
var state = args.Powered ? VendingMachineVisualState.Normal : VendingMachineVisualState.Off;
|
var state = args.Powered ? VendingMachineVisualState.Normal : VendingMachineVisualState.Off;
|
||||||
TrySetVisualState(state);
|
TrySetVisualState(state);
|
||||||
@@ -141,8 +149,8 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
|||||||
case VendingMachineEjectMessage msg:
|
case VendingMachineEjectMessage msg:
|
||||||
TryEject(msg.ID);
|
TryEject(msg.ID);
|
||||||
break;
|
break;
|
||||||
case InventorySyncRequestMessage msg:
|
case InventorySyncRequestMessage _:
|
||||||
_userInterface.SendMessage(new VendingMachineInventoryMessage(Inventory));
|
UserInterface?.SendMessage(new VendingMachineInventoryMessage(Inventory));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +168,7 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VendingMachineInventoryEntry entry = Inventory.Find(x => x.ID == id);
|
var entry = Inventory.Find(x => x.ID == id);
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
{
|
{
|
||||||
FlickDenyAnimation();
|
FlickDenyAnimation();
|
||||||
@@ -175,7 +183,7 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
|||||||
|
|
||||||
_ejecting = true;
|
_ejecting = true;
|
||||||
entry.Amount--;
|
entry.Amount--;
|
||||||
_userInterface.SendMessage(new VendingMachineInventoryMessage(Inventory));
|
UserInterface?.SendMessage(new VendingMachineInventoryMessage(Inventory));
|
||||||
TrySetVisualState(VendingMachineVisualState.Eject);
|
TrySetVisualState(VendingMachineVisualState.Eject);
|
||||||
|
|
||||||
Timer.Spawn(_animationDuration, () =>
|
Timer.Spawn(_animationDuration, () =>
|
||||||
@@ -204,14 +212,20 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
|||||||
if (_broken)
|
if (_broken)
|
||||||
{
|
{
|
||||||
finalState = VendingMachineVisualState.Broken;
|
finalState = VendingMachineVisualState.Broken;
|
||||||
} else if (_ejecting)
|
}
|
||||||
|
else if (_ejecting)
|
||||||
{
|
{
|
||||||
finalState = VendingMachineVisualState.Eject;
|
finalState = VendingMachineVisualState.Eject;
|
||||||
} else if (!Powered)
|
}
|
||||||
|
else if (!Powered)
|
||||||
{
|
{
|
||||||
finalState = VendingMachineVisualState.Off;
|
finalState = VendingMachineVisualState.Off;
|
||||||
}
|
}
|
||||||
_appearance.SetData(VendingMachineVisuals.VisualState, finalState);
|
|
||||||
|
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
{
|
||||||
|
appearance.SetData(VendingMachineVisuals.VisualState, finalState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBreak(BreakageEventArgs eventArgs)
|
public void OnBreak(BreakageEventArgs eventArgs)
|
||||||
|
|||||||
@@ -158,7 +158,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
|
|||||||
{
|
{
|
||||||
base.OnAdd();
|
base.OnAdd();
|
||||||
var rangedWeaponComponent = Owner.GetComponent<ServerRangedWeaponComponent>();
|
var rangedWeaponComponent = Owner.GetComponent<ServerRangedWeaponComponent>();
|
||||||
rangedWeaponComponent.Barrel = this;
|
|
||||||
|
rangedWeaponComponent.Barrel ??= this;
|
||||||
rangedWeaponComponent.FireHandler += Fire;
|
rangedWeaponComponent.FireHandler += Fire;
|
||||||
rangedWeaponComponent.WeaponCanFireHandler += WeaponCanFire;
|
rangedWeaponComponent.WeaponCanFireHandler += WeaponCanFire;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,11 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine, IMapInit
|
public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine, IMapInit
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
private AudioSystem _audioSystem = default!;
|
private AudioSystem _audioSystem = default!;
|
||||||
private AppearanceComponent _appearance = default!;
|
private AppearanceComponent _appearance = default!;
|
||||||
private BoundUserInterface _userInterface = default!;
|
|
||||||
|
|
||||||
private bool _isPanelOpen;
|
private bool _isPanelOpen;
|
||||||
|
|
||||||
@@ -140,15 +138,23 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private string? _layoutId;
|
private string? _layoutId;
|
||||||
|
|
||||||
|
private BoundUserInterface? UserInterface =>
|
||||||
|
Owner.TryGetComponent(out ServerUserInterfaceComponent? ui) &&
|
||||||
|
ui.TryGetBoundUserInterface(WiresUiKey.Key, out var boundUi)
|
||||||
|
? boundUi
|
||||||
|
: null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_audioSystem = EntitySystem.Get<AudioSystem>();
|
_audioSystem = EntitySystem.Get<AudioSystem>();
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
_appearance = Owner.GetComponent<AppearanceComponent>();
|
||||||
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen);
|
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen);
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
||||||
.GetBoundUserInterface(WiresUiKey.Key);
|
if (UserInterface != null)
|
||||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
{
|
||||||
|
UserInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateSerialNumber()
|
private void GenerateSerialNumber()
|
||||||
@@ -357,7 +363,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void OpenInterface(IPlayerSession session)
|
public void OpenInterface(IPlayerSession session)
|
||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
UserInterface?.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg)
|
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg)
|
||||||
@@ -450,7 +456,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
entry.Letter));
|
entry.Letter));
|
||||||
}
|
}
|
||||||
|
|
||||||
_userInterface.SetState(
|
UserInterface?.SetState(
|
||||||
new WiresBoundUserInterfaceState(
|
new WiresBoundUserInterfaceState(
|
||||||
clientList.ToArray(),
|
clientList.ToArray(),
|
||||||
_statuses.Select(p => new StatusEntry(p.Key, p.Value)).ToArray(),
|
_statuses.Select(p => new StatusEntry(p.Key, p.Value)).ToArray(),
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI
|
|||||||
/// <param name="controller"></param>
|
/// <param name="controller"></param>
|
||||||
public void ProcessorInitialize(AiControllerComponent controller)
|
public void ProcessorInitialize(AiControllerComponent controller)
|
||||||
{
|
{
|
||||||
if (controller.Processor != null) return;
|
if (controller.Processor != null || controller.LogicName == null) return;
|
||||||
controller.Processor = CreateProcessor(controller.LogicName);
|
controller.Processor = CreateProcessor(controller.LogicName);
|
||||||
controller.Processor.SelfEntity = controller.Owner;
|
controller.Processor.SelfEntity = controller.Owner;
|
||||||
controller.Processor.Setup();
|
controller.Processor.Setup();
|
||||||
|
|||||||
@@ -153,13 +153,20 @@ namespace Content.Server.GameObjects.EntitySystems.Atmos
|
|||||||
private bool TryRefreshTile(GridAtmosphereComponent gam, GasOverlayData oldTile, MapIndices indices, out GasOverlayData overlayData)
|
private bool TryRefreshTile(GridAtmosphereComponent gam, GasOverlayData oldTile, MapIndices indices, out GasOverlayData overlayData)
|
||||||
{
|
{
|
||||||
var tile = gam.GetTile(indices);
|
var tile = gam.GetTile(indices);
|
||||||
|
|
||||||
|
if (tile == null)
|
||||||
|
{
|
||||||
|
overlayData = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var tileData = new List<GasData>();
|
var tileData = new List<GasData>();
|
||||||
|
|
||||||
for (byte i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
for (byte i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
||||||
{
|
{
|
||||||
var gas = Atmospherics.GetGas(i);
|
var gas = Atmospherics.GetGas(i);
|
||||||
var overlay = Atmospherics.GetOverlay(i);
|
var overlay = Atmospherics.GetOverlay(i);
|
||||||
if (overlay == null || tile.Air == null) continue;
|
if (overlay == null || tile?.Air == null) continue;
|
||||||
|
|
||||||
var moles = tile.Air.Gases[i];
|
var moles = tile.Air.Gases[i];
|
||||||
|
|
||||||
@@ -169,7 +176,7 @@ namespace Content.Server.GameObjects.EntitySystems.Atmos
|
|||||||
tileData.Add(data);
|
tileData.Add(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
overlayData = new GasOverlayData(tile.Hotspot.State, tile.Hotspot.Temperature, tileData.Count == 0 ? null : tileData.ToArray());
|
overlayData = new GasOverlayData(tile!.Hotspot.State, tile.Hotspot.Temperature, tileData.Count == 0 ? null : tileData.ToArray());
|
||||||
|
|
||||||
if (overlayData.Equals(oldTile))
|
if (overlayData.Equals(oldTile))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,13 +30,11 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
internal class MoverSystem : SharedMoverSystem
|
internal class MoverSystem : SharedMoverSystem
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IPauseManager _pauseManager = default!;
|
[Dependency] private readonly IPauseManager _pauseManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
|
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private AudioSystem _audioSystem = default!;
|
private AudioSystem _audioSystem = default!;
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ namespace Content.Shared.GameObjects.Components.Damage
|
|||||||
[ComponentReference(typeof(IDamageableComponent))]
|
[ComponentReference(typeof(IDamageableComponent))]
|
||||||
public class DamageableComponent : Component, IDamageableComponent
|
public class DamageableComponent : Component, IDamageableComponent
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "Damageable";
|
public override string Name => "Damageable";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Content.Shared.GameObjects.Components.Mobs;
|
using Content.Shared.GameObjects.Components.Mobs;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
@@ -7,6 +8,7 @@ using Robust.Shared.GameObjects;
|
|||||||
using Robust.Shared.GameObjects.Components;
|
using Robust.Shared.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
@@ -116,12 +118,18 @@ namespace Content.Shared.GameObjects.Components.Movement
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
var collidable = Owner.GetComponent<ICollidableComponent>();
|
|
||||||
|
var collidable = Owner.EnsureComponent<CollidableComponent>();
|
||||||
|
|
||||||
collidable.Hard = false;
|
collidable.Hard = false;
|
||||||
var shape = collidable.PhysicsShapes[0];
|
|
||||||
|
var shape = collidable.PhysicsShapes.FirstOrDefault();
|
||||||
|
|
||||||
|
if (shape != null)
|
||||||
|
{
|
||||||
shape.CollisionLayer |= (int) CollisionGroup.SmallImpassable;
|
shape.CollisionLayer |= (int) CollisionGroup.SmallImpassable;
|
||||||
shape.CollisionMask = (int)CollisionGroup.None;
|
shape.CollisionMask = (int) CollisionGroup.None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="Lidgren.Network" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data></s:String>
|
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="Lidgren.Network" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data></s:String>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Collidable/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Collidable/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cooldowns/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cooldowns/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Discharger/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=crit/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=crit/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=firelocks/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=firelocks/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=diminishingly/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=diminishingly/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
Reference in New Issue
Block a user