move hot plate item placement stuff into its own system (#18923)
Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
using Content.Shared.Whitelist;
|
|
||||||
|
|
||||||
namespace Content.Server.Chemistry.Components;
|
namespace Content.Server.Chemistry.Components;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
@@ -28,23 +26,4 @@ public sealed class SolutionHeaterComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("partRatingHeatMultiplier")]
|
[DataField("partRatingHeatMultiplier")]
|
||||||
public float PartRatingHeatMultiplier = 1.5f;
|
public float PartRatingHeatMultiplier = 1.5f;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The entities that are placed on the heater.
|
|
||||||
/// <summary>
|
|
||||||
[DataField("placedEntities")]
|
|
||||||
public HashSet<EntityUid> PlacedEntities = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The max amount of entities that can be heated at the same time.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("maxEntities")]
|
|
||||||
public uint MaxEntities = 1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whitelist for entities that can be placed on the heater.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("whitelist")]
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public EntityWhitelist? Whitelist;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Linq;
|
|
||||||
using Content.Server.Chemistry.Components;
|
using Content.Server.Chemistry.Components;
|
||||||
using Content.Server.Chemistry.Components.SolutionManager;
|
using Content.Server.Chemistry.Components.SolutionManager;
|
||||||
using Content.Server.Construction;
|
using Content.Server.Construction;
|
||||||
@@ -6,27 +5,26 @@ using Content.Server.Power.Components;
|
|||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.Placeable;
|
using Content.Shared.Placeable;
|
||||||
using Robust.Shared.Physics.Events;
|
|
||||||
using Robust.Shared.Physics.Systems;
|
|
||||||
|
|
||||||
namespace Content.Server.Chemistry.EntitySystems;
|
namespace Content.Server.Chemistry.EntitySystems;
|
||||||
|
|
||||||
public sealed class SolutionHeaterSystem : EntitySystem
|
public sealed class SolutionHeaterSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly ItemPlacerSystem _itemPlacer = default!;
|
||||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
|
||||||
[Dependency] private readonly PlaceableSurfaceSystem _placeableSurface = default!;
|
|
||||||
[Dependency] private readonly PowerReceiverSystem _powerReceiver = default!;
|
[Dependency] private readonly PowerReceiverSystem _powerReceiver = default!;
|
||||||
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SolutionContainerSystem _solution = default!;
|
[Dependency] private readonly SolutionContainerSystem _solution = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<SolutionHeaterComponent, PowerChangedEvent>(OnPowerChanged);
|
SubscribeLocalEvent<SolutionHeaterComponent, PowerChangedEvent>(OnPowerChanged);
|
||||||
SubscribeLocalEvent<SolutionHeaterComponent, RefreshPartsEvent>(OnRefreshParts);
|
SubscribeLocalEvent<SolutionHeaterComponent, RefreshPartsEvent>(OnRefreshParts);
|
||||||
SubscribeLocalEvent<SolutionHeaterComponent, UpgradeExamineEvent>(OnUpgradeExamine);
|
SubscribeLocalEvent<SolutionHeaterComponent, UpgradeExamineEvent>(OnUpgradeExamine);
|
||||||
SubscribeLocalEvent<SolutionHeaterComponent, StartCollideEvent>(OnStartCollide);
|
SubscribeLocalEvent<SolutionHeaterComponent, ItemPlacedEvent>(OnItemPlaced);
|
||||||
SubscribeLocalEvent<SolutionHeaterComponent, EndCollideEvent>(OnEndCollide);
|
SubscribeLocalEvent<SolutionHeaterComponent, ItemRemovedEvent>(OnItemRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TurnOn(EntityUid uid)
|
private void TurnOn(EntityUid uid)
|
||||||
@@ -35,9 +33,12 @@ public sealed class SolutionHeaterSystem : EntitySystem
|
|||||||
EnsureComp<ActiveSolutionHeaterComponent>(uid);
|
EnsureComp<ActiveSolutionHeaterComponent>(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryTurnOn(EntityUid uid, SolutionHeaterComponent component)
|
public bool TryTurnOn(EntityUid uid, ItemPlacerComponent? placer = null)
|
||||||
{
|
{
|
||||||
if (component.PlacedEntities.Count <= 0 || !_powerReceiver.IsPowered(uid))
|
if (!Resolve(uid, ref placer))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (placer.PlacedEntities.Count <= 0 || !_powerReceiver.IsPowered(uid))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TurnOn(uid);
|
TurnOn(uid);
|
||||||
@@ -52,7 +53,8 @@ public sealed class SolutionHeaterSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnPowerChanged(EntityUid uid, SolutionHeaterComponent component, ref PowerChangedEvent args)
|
private void OnPowerChanged(EntityUid uid, SolutionHeaterComponent component, ref PowerChangedEvent args)
|
||||||
{
|
{
|
||||||
if (args.Powered && component.PlacedEntities.Count > 0)
|
var placer = Comp<ItemPlacerComponent>(uid);
|
||||||
|
if (args.Powered && placer.PlacedEntities.Count > 0)
|
||||||
{
|
{
|
||||||
TurnOn(uid);
|
TurnOn(uid);
|
||||||
}
|
}
|
||||||
@@ -74,43 +76,26 @@ public sealed class SolutionHeaterSystem : EntitySystem
|
|||||||
args.AddPercentageUpgrade("solution-heater-upgrade-heat", component.HeatPerSecond / component.BaseHeatPerSecond);
|
args.AddPercentageUpgrade("solution-heater-upgrade-heat", component.HeatPerSecond / component.BaseHeatPerSecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStartCollide(EntityUid uid, SolutionHeaterComponent component, ref StartCollideEvent args)
|
private void OnItemPlaced(EntityUid uid, SolutionHeaterComponent comp, ref ItemPlacedEvent args)
|
||||||
{
|
{
|
||||||
if (component.Whitelist is not null && !component.Whitelist.IsValid(args.OtherEntity))
|
TryTurnOn(uid);
|
||||||
return;
|
|
||||||
|
|
||||||
// Disallow sleeping so we can detect when entity is removed from the heater.
|
|
||||||
_physics.SetSleepingAllowed(args.OtherEntity, args.OtherBody, false);
|
|
||||||
|
|
||||||
component.PlacedEntities.Add(args.OtherEntity);
|
|
||||||
|
|
||||||
TryTurnOn(uid, component);
|
|
||||||
|
|
||||||
if (component.PlacedEntities.Count >= component.MaxEntities)
|
|
||||||
_placeableSurface.SetPlaceable(uid, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEndCollide(EntityUid uid, SolutionHeaterComponent component, ref EndCollideEvent args)
|
private void OnItemRemoved(EntityUid uid, SolutionHeaterComponent component, ref ItemRemovedEvent args)
|
||||||
{
|
{
|
||||||
// Re-allow sleeping.
|
var placer = Comp<ItemPlacerComponent>(uid);
|
||||||
_physics.SetSleepingAllowed(args.OtherEntity, args.OtherBody, true);
|
if (placer.PlacedEntities.Count == 0) // Last entity was removed
|
||||||
|
|
||||||
component.PlacedEntities.Remove(args.OtherEntity);
|
|
||||||
|
|
||||||
if (component.PlacedEntities.Count == 0) // Last entity was removed
|
|
||||||
TurnOff(uid);
|
TurnOff(uid);
|
||||||
|
|
||||||
_placeableSurface.SetPlaceable(uid, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|
||||||
var query = EntityQueryEnumerator<ActiveSolutionHeaterComponent, SolutionHeaterComponent>();
|
var query = EntityQueryEnumerator<ActiveSolutionHeaterComponent, SolutionHeaterComponent, ItemPlacerComponent>();
|
||||||
while (query.MoveNext(out _, out _, out var heater))
|
while (query.MoveNext(out _, out _, out var heater, out var placer))
|
||||||
{
|
{
|
||||||
foreach (var heatingEntity in heater.PlacedEntities.Take((int) heater.MaxEntities))
|
foreach (var heatingEntity in placer.PlacedEntities)
|
||||||
{
|
{
|
||||||
if (!TryComp<SolutionContainerManagerComponent>(heatingEntity, out var solution))
|
if (!TryComp<SolutionContainerManagerComponent>(heatingEntity, out var solution))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ public sealed class ArtifactAnalyzerComponent : Component
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public EntityUid? Console;
|
public EntityUid? Console;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All of the valid artifacts currently touching the analyzer.
|
|
||||||
/// </summary>
|
|
||||||
[ViewVariables]
|
|
||||||
public HashSet<EntityUid> Contacts = new();
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public bool ReadyToPrint = false;
|
public bool ReadyToPrint = false;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
|
|||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.DeviceLinking;
|
using Content.Shared.DeviceLinking;
|
||||||
using Content.Shared.DeviceLinking.Events;
|
using Content.Shared.DeviceLinking.Events;
|
||||||
|
using Content.Shared.Placeable;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Research.Components;
|
using Content.Shared.Research.Components;
|
||||||
using Content.Shared.Xenoarchaeology.Equipment;
|
using Content.Shared.Xenoarchaeology.Equipment;
|
||||||
@@ -18,7 +19,6 @@ using JetBrains.Annotations;
|
|||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Physics.Events;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -45,7 +45,6 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<ActiveScannedArtifactComponent, MoveEvent>(OnScannedMoved);
|
|
||||||
SubscribeLocalEvent<ActiveScannedArtifactComponent, ArtifactActivatedEvent>(OnArtifactActivated);
|
SubscribeLocalEvent<ActiveScannedArtifactComponent, ArtifactActivatedEvent>(OnArtifactActivated);
|
||||||
|
|
||||||
SubscribeLocalEvent<ActiveArtifactAnalyzerComponent, ComponentStartup>(OnAnalyzeStart);
|
SubscribeLocalEvent<ActiveArtifactAnalyzerComponent, ComponentStartup>(OnAnalyzeStart);
|
||||||
@@ -54,8 +53,8 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<ArtifactAnalyzerComponent, UpgradeExamineEvent>(OnUpgradeExamine);
|
SubscribeLocalEvent<ArtifactAnalyzerComponent, UpgradeExamineEvent>(OnUpgradeExamine);
|
||||||
SubscribeLocalEvent<ArtifactAnalyzerComponent, RefreshPartsEvent>(OnRefreshParts);
|
SubscribeLocalEvent<ArtifactAnalyzerComponent, RefreshPartsEvent>(OnRefreshParts);
|
||||||
SubscribeLocalEvent<ArtifactAnalyzerComponent, StartCollideEvent>(OnCollide);
|
SubscribeLocalEvent<ArtifactAnalyzerComponent, ItemPlacedEvent>(OnItemPlaced);
|
||||||
SubscribeLocalEvent<ArtifactAnalyzerComponent, EndCollideEvent>(OnEndCollide);
|
SubscribeLocalEvent<ArtifactAnalyzerComponent, ItemRemovedEvent>(OnItemRemoved);
|
||||||
|
|
||||||
SubscribeLocalEvent<ArtifactAnalyzerComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<ArtifactAnalyzerComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<AnalysisConsoleComponent, NewLinkEvent>(OnNewLink);
|
SubscribeLocalEvent<AnalysisConsoleComponent, NewLinkEvent>(OnNewLink);
|
||||||
@@ -107,22 +106,18 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Goes through the current contacts on
|
/// Goes through the current entities on
|
||||||
/// the analyzer and returns a valid artifact
|
/// the analyzer and returns a valid artifact
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uid"></param>
|
/// <param name="uid"></param>
|
||||||
/// <param name="component"></param>
|
/// <param name="placer"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private EntityUid? GetArtifactForAnalysis(EntityUid? uid, ArtifactAnalyzerComponent? component = null)
|
private EntityUid? GetArtifactForAnalysis(EntityUid? uid, ItemPlacerComponent? placer = null)
|
||||||
{
|
{
|
||||||
if (uid == null)
|
if (uid == null || !Resolve(uid.Value, ref placer))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (!Resolve(uid.Value, ref component))
|
return placer.PlacedEntities.FirstOrNull();
|
||||||
return null;
|
|
||||||
|
|
||||||
var validEnts = component.Contacts.Where(HasComp<ArtifactComponent>).ToHashSet();
|
|
||||||
return validEnts.FirstOrNull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -205,11 +200,12 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
|
|||||||
artifact = analyzer.LastAnalyzedArtifact;
|
artifact = analyzer.LastAnalyzedArtifact;
|
||||||
msg = GetArtifactScanMessage(analyzer);
|
msg = GetArtifactScanMessage(analyzer);
|
||||||
totalTime = analyzer.AnalysisDuration * analyzer.AnalysisDurationMulitplier;
|
totalTime = analyzer.AnalysisDuration * analyzer.AnalysisDurationMulitplier;
|
||||||
canScan = analyzer.Contacts.Any();
|
if (TryComp<ItemPlacerComponent>(component.AnalyzerEntity, out var placer))
|
||||||
|
canScan = placer.PlacedEntities.Any();
|
||||||
canPrint = analyzer.ReadyToPrint;
|
canPrint = analyzer.ReadyToPrint;
|
||||||
|
|
||||||
// the artifact that's actually on the scanner right now.
|
// the artifact that's actually on the scanner right now.
|
||||||
if (GetArtifactForAnalysis(component.AnalyzerEntity, analyzer) is { } current)
|
if (GetArtifactForAnalysis(component.AnalyzerEntity, placer) is { } current)
|
||||||
points = _artifact.GetResearchPointValue(current);
|
points = _artifact.GetResearchPointValue(current);
|
||||||
}
|
}
|
||||||
var analyzerConnected = component.AnalyzerEntity != null;
|
var analyzerConnected = component.AnalyzerEntity != null;
|
||||||
@@ -381,20 +377,6 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
|
|||||||
CancelScan(uid);
|
CancelScan(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks to make sure that the currently scanned artifact isn't moved off of the scanner
|
|
||||||
/// </summary>
|
|
||||||
private void OnScannedMoved(EntityUid uid, ActiveScannedArtifactComponent component, ref MoveEvent args)
|
|
||||||
{
|
|
||||||
if (!TryComp<ArtifactAnalyzerComponent>(component.Scanner, out var analyzer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (analyzer.Contacts.Contains(uid))
|
|
||||||
return;
|
|
||||||
|
|
||||||
CancelScan(uid, component, analyzer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stops the current scan
|
/// Stops the current scan
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -448,27 +430,16 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
|
|||||||
args.AddPercentageUpgrade("analyzer-artifact-component-upgrade-analysis", component.AnalysisDurationMulitplier);
|
args.AddPercentageUpgrade("analyzer-artifact-component-upgrade-analysis", component.AnalysisDurationMulitplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCollide(EntityUid uid, ArtifactAnalyzerComponent component, ref StartCollideEvent args)
|
private void OnItemPlaced(EntityUid uid, ArtifactAnalyzerComponent component, ref ItemPlacedEvent args)
|
||||||
{
|
{
|
||||||
var otherEnt = args.OtherEntity;
|
if (component.Console != null && Exists(component.Console))
|
||||||
|
|
||||||
if (!HasComp<ArtifactComponent>(otherEnt))
|
|
||||||
return;
|
|
||||||
|
|
||||||
component.Contacts.Add(otherEnt);
|
|
||||||
|
|
||||||
if (component.Console != null)
|
|
||||||
UpdateUserInterface(component.Console.Value);
|
UpdateUserInterface(component.Console.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEndCollide(EntityUid uid, ArtifactAnalyzerComponent component, ref EndCollideEvent args)
|
private void OnItemRemoved(EntityUid uid, ArtifactAnalyzerComponent component, ref ItemRemovedEvent args)
|
||||||
{
|
{
|
||||||
var otherEnt = args.OtherEntity;
|
// cancel the scan if the artifact moves off the analyzer
|
||||||
|
CancelScan(args.OtherEntity);
|
||||||
if (!HasComp<ArtifactComponent>(otherEnt))
|
|
||||||
return;
|
|
||||||
component.Contacts.Remove(otherEnt);
|
|
||||||
|
|
||||||
if (component.Console != null && Exists(component.Console))
|
if (component.Console != null && Exists(component.Console))
|
||||||
UpdateUserInterface(component.Console.Value);
|
UpdateUserInterface(component.Console.Value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using Content.Server.Xenoarchaeology.Equipment.Components;
|
|||||||
using Content.Server.Xenoarchaeology.XenoArtifacts;
|
using Content.Server.Xenoarchaeology.XenoArtifacts;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Robust.Shared.Physics.Events;
|
using Content.Shared.Placeable;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -13,8 +13,8 @@ namespace Content.Server.Xenoarchaeology.Equipment.Systems;
|
|||||||
|
|
||||||
public sealed class TraversalDistorterSystem : EntitySystem
|
public sealed class TraversalDistorterSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly PopupSystem _popup = default!;
|
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -26,8 +26,8 @@ public sealed class TraversalDistorterSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<TraversalDistorterComponent, RefreshPartsEvent>(OnRefreshParts);
|
SubscribeLocalEvent<TraversalDistorterComponent, RefreshPartsEvent>(OnRefreshParts);
|
||||||
SubscribeLocalEvent<TraversalDistorterComponent, UpgradeExamineEvent>(OnUpgradeExamine);
|
SubscribeLocalEvent<TraversalDistorterComponent, UpgradeExamineEvent>(OnUpgradeExamine);
|
||||||
|
|
||||||
SubscribeLocalEvent<TraversalDistorterComponent, StartCollideEvent>(OnCollide);
|
SubscribeLocalEvent<TraversalDistorterComponent, ItemPlacedEvent>(OnItemPlaced);
|
||||||
SubscribeLocalEvent<TraversalDistorterComponent, EndCollideEvent>(OnEndCollide);
|
SubscribeLocalEvent<TraversalDistorterComponent, ItemRemovedEvent>(OnItemRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, TraversalDistorterComponent component, MapInitEvent args)
|
private void OnInit(EntityUid uid, TraversalDistorterComponent component, MapInitEvent args)
|
||||||
@@ -88,24 +88,15 @@ public sealed class TraversalDistorterSystem : EntitySystem
|
|||||||
args.AddPercentageUpgrade("traversal-distorter-upgrade-bias", component.BiasChance / component.BaseBiasChance);
|
args.AddPercentageUpgrade("traversal-distorter-upgrade-bias", component.BiasChance / component.BaseBiasChance);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCollide(EntityUid uid, TraversalDistorterComponent component, ref StartCollideEvent args)
|
private void OnItemPlaced(EntityUid uid, TraversalDistorterComponent component, ref ItemPlacedEvent args)
|
||||||
{
|
{
|
||||||
var otherEnt = args.OtherEntity;
|
var bias = EnsureComp<BiasedArtifactComponent>(args.OtherEntity);
|
||||||
|
|
||||||
if (!HasComp<ArtifactComponent>(otherEnt))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var bias = EnsureComp<BiasedArtifactComponent>(otherEnt);
|
|
||||||
bias.Provider = uid;
|
bias.Provider = uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEndCollide(EntityUid uid, TraversalDistorterComponent component, ref EndCollideEvent args)
|
private void OnItemRemoved(EntityUid uid, TraversalDistorterComponent component, ref ItemRemovedEvent args)
|
||||||
{
|
{
|
||||||
var otherEnt = args.OtherEntity;
|
var otherEnt = args.OtherEntity;
|
||||||
|
|
||||||
if (!HasComp<ArtifactComponent>(otherEnt))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (TryComp<BiasedArtifactComponent>(otherEnt, out var bias) && bias.Provider == uid)
|
if (TryComp<BiasedArtifactComponent>(otherEnt, out var bias) && bias.Provider == uid)
|
||||||
RemComp(otherEnt, bias);
|
RemComp(otherEnt, bias);
|
||||||
}
|
}
|
||||||
|
|||||||
31
Content.Shared/Placeable/ItemPlacerComponent.cs
Normal file
31
Content.Shared/Placeable/ItemPlacerComponent.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Placeable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Detects items placed on it that match a whitelist.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(ItemPlacerSystem))]
|
||||||
|
public sealed partial class ItemPlacerComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The entities that are currently on top of the placer.
|
||||||
|
/// Guaranteed to have less than <see cref="MaxEntities"/> enitites if it is set.
|
||||||
|
/// <summary>
|
||||||
|
[DataField("placedEntities"), AutoNetworkedField]
|
||||||
|
public HashSet<EntityUid> PlacedEntities = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whitelist for entities that can be placed.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("whitelist"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public EntityWhitelist? Whitelist;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The max amount of entities that can be placed at the same time.
|
||||||
|
/// If 0, there is no limit.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("maxEntities"), AutoNetworkedField]
|
||||||
|
public uint MaxEntities = 1;
|
||||||
|
}
|
||||||
72
Content.Shared/Placeable/ItemPlacerSystem.cs
Normal file
72
Content.Shared/Placeable/ItemPlacerSystem.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using Robust.Shared.Physics.Events;
|
||||||
|
using Robust.Shared.Physics.Systems;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Content.Shared.Placeable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tracks placed entities
|
||||||
|
/// Subscribe to <see cref="ItemPlacedEvent"/> or <see cref="ItemRemovedEvent"/> to do things when items or placed or removed.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ItemPlacerSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly PlaceableSurfaceSystem _placeableSurface = default!;
|
||||||
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<ItemPlacerComponent, StartCollideEvent>(OnStartCollide);
|
||||||
|
SubscribeLocalEvent<ItemPlacerComponent, EndCollideEvent>(OnEndCollide);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStartCollide(EntityUid uid, ItemPlacerComponent comp, ref StartCollideEvent args)
|
||||||
|
{
|
||||||
|
if (comp.Whitelist != null && !comp.Whitelist.IsValid(args.OtherEntity))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Disallow sleeping so we can detect when entity is removed from the heater.
|
||||||
|
_physics.SetSleepingAllowed(args.OtherEntity, args.OtherBody, false);
|
||||||
|
|
||||||
|
var count = comp.PlacedEntities.Count;
|
||||||
|
if (comp.MaxEntities == 0 || count < comp.MaxEntities)
|
||||||
|
{
|
||||||
|
comp.PlacedEntities.Add(args.OtherEntity);
|
||||||
|
|
||||||
|
var ev = new ItemPlacedEvent(args.OtherEntity);
|
||||||
|
RaiseLocalEvent(uid, ref ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp.MaxEntities > 0 && count >= (comp.MaxEntities - 1))
|
||||||
|
{
|
||||||
|
// Don't let any more items be placed if it's reached its limit.
|
||||||
|
_placeableSurface.SetPlaceable(uid, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEndCollide(EntityUid uid, ItemPlacerComponent comp, ref EndCollideEvent args)
|
||||||
|
{
|
||||||
|
// Re-allow sleeping.
|
||||||
|
_physics.SetSleepingAllowed(args.OtherEntity, args.OtherBody, true);
|
||||||
|
|
||||||
|
comp.PlacedEntities.Remove(args.OtherEntity);
|
||||||
|
|
||||||
|
var ev = new ItemRemovedEvent(args.OtherEntity);
|
||||||
|
RaiseLocalEvent(uid, ref ev);
|
||||||
|
|
||||||
|
_placeableSurface.SetPlaceable(uid, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised on the <see cref="ItemPlacer"/> when an item is placed and it is under the item limit.
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct ItemPlacedEvent(EntityUid OtherEntity);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised on the <see cref="ItemPlacer"/> when an item is removed from it.
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct ItemRemovedEvent(EntityUid OtherEntity);
|
||||||
@@ -46,6 +46,10 @@
|
|||||||
powerDrawMultiplier: 0.80
|
powerDrawMultiplier: 0.80
|
||||||
scaling: Exponential
|
scaling: Exponential
|
||||||
- type: ArtifactAnalyzer
|
- type: ArtifactAnalyzer
|
||||||
|
- type: ItemPlacer
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Artifact
|
||||||
- type: DeviceNetwork
|
- type: DeviceNetwork
|
||||||
deviceNetId: Wired
|
deviceNetId: Wired
|
||||||
receiveFrequencyId: BasicDevice
|
receiveFrequencyId: BasicDevice
|
||||||
@@ -109,6 +113,14 @@
|
|||||||
powerDrawMultiplier: 0.80
|
powerDrawMultiplier: 0.80
|
||||||
scaling: Exponential
|
scaling: Exponential
|
||||||
- type: TraversalDistorter
|
- type: TraversalDistorter
|
||||||
|
- type: ItemPlacer
|
||||||
|
# don't limit the number of artifacts that can be biased
|
||||||
|
maxEntities: 0
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Artifact
|
||||||
|
- type: PlaceableSurface
|
||||||
|
placeCentered: true
|
||||||
- type: Machine
|
- type: Machine
|
||||||
board: TraversalDistorterMachineCircuitboard
|
board: TraversalDistorterMachineCircuitboard
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
components:
|
components:
|
||||||
- FitsInDispenser
|
- FitsInDispenser
|
||||||
- type: SolutionHeater
|
- type: SolutionHeater
|
||||||
|
- type: ItemPlacer
|
||||||
whitelist:
|
whitelist:
|
||||||
components:
|
components:
|
||||||
- FitsInDispenser
|
- FitsInDispenser
|
||||||
|
|||||||
Reference in New Issue
Block a user