mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 18:31:17 +03:00
* Predict Light Replacers * Public once more * Light changes * Introduce an OrderList. * Added Radial Menu * Fix missing Dirty() * Introduce EntityProvider * Migratiooon! * Adress Reviews * Forgot Comments * Test-Fail Fix * Fixes * Update buttons * Revert "Update buttons" This reverts commit f84d8f2502600905a2ab4bce5463af6f2b4b1c3e. * Introduce Dedicated Short String * review * Another review has hit the PR Co-Authored-By: Whatstone <166147148+whatston3@users.noreply.github.com> * Adressing reviews Co-Authored-By: Whatstone <166147148+whatston3@users.noreply.github.com> * Update LightReplacerMenuBoundUserInterface.cs * refactor: do not pass ref type by ref, try not to create impure methods where it is not required * refactor: random xml-doc changes * refactor: more xml-doc, and 1 call per line convention * Small fixes * Iterate through the container * updated xml docs * IReadOnlyfix * refactor: renaming, whitespaces, use deconstructor in foreach, use Enumerable instead of creating additional list when its possible that it will be empty and wont be modified * refactor: fix collction cloning to not throw during modificaiton * Replace popups with sounds. * Added singular sounds * refactor: fix error on moving items from one EntityProvider to another and back when they have some spawned entities in container * Replaced Popup with Sound --------- Co-authored-by: Pok245 <113675512+Pok27@users.noreply.github.com> Co-authored-by: Whatstone <166147148+whatston3@users.noreply.github.com> Co-authored-by: Fildrance <fildrance@gmail.com>
184 lines
7.2 KiB
C#
184 lines
7.2 KiB
C#
using Content.Shared.Examine;
|
|
using Content.Shared.Interaction;
|
|
using Content.Shared.Interaction.Events;
|
|
using Content.Shared.Light.Components;
|
|
using Content.Shared.Light.Events;
|
|
using Content.Shared.Popups;
|
|
using Content.Shared.Storage.EntitySystems;
|
|
using Content.Shared.Storage.Events;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Serialization;
|
|
|
|
namespace Content.Shared.Light.EntitySystems;
|
|
|
|
/// <summary>
|
|
/// System that handles light replacer tool (which picks proper light entity for socket
|
|
/// and replaces it with other one, hopefully working one!).
|
|
/// </summary>
|
|
public sealed partial class LightReplacerSystem : EntitySystem
|
|
{
|
|
[Dependency] private SharedAudioSystem _audio = default!;
|
|
[Dependency] private EntityProviderSystem _provider = default!;
|
|
[Dependency] private SharedPopupSystem _popup = default!;
|
|
[Dependency] private SharedPoweredLightSystem _poweredLight = default!;
|
|
[Dependency] private SharedUserInterfaceSystem _ui = default!;
|
|
|
|
[Dependency] private EntityQuery<LightBulbComponent> _lightBulbQuery = default!;
|
|
|
|
/// <summary> Adds contents info into examine. </summary>
|
|
[SubscribeLocalEvent]
|
|
private void OnExamined(Entity<LightReplacerComponent> replacer, ref ExaminedEvent args)
|
|
{
|
|
if (!_provider.TryGetEntityCounter(replacer.Owner, out var entities))
|
|
return;
|
|
|
|
using (args.PushGroup(nameof(LightReplacerComponent)))
|
|
{
|
|
if (entities.Count == 0)
|
|
{
|
|
args.PushMarkup(Loc.GetString("comp-light-replacer-no-lights"));
|
|
return;
|
|
}
|
|
|
|
args.PushMarkup(Loc.GetString("comp-light-replacer-has-lights"));
|
|
|
|
foreach (var bulb in entities)
|
|
{
|
|
if (!ProtoMan.Resolve(bulb.Key, out var bulbPrototype))
|
|
continue;
|
|
|
|
args.PushMarkup(Loc.GetString("comp-light-replacer-light-listing", ("amount", bulb.Value), ("name", bulbPrototype.Name)));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary> Attempts to open UI for replacer, if there are any viable options to put into it. </summary>
|
|
[SubscribeLocalEvent]
|
|
private void OnUse(Entity<LightReplacerComponent> replacer, ref UseInHandEvent args)
|
|
{
|
|
if (args.Handled || !_provider.TryGetEntityCounter(replacer.Owner, out var entities))
|
|
return;
|
|
|
|
args.ApplyDelay = false;
|
|
|
|
if (entities.Count == 0)
|
|
{
|
|
_popup.PopupEntity(Loc.GetString("comp-light-replacer-open-empty", ("light-replacer", replacer)), replacer, args.User);
|
|
return;
|
|
}
|
|
|
|
args.Handled = true;
|
|
_ui.OpenUi(replacer.Owner, LightReplacerUiKey.Key, args.User);
|
|
}
|
|
|
|
/// <summary> Tries to replace bulb/tube if applicable.</summary>
|
|
[SubscribeLocalEvent]
|
|
private void OnAfterInteract(Entity<LightReplacerComponent> replacer, ref AfterInteractEvent eventArgs)
|
|
{
|
|
if (eventArgs.Handled
|
|
|| !eventArgs.CanReach // standard interaction checks
|
|
|| eventArgs.Target == null) // behavior will depend on the target type
|
|
return;
|
|
|
|
var targetUid = (EntityUid) eventArgs.Target;
|
|
|
|
// replace broken light in fixture?
|
|
if (TryComp<PoweredLightComponent>(targetUid, out var fixture))
|
|
eventArgs.Handled = TryReplaceBulb(replacer.AsNullable(), (targetUid, fixture), eventArgs.User);
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnEjectMessage(Entity<LightReplacerComponent> replacer, ref EjectLightTypeMessage args)
|
|
{
|
|
_provider.TryEjectEntities(replacer.Owner, args.LightEntProtoId, out _, user: args.Actor);
|
|
}
|
|
|
|
/// <summary> Attempts to switch currently selected bulb type according to request. </summary>
|
|
[SubscribeLocalEvent]
|
|
private void OnSwitchMessage(Entity<LightReplacerComponent> replacer, ref SwitchLightTypeMessage args)
|
|
{
|
|
if (!ProtoMan.Resolve(args.LightEntProtoId, out var prototype)
|
|
|| !_provider.TryGetEntityCounter(replacer.Owner, out var entities)
|
|
|| !entities.TryGetValue(args.LightEntProtoId, out var amount)
|
|
|| amount <= 0)
|
|
return;
|
|
|
|
if (args.LightType == LightBulbType.Tube)
|
|
replacer.Comp.ActiveLightTube = args.LightEntProtoId;
|
|
else
|
|
replacer.Comp.ActiveLightBulb = args.LightEntProtoId;
|
|
|
|
Dirty(replacer);
|
|
|
|
_audio.PlayPredicted(replacer.Comp.Sound, replacer, args.Actor);
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnLightProviderInsertedCheck(Entity<LightBulbComponent> bulb, ref EntityProviderInsertCheckEvent args)
|
|
{
|
|
if (bulb.Comp.State == LightBulbState.Broken)
|
|
args.FailureMessage = Loc.GetString("comp-light-replacer-insert-broken-light");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Try to replace a light bulb in <paramref name="lightHolder"/>
|
|
/// using light replacer. Light fixture should have <see cref="PoweredLightComponent"/>.
|
|
/// </summary>
|
|
/// <param name="replacer">The light replacer used to replace the bulb.</param>
|
|
/// <param name="lightHolder">The fixture whose light is being replaced.</param>
|
|
/// <param name="userUid">The user who is replacing the light.</param>
|
|
/// <returns>True if successfully replaced light, false otherwise</returns>
|
|
public bool TryReplaceBulb(Entity<LightReplacerComponent?> replacer, Entity<PoweredLightComponent?> lightHolder, EntityUid? userUid = null)
|
|
{
|
|
if (!Resolve(replacer, ref replacer.Comp)
|
|
|| !Resolve(lightHolder, ref lightHolder.Comp))
|
|
return false;
|
|
|
|
var activeType = lightHolder.Comp.BulbType == LightBulbType.Tube
|
|
? replacer.Comp.ActiveLightTube
|
|
: replacer.Comp.ActiveLightBulb;
|
|
|
|
// check if light bulb is broken or missing
|
|
EntityUid? currentBulbInHolder = _poweredLight.GetBulb(lightHolder, lightHolder.Comp);
|
|
if (currentBulbInHolder != null)
|
|
{
|
|
if (!_lightBulbQuery.TryComp(currentBulbInHolder.Value, out var fixtureBulb))
|
|
return false;
|
|
|
|
var prototype = MetaData(currentBulbInHolder.Value).EntityPrototype;
|
|
|
|
if (fixtureBulb.State == LightBulbState.Normal && prototype != null && prototype.ID == activeType)
|
|
{
|
|
_popup.PopupEntity(Loc.GetString("comp-light-replacer-same-light", ("light", currentBulbInHolder)), lightHolder, userUid, PopupType.Medium);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!_provider.TryGetEntity(replacer.Owner, activeType, out var insertedBulb))
|
|
{
|
|
if (userUid == null || !ProtoMan.Resolve(activeType, out var bulbPrototype))
|
|
return false;
|
|
|
|
var msg = Loc.GetString("comp-light-replacer-missing-light",
|
|
("light-name", bulbPrototype.Name),
|
|
("light-replacer", replacer));
|
|
_popup.PopupEntity(msg, replacer, userUid.Value);
|
|
return false;
|
|
}
|
|
|
|
// insert it into fixture
|
|
var wasReplaced = _poweredLight.ReplaceBulb(lightHolder, insertedBulb.Value, lightHolder.Comp);
|
|
if (wasReplaced)
|
|
{
|
|
_audio.PlayPredicted(replacer.Comp.Sound, replacer, userUid);
|
|
}
|
|
|
|
return wasReplaced;
|
|
}
|
|
}
|
|
|
|
[Serializable, NetSerializable]
|
|
public enum LightReplacerUiKey : byte
|
|
{
|
|
Key,
|
|
}
|