Merge 76f2a66b7c into c3c6a6abd9
This commit is contained in:
commit
e2c55dbb04
|
|
@ -0,0 +1,126 @@
|
|||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._DV.Light.Events;
|
||||
using Content.Shared.Light.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._DV.Light.BoundUserInterfaces;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class LightReplacerMenuBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
|
||||
{
|
||||
private EntityQuery<LightBulbComponent> _lightBulbQuery;
|
||||
private EntityQuery<MetaDataComponent> _metaDataQuery;
|
||||
|
||||
private SimpleRadialMenu? _menu;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_lightBulbQuery = EntMan.GetEntityQuery<LightBulbComponent>();
|
||||
_metaDataQuery = EntMan.GetEntityQuery<MetaDataComponent>();
|
||||
|
||||
if (!EntMan.TryGetComponent<LightReplacerComponent>(Owner, out var replacer))
|
||||
return;
|
||||
|
||||
var lightTypes = CreateButtons(replacer);
|
||||
|
||||
if (lightTypes == null)
|
||||
return;
|
||||
|
||||
_menu = this.CreateWindow<SimpleRadialMenu>();
|
||||
_menu.SetButtons(lightTypes);
|
||||
|
||||
_menu.OpenCentered();
|
||||
}
|
||||
|
||||
private List<RadialMenuOptionBase>? CreateButtons(LightReplacerComponent replacer)
|
||||
{
|
||||
var options = new List<RadialMenuOptionBase>();
|
||||
|
||||
Dictionary<string, EntityUid> tubes = [];
|
||||
Dictionary<string, EntityUid> bulbs = [];
|
||||
|
||||
var hasActiveTubes = false;
|
||||
var hasActiveBulbs = false;
|
||||
|
||||
foreach (var light in replacer.InsertedBulbs.ContainedEntities)
|
||||
{
|
||||
if (!_lightBulbQuery.TryComp(light, out var bulb)
|
||||
|| !_metaDataQuery.TryComp(light, out var metaData))
|
||||
continue;
|
||||
|
||||
if (bulb.Type == LightBulbType.Tube)
|
||||
{
|
||||
if (metaData.EntityName != replacer.ActiveLightTube)
|
||||
tubes.TryAdd(metaData.EntityName, light);
|
||||
else
|
||||
hasActiveTubes = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (metaData.EntityName != replacer.ActiveLightBulb)
|
||||
bulbs.TryAdd(metaData.EntityName, light);
|
||||
else
|
||||
hasActiveBulbs = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasActiveTubes)
|
||||
{
|
||||
var toggleLightTubes = new RadialMenuActionOption<string>(EjectLights, replacer.ActiveLightTube)
|
||||
{
|
||||
IconSpecifier = RadialMenuIconSpecifier.With(replacer.EjectTubes),
|
||||
ToolTip = Loc.GetString("comp-light-replacer-eject-specified-lights", ("light-name", replacer.ActiveLightTube)),
|
||||
};
|
||||
options.Add(toggleLightTubes);
|
||||
}
|
||||
|
||||
if (hasActiveBulbs)
|
||||
{
|
||||
var toggleLightBulbs = new RadialMenuActionOption<string>(EjectLights, replacer.ActiveLightBulb)
|
||||
{
|
||||
IconSpecifier = RadialMenuIconSpecifier.With(replacer.EjectBulbs),
|
||||
ToolTip = Loc.GetString("comp-light-replacer-eject-specified-lights", ("light-name", replacer.ActiveLightBulb)),
|
||||
};
|
||||
options.Add(toggleLightBulbs);
|
||||
}
|
||||
|
||||
// This iterates through every unique light to add them as options.
|
||||
foreach (var light in tubes)
|
||||
{
|
||||
PopulateOptions(light.Key, light.Value, LightBulbType.Tube, ref options);
|
||||
}
|
||||
|
||||
foreach (var light in bulbs)
|
||||
{
|
||||
PopulateOptions(light.Key, light.Value, LightBulbType.Bulb, ref options);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private void PopulateOptions(string name, EntityUid light, LightBulbType lightType, ref List<RadialMenuOptionBase> options)
|
||||
{
|
||||
var switchLight = new RadialMenuActionOption<(string, LightBulbType)>(SwitchActiveLight, (name, lightType))
|
||||
{
|
||||
IconSpecifier = RadialMenuIconSpecifier.With(light),
|
||||
ToolTip = Loc.GetString("comp-light-replacer-select-lights", ("light-name", name)),
|
||||
};
|
||||
options.Add(switchLight);
|
||||
}
|
||||
|
||||
private void SwitchActiveLight((string, LightBulbType) light)
|
||||
{
|
||||
var message = new SwitchLightTypeMessage(light);
|
||||
SendPredictedMessage(message);
|
||||
}
|
||||
|
||||
private void EjectLights(string lightName)
|
||||
{
|
||||
var message = new EjectLightTypeMessage(lightName);
|
||||
SendPredictedMessage(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
using Content.Client.Message;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Light.Components;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._DV.Light.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the label on the light replacer
|
||||
/// </summary>
|
||||
public sealed class LightReplacerStatusControl : Control
|
||||
{
|
||||
|
||||
private readonly Entity<LightReplacerComponent> _parent;
|
||||
private readonly RichTextLabel _label;
|
||||
|
||||
private string? _prevActiveLightTube;
|
||||
private string? _prevActiveLightBulb;
|
||||
private string? _labelTube;
|
||||
private string? _labelBulb;
|
||||
|
||||
public LightReplacerStatusControl(Entity<LightReplacerComponent> parent)
|
||||
{
|
||||
_parent = parent;
|
||||
_label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
|
||||
AddChild(_label);
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
// only updates the UI if any of the details are different than they previously were
|
||||
if (_prevActiveLightTube == _parent.Comp.ActiveLightTube
|
||||
&& _prevActiveLightBulb == _parent.Comp.ActiveLightBulb)
|
||||
return;
|
||||
|
||||
_prevActiveLightTube = _parent.Comp.ActiveLightTube;
|
||||
_prevActiveLightBulb = _parent.Comp.ActiveLightBulb;
|
||||
_labelTube = _prevActiveLightTube;
|
||||
_labelBulb = _prevActiveLightBulb;
|
||||
|
||||
// Remove " light tube" at the end to save precious label space.
|
||||
if (_labelTube.EndsWith(" light tube"))
|
||||
{
|
||||
_labelTube = _labelTube.Remove(_labelTube.Length - 11);
|
||||
// Remove " crystal" in case of colored lights
|
||||
if (_labelTube.EndsWith(" crystal"))
|
||||
_labelTube = _labelTube.Remove(_labelTube.Length - 8);
|
||||
}
|
||||
// Same with bulbs.
|
||||
if (_labelBulb.EndsWith(" light bulb"))
|
||||
{
|
||||
_labelBulb = _labelBulb.Remove(_labelBulb.Length - 11);
|
||||
if (_labelBulb.EndsWith(" crystal"))
|
||||
_labelBulb = _labelBulb.Remove(_labelBulb.Length - 8);
|
||||
}
|
||||
|
||||
// Update current active lights
|
||||
_label.SetMarkup(Loc.GetString("comp-light-replacer-label",
|
||||
("tube", _labelTube),
|
||||
("bulb", _labelBulb)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using Content.Client._DV.Light.Controls;
|
||||
using Content.Client.Items;
|
||||
using Content.Shared.Light.Components;
|
||||
|
||||
namespace Content.Client._DV.Light.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the label on the light replacer
|
||||
/// </summary>
|
||||
public sealed class LightReplacerStatusControlSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
Subs.ItemStatus<LightReplacerComponent>(replacer => new LightReplacerStatusControl(replacer));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,242 +1,243 @@
|
|||
using System.Linq;
|
||||
using Content.Server.Light.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Light.EntitySystems;
|
||||
using Content.Shared.Light.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Storage;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Server.Light.EntitySystems;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class LightReplacerSystem : SharedLightReplacerSystem
|
||||
{
|
||||
[Dependency] private readonly PoweredLightSystem _poweredLight = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LightReplacerComponent, ExaminedEvent>(OnExamined);
|
||||
SubscribeLocalEvent<LightReplacerComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<LightReplacerComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<LightReplacerComponent, InteractUsingEvent>(HandleInteract);
|
||||
SubscribeLocalEvent<LightReplacerComponent, AfterInteractEvent>(HandleAfterInteract);
|
||||
}
|
||||
|
||||
private void OnExamined(EntityUid uid, LightReplacerComponent component, ExaminedEvent args)
|
||||
{
|
||||
using (args.PushGroup(nameof(LightReplacerComponent)))
|
||||
{
|
||||
if (!component.InsertedBulbs.ContainedEntities.Any())
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("comp-light-replacer-no-lights"));
|
||||
return;
|
||||
}
|
||||
|
||||
args.PushMarkup(Loc.GetString("comp-light-replacer-has-lights"));
|
||||
var groups = new Dictionary<string, int>();
|
||||
var metaQuery = GetEntityQuery<MetaDataComponent>();
|
||||
foreach (var bulb in component.InsertedBulbs.ContainedEntities)
|
||||
{
|
||||
var metaData = metaQuery.GetComponent(bulb);
|
||||
groups[metaData.EntityName] = groups.GetValueOrDefault(metaData.EntityName) + 1;
|
||||
}
|
||||
|
||||
foreach (var (name, amount) in groups)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("comp-light-replacer-light-listing", ("amount", amount), ("name", name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, LightReplacerComponent component, MapInitEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
foreach (var spawn in EntitySpawnCollection.GetSpawns(component.Contents))
|
||||
{
|
||||
var ent = Spawn(spawn, xform.Coordinates);
|
||||
TryInsertBulb(uid, ent, replacer: component);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, LightReplacerComponent replacer, ComponentInit args)
|
||||
{
|
||||
replacer.InsertedBulbs = _container.EnsureContainer<Container>(uid, "light_replacer_storage");
|
||||
}
|
||||
|
||||
private void HandleAfterInteract(EntityUid uid, LightReplacerComponent component, AfterInteractEvent eventArgs)
|
||||
{
|
||||
if (eventArgs.Handled)
|
||||
return;
|
||||
|
||||
// standard interaction checks
|
||||
if (!eventArgs.CanReach)
|
||||
return;
|
||||
|
||||
// behaviour will depends on target type
|
||||
if (eventArgs.Target != null)
|
||||
{
|
||||
var targetUid = (EntityUid) eventArgs.Target;
|
||||
|
||||
// replace broken light in fixture?
|
||||
if (TryComp<PoweredLightComponent>(targetUid, out var fixture))
|
||||
eventArgs.Handled = TryReplaceBulb(uid, targetUid, eventArgs.User, component, fixture);
|
||||
// add new bulb to light replacer container?
|
||||
else if (TryComp<LightBulbComponent>(targetUid, out var bulb))
|
||||
eventArgs.Handled = TryInsertBulb(uid, targetUid, eventArgs.User, true, component, bulb);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleInteract(EntityUid uid, LightReplacerComponent component, InteractUsingEvent eventArgs)
|
||||
{
|
||||
if (eventArgs.Handled)
|
||||
return;
|
||||
|
||||
var usedUid = eventArgs.Used;
|
||||
|
||||
// want to insert a new light bulb?
|
||||
if (TryComp<LightBulbComponent>(usedUid, out var bulb))
|
||||
eventArgs.Handled = TryInsertBulb(uid, usedUid, eventArgs.User, true, component, bulb);
|
||||
// add bulbs from storage?
|
||||
else if (TryComp<StorageComponent>(usedUid, out var storage))
|
||||
eventArgs.Handled = TryInsertBulbsFromStorage(uid, usedUid, eventArgs.User, component, storage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to replace a light bulb in <paramref name="fixtureUid"/>
|
||||
/// using light replacer. Light fixture should have <see cref="PoweredLightComponent"/>.
|
||||
/// </summary>
|
||||
/// <returns>True if successfully replaced light, false otherwise</returns>
|
||||
public bool TryReplaceBulb(EntityUid replacerUid, EntityUid fixtureUid, EntityUid? userUid = null,
|
||||
LightReplacerComponent? replacer = null, PoweredLightComponent? fixture = null)
|
||||
{
|
||||
if (!Resolve(replacerUid, ref replacer))
|
||||
return false;
|
||||
if (!Resolve(fixtureUid, ref fixture))
|
||||
return false;
|
||||
|
||||
// check if light bulb is broken or missing
|
||||
var fixtureBulbUid = _poweredLight.GetBulb(fixtureUid, fixture);
|
||||
if (fixtureBulbUid != null)
|
||||
{
|
||||
if (!TryComp<LightBulbComponent>(fixtureBulbUid.Value, out var fixtureBulb))
|
||||
return false;
|
||||
if (fixtureBulb.State == LightBulbState.Normal)
|
||||
return false;
|
||||
}
|
||||
|
||||
// try get first inserted bulb of the same type as targeted light fixtutre
|
||||
var bulb = replacer.InsertedBulbs.ContainedEntities.FirstOrDefault(
|
||||
e => CompOrNull<LightBulbComponent>(e)?.Type == fixture.BulbType);
|
||||
|
||||
// found bulb in inserted storage
|
||||
if (bulb.Valid) // FirstOrDefault can return default/invalid uid.
|
||||
{
|
||||
// try to remove it
|
||||
var hasRemoved = _container.Remove(bulb, replacer.InsertedBulbs);
|
||||
if (!hasRemoved)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (userUid != null)
|
||||
{
|
||||
var msg = Loc.GetString("comp-light-replacer-missing-light",
|
||||
("light-replacer", replacerUid));
|
||||
_popupSystem.PopupEntity(msg, replacerUid, userUid.Value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// insert it into fixture
|
||||
var wasReplaced = _poweredLight.ReplaceBulb(fixtureUid, bulb, fixture);
|
||||
if (wasReplaced)
|
||||
{
|
||||
_audio.PlayPvs(replacer.Sound, replacerUid);
|
||||
}
|
||||
|
||||
return wasReplaced;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to insert a new bulb inside light replacer
|
||||
/// </summary>
|
||||
/// <returns>True if successfully inserted light, false otherwise</returns>
|
||||
public bool TryInsertBulb(EntityUid replacerUid, EntityUid bulbUid, EntityUid? userUid = null, bool showTooltip = false,
|
||||
LightReplacerComponent? replacer = null, LightBulbComponent? bulb = null)
|
||||
{
|
||||
if (!Resolve(replacerUid, ref replacer))
|
||||
return false;
|
||||
if (!Resolve(bulbUid, ref bulb))
|
||||
return false;
|
||||
|
||||
// only normal (non-broken) bulbs can be inserted inside light replacer
|
||||
if (bulb.State != LightBulbState.Normal)
|
||||
{
|
||||
if (showTooltip && userUid != null)
|
||||
{
|
||||
var msg = Loc.GetString("comp-light-replacer-insert-broken-light");
|
||||
_popupSystem.PopupEntity(msg, replacerUid, userUid.Value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// try insert light and show message
|
||||
var hasInsert = _container.Insert(bulbUid, replacer.InsertedBulbs);
|
||||
if (hasInsert && showTooltip && userUid != null)
|
||||
{
|
||||
var msg = Loc.GetString("comp-light-replacer-insert-light",
|
||||
("light-replacer", replacerUid), ("bulb", bulbUid));
|
||||
_popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium);
|
||||
}
|
||||
|
||||
return hasInsert;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to insert all light bulbs from storage (for example light tubes box)
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Returns true if storage contained at least one light bulb
|
||||
/// which was successfully inserted inside light replacer
|
||||
/// </returns>
|
||||
public bool TryInsertBulbsFromStorage(EntityUid replacerUid, EntityUid storageUid, EntityUid? userUid = null,
|
||||
LightReplacerComponent? replacer = null, StorageComponent? storage = null)
|
||||
{
|
||||
if (!Resolve(replacerUid, ref replacer))
|
||||
return false;
|
||||
if (!Resolve(storageUid, ref storage))
|
||||
return false;
|
||||
|
||||
var insertedBulbs = 0;
|
||||
var storagedEnts = storage.Container.ContainedEntities.ToArray();
|
||||
|
||||
foreach (var ent in storagedEnts)
|
||||
{
|
||||
if (TryComp<LightBulbComponent>(ent, out var bulb) &&
|
||||
TryInsertBulb(replacerUid, ent, userUid, false, replacer, bulb))
|
||||
{
|
||||
insertedBulbs++;
|
||||
}
|
||||
}
|
||||
|
||||
// show some message if success
|
||||
if (insertedBulbs > 0 && userUid != null)
|
||||
{
|
||||
var msg = Loc.GetString("comp-light-replacer-refill-from-storage", ("light-replacer", replacerUid));
|
||||
_popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium);
|
||||
}
|
||||
|
||||
return insertedBulbs > 0;
|
||||
}
|
||||
}
|
||||
// THIS HAS BEEN REMOVED BECAUSE THIS SYSTEM WAS OVERHAULED IN Delta-V!
|
||||
// using System.Linq;
|
||||
// using Content.Server.Light.Components;
|
||||
// using Content.Shared.Examine;
|
||||
// using Content.Shared.Interaction;
|
||||
// using Content.Shared.Light.EntitySystems;
|
||||
// using Content.Shared.Light.Components;
|
||||
// using Content.Shared.Popups;
|
||||
// using Content.Shared.Storage;
|
||||
// using JetBrains.Annotations;
|
||||
// using Robust.Shared.Audio;
|
||||
// using Robust.Shared.Audio.Systems;
|
||||
// using Robust.Shared.Containers;
|
||||
//
|
||||
// namespace Content.Server.Light.EntitySystems;
|
||||
//
|
||||
// [UsedImplicitly]
|
||||
// public sealed class LightReplacerSystem : SharedLightReplacerSystem
|
||||
// {
|
||||
// [Dependency] private readonly PoweredLightSystem _poweredLight = default!;
|
||||
// [Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
// [Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
// [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
//
|
||||
// public override void Initialize()
|
||||
// {
|
||||
// base.Initialize();
|
||||
//
|
||||
// SubscribeLocalEvent<LightReplacerComponent, ExaminedEvent>(OnExamined);
|
||||
// SubscribeLocalEvent<LightReplacerComponent, MapInitEvent>(OnMapInit);
|
||||
// SubscribeLocalEvent<LightReplacerComponent, ComponentInit>(OnInit);
|
||||
// SubscribeLocalEvent<LightReplacerComponent, InteractUsingEvent>(HandleInteract);
|
||||
// SubscribeLocalEvent<LightReplacerComponent, AfterInteractEvent>(HandleAfterInteract);
|
||||
// }
|
||||
//
|
||||
// private void OnExamined(EntityUid uid, LightReplacerComponent component, ExaminedEvent args)
|
||||
// {
|
||||
// using (args.PushGroup(nameof(LightReplacerComponent)))
|
||||
// {
|
||||
// if (!component.InsertedBulbs.ContainedEntities.Any())
|
||||
// {
|
||||
// args.PushMarkup(Loc.GetString("comp-light-replacer-no-lights"));
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// args.PushMarkup(Loc.GetString("comp-light-replacer-has-lights"));
|
||||
// var groups = new Dictionary<string, int>();
|
||||
// var metaQuery = GetEntityQuery<MetaDataComponent>();
|
||||
// foreach (var bulb in component.InsertedBulbs.ContainedEntities)
|
||||
// {
|
||||
// var metaData = metaQuery.GetComponent(bulb);
|
||||
// groups[metaData.EntityName] = groups.GetValueOrDefault(metaData.EntityName) + 1;
|
||||
// }
|
||||
//
|
||||
// foreach (var (name, amount) in groups)
|
||||
// {
|
||||
// args.PushMarkup(Loc.GetString("comp-light-replacer-light-listing", ("amount", amount), ("name", name)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void OnMapInit(EntityUid uid, LightReplacerComponent component, MapInitEvent args)
|
||||
// {
|
||||
// var xform = Transform(uid);
|
||||
// foreach (var spawn in EntitySpawnCollection.GetSpawns(component.Contents))
|
||||
// {
|
||||
// var ent = Spawn(spawn, xform.Coordinates);
|
||||
// TryInsertBulb(uid, ent, replacer: component);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void OnInit(EntityUid uid, LightReplacerComponent replacer, ComponentInit args)
|
||||
// {
|
||||
// replacer.InsertedBulbs = _container.EnsureContainer<Container>(uid, "light_replacer_storage");
|
||||
// }
|
||||
//
|
||||
// private void HandleAfterInteract(EntityUid uid, LightReplacerComponent component, AfterInteractEvent eventArgs)
|
||||
// {
|
||||
// if (eventArgs.Handled)
|
||||
// return;
|
||||
//
|
||||
// // standard interaction checks
|
||||
// if (!eventArgs.CanReach)
|
||||
// return;
|
||||
//
|
||||
// // behaviour will depends on target type
|
||||
// if (eventArgs.Target != null)
|
||||
// {
|
||||
// var targetUid = (EntityUid) eventArgs.Target;
|
||||
//
|
||||
// // replace broken light in fixture?
|
||||
// if (TryComp<PoweredLightComponent>(targetUid, out var fixture))
|
||||
// eventArgs.Handled = TryReplaceBulb(uid, targetUid, eventArgs.User, component, fixture);
|
||||
// // add new bulb to light replacer container?
|
||||
// else if (TryComp<LightBulbComponent>(targetUid, out var bulb))
|
||||
// eventArgs.Handled = TryInsertBulb(uid, targetUid, eventArgs.User, true, component, bulb);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void HandleInteract(EntityUid uid, LightReplacerComponent component, InteractUsingEvent eventArgs)
|
||||
// {
|
||||
// if (eventArgs.Handled)
|
||||
// return;
|
||||
//
|
||||
// var usedUid = eventArgs.Used;
|
||||
//
|
||||
// // want to insert a new light bulb?
|
||||
// if (TryComp<LightBulbComponent>(usedUid, out var bulb))
|
||||
// eventArgs.Handled = TryInsertBulb(uid, usedUid, eventArgs.User, true, component, bulb);
|
||||
// // add bulbs from storage?
|
||||
// else if (TryComp<StorageComponent>(usedUid, out var storage))
|
||||
// eventArgs.Handled = TryInsertBulbsFromStorage(uid, usedUid, eventArgs.User, component, storage);
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Try to replace a light bulb in <paramref name="fixtureUid"/>
|
||||
// /// using light replacer. Light fixture should have <see cref="PoweredLightComponent"/>.
|
||||
// /// </summary>
|
||||
// /// <returns>True if successfully replaced light, false otherwise</returns>
|
||||
// public bool TryReplaceBulb(EntityUid replacerUid, EntityUid fixtureUid, EntityUid? userUid = null,
|
||||
// LightReplacerComponent? replacer = null, PoweredLightComponent? fixture = null)
|
||||
// {
|
||||
// if (!Resolve(replacerUid, ref replacer))
|
||||
// return false;
|
||||
// if (!Resolve(fixtureUid, ref fixture))
|
||||
// return false;
|
||||
//
|
||||
// // check if light bulb is broken or missing
|
||||
// var fixtureBulbUid = _poweredLight.GetBulb(fixtureUid, fixture);
|
||||
// if (fixtureBulbUid != null)
|
||||
// {
|
||||
// if (!TryComp<LightBulbComponent>(fixtureBulbUid.Value, out var fixtureBulb))
|
||||
// return false;
|
||||
// if (fixtureBulb.State == LightBulbState.Normal)
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // try get first inserted bulb of the same type as targeted light fixtutre
|
||||
// var bulb = replacer.InsertedBulbs.ContainedEntities.FirstOrDefault(
|
||||
// e => CompOrNull<LightBulbComponent>(e)?.Type == fixture.BulbType);
|
||||
//
|
||||
// // found bulb in inserted storage
|
||||
// if (bulb.Valid) // FirstOrDefault can return default/invalid uid.
|
||||
// {
|
||||
// // try to remove it
|
||||
// var hasRemoved = _container.Remove(bulb, replacer.InsertedBulbs);
|
||||
// if (!hasRemoved)
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (userUid != null)
|
||||
// {
|
||||
// var msg = Loc.GetString("comp-light-replacer-missing-light",
|
||||
// ("light-replacer", replacerUid));
|
||||
// _popupSystem.PopupEntity(msg, replacerUid, userUid.Value);
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // insert it into fixture
|
||||
// var wasReplaced = _poweredLight.ReplaceBulb(fixtureUid, bulb, fixture);
|
||||
// if (wasReplaced)
|
||||
// {
|
||||
// _audio.PlayPvs(replacer.Sound, replacerUid);
|
||||
// }
|
||||
//
|
||||
// return wasReplaced;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Try to insert a new bulb inside light replacer
|
||||
// /// </summary>
|
||||
// /// <returns>True if successfully inserted light, false otherwise</returns>
|
||||
// public bool TryInsertBulb(EntityUid replacerUid, EntityUid bulbUid, EntityUid? userUid = null, bool showTooltip = false,
|
||||
// LightReplacerComponent? replacer = null, LightBulbComponent? bulb = null)
|
||||
// {
|
||||
// if (!Resolve(replacerUid, ref replacer))
|
||||
// return false;
|
||||
// if (!Resolve(bulbUid, ref bulb))
|
||||
// return false;
|
||||
//
|
||||
// // only normal (non-broken) bulbs can be inserted inside light replacer
|
||||
// if (bulb.State != LightBulbState.Normal)
|
||||
// {
|
||||
// if (showTooltip && userUid != null)
|
||||
// {
|
||||
// var msg = Loc.GetString("comp-light-replacer-insert-broken-light");
|
||||
// _popupSystem.PopupEntity(msg, replacerUid, userUid.Value);
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // try insert light and show message
|
||||
// var hasInsert = _container.Insert(bulbUid, replacer.InsertedBulbs);
|
||||
// if (hasInsert && showTooltip && userUid != null)
|
||||
// {
|
||||
// var msg = Loc.GetString("comp-light-replacer-insert-light",
|
||||
// ("light-replacer", replacerUid), ("bulb", bulbUid));
|
||||
// _popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium);
|
||||
// }
|
||||
//
|
||||
// return hasInsert;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Try to insert all light bulbs from storage (for example light tubes box)
|
||||
// /// </summary>
|
||||
// /// <returns>
|
||||
// /// Returns true if storage contained at least one light bulb
|
||||
// /// which was successfully inserted inside light replacer
|
||||
// /// </returns>
|
||||
// public bool TryInsertBulbsFromStorage(EntityUid replacerUid, EntityUid storageUid, EntityUid? userUid = null,
|
||||
// LightReplacerComponent? replacer = null, StorageComponent? storage = null)
|
||||
// {
|
||||
// if (!Resolve(replacerUid, ref replacer))
|
||||
// return false;
|
||||
// if (!Resolve(storageUid, ref storage))
|
||||
// return false;
|
||||
//
|
||||
// var insertedBulbs = 0;
|
||||
// var storagedEnts = storage.Container.ContainedEntities.ToArray();
|
||||
//
|
||||
// foreach (var ent in storagedEnts)
|
||||
// {
|
||||
// if (TryComp<LightBulbComponent>(ent, out var bulb) &&
|
||||
// TryInsertBulb(replacerUid, ent, userUid, false, replacer, bulb))
|
||||
// {
|
||||
// insertedBulbs++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // show some message if success
|
||||
// if (insertedBulbs > 0 && userUid != null)
|
||||
// {
|
||||
// var msg = Loc.GetString("comp-light-replacer-refill-from-storage", ("light-replacer", replacerUid));
|
||||
// _popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium);
|
||||
// }
|
||||
//
|
||||
// return insertedBulbs > 0;
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Content.Shared.Storage;
|
|||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Utility; // DeltaV - Predicted Light Replacer & Added Radial Menu
|
||||
|
||||
namespace Content.Shared.Light.Components;
|
||||
|
||||
|
|
@ -11,7 +12,8 @@ namespace Content.Shared.Light.Components;
|
|||
/// Device that allows user to quikly change bulbs in <see cref="PoweredLightComponent"/>
|
||||
/// Can be reloaded by new light tubes or light bulbs
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedLightReplacerSystem))]
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] // DeltaV - Predicted Light Replacer & Added Radial Menu
|
||||
[Access(typeof(SharedLightReplacerSystem))]
|
||||
public sealed partial class LightReplacerComponent : Component
|
||||
{
|
||||
[DataField("sound")]
|
||||
|
|
@ -34,4 +36,30 @@ public sealed partial class LightReplacerComponent : Component
|
|||
/// </summary>
|
||||
[DataField("contents")]
|
||||
public List<EntitySpawnEntry> Contents = new();
|
||||
|
||||
// Start DeltaV - Predicting Light Replacers & Adding Radial Menu
|
||||
/// <summary>
|
||||
/// This string defines what kind of tube will be inserted into light fixtures.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public string ActiveLightTube = "fluorescent light tube";
|
||||
|
||||
/// <summary>
|
||||
/// This string defines what kind of bulb will be inserted into light fixtures.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public string ActiveLightBulb = "incandescent light bulb";
|
||||
|
||||
/// <summary>
|
||||
/// The Icon Sprite for ejecting tubes in the radial menu.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SpriteSpecifier EjectTubes = new SpriteSpecifier.Rsi(new ResPath("_DV/Objects/Specific/Janitorial/light_replacer.rsi"), "eject-tubes");
|
||||
|
||||
/// <summary>
|
||||
/// The Icon Sprite for ejecting bulbs in the radial menu.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SpriteSpecifier EjectBulbs = new SpriteSpecifier.Rsi(new ResPath("_DV/Objects/Specific/Janitorial/light_replacer.rsi"), "eject-bulbs");
|
||||
// End DeltaV - Predicting Light Replacers & Adding Radial Menu
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,308 @@
|
|||
using System.Linq;
|
||||
using Content.Shared._DV.Light.Events;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Light.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Light.EntitySystems;
|
||||
|
||||
public abstract class SharedLightReplacerSystem : EntitySystem
|
||||
public sealed class SharedLightReplacerSystem : EntitySystem // There is no Client and Server System anymore, this has been greatly overhauled in Delta-V.
|
||||
{
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedPoweredLightSystem _poweredLight = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
||||
|
||||
private EntityQuery<LightBulbComponent> _lightBulbQuery;
|
||||
private EntityQuery<MetaDataComponent> _metaDataQuery;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<LightReplacerComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<LightReplacerComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<LightReplacerComponent, ExaminedEvent>(OnExamined);
|
||||
SubscribeLocalEvent<LightReplacerComponent, UseInHandEvent>(OnUse);
|
||||
SubscribeLocalEvent<LightReplacerComponent, InteractUsingEvent>(HandleInteract);
|
||||
SubscribeLocalEvent<LightReplacerComponent, AfterInteractEvent>(HandleAfterInteract);
|
||||
SubscribeLocalEvent<LightReplacerComponent, EjectLightTypeMessage>(OnEjectMessage);
|
||||
SubscribeLocalEvent<LightReplacerComponent, SwitchLightTypeMessage>(OnSwitchMessage);
|
||||
|
||||
_lightBulbQuery = GetEntityQuery<LightBulbComponent>();
|
||||
_metaDataQuery = GetEntityQuery<MetaDataComponent>();
|
||||
}
|
||||
|
||||
private void OnInit(Entity<LightReplacerComponent> replacer, ref ComponentInit args)
|
||||
{
|
||||
// This needs to be handled on CompInit because otherwise, it's empty on the client.
|
||||
replacer.Comp.InsertedBulbs = _container.EnsureContainer<Container>(replacer, "light_replacer_storage");
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<LightReplacerComponent> replacer, ref MapInitEvent args)
|
||||
{
|
||||
var xform = Transform(replacer);
|
||||
foreach (var spawn in EntitySpawnCollection.GetSpawns(replacer.Comp.Contents))
|
||||
{
|
||||
var light = Spawn(spawn, xform.Coordinates);
|
||||
TryInsertBulb(replacer.AsNullable(), light);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnExamined(Entity<LightReplacerComponent> replacer, ref ExaminedEvent args)
|
||||
{
|
||||
using (args.PushGroup(nameof(LightReplacerComponent)))
|
||||
{
|
||||
if (!replacer.Comp.InsertedBulbs.ContainedEntities.Any())
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("comp-light-replacer-no-lights"));
|
||||
return;
|
||||
}
|
||||
|
||||
args.PushMarkup(Loc.GetString("comp-light-replacer-has-lights"));
|
||||
var groups = new Dictionary<string, int>();
|
||||
foreach (var bulb in replacer.Comp.InsertedBulbs.ContainedEntities)
|
||||
{
|
||||
var metaData = _metaDataQuery.GetComponent(bulb);
|
||||
groups[metaData.EntityName] = groups.GetValueOrDefault(metaData.EntityName) + 1;
|
||||
}
|
||||
|
||||
foreach (var (name, amount) in groups)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("comp-light-replacer-light-listing-dv", ("amount", amount), ("light-name", name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUse(Entity<LightReplacerComponent> replacer, ref UseInHandEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
args.ApplyDelay = false;
|
||||
|
||||
if (!replacer.Comp.InsertedBulbs.ContainedEntities.Any())
|
||||
{
|
||||
_popup.PopupClient(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);
|
||||
}
|
||||
|
||||
private void HandleAfterInteract(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);
|
||||
// add new bulb to light replacer container?
|
||||
else if (_lightBulbQuery.TryComp(targetUid, out var bulb))
|
||||
eventArgs.Handled = TryInsertBulb(replacer.AsNullable(), (targetUid, bulb), eventArgs.User, true);
|
||||
}
|
||||
|
||||
private void HandleInteract(Entity<LightReplacerComponent> replacer, ref InteractUsingEvent eventArgs)
|
||||
{
|
||||
if (eventArgs.Handled)
|
||||
return;
|
||||
|
||||
var usedUid = eventArgs.Used;
|
||||
|
||||
// want to insert a new light bulb?
|
||||
if (_lightBulbQuery.TryComp(usedUid, out var bulb))
|
||||
eventArgs.Handled = TryInsertBulb(replacer.AsNullable(), (usedUid, bulb), eventArgs.User, true);
|
||||
// add bulbs from storage?
|
||||
else if (TryComp<StorageComponent>(usedUid, out var storage))
|
||||
eventArgs.Handled = TryInsertBulbsFromStorage(replacer.AsNullable(), (usedUid, storage), eventArgs.User);
|
||||
}
|
||||
|
||||
private void OnEjectMessage(Entity<LightReplacerComponent> replacer, ref EjectLightTypeMessage args)
|
||||
{
|
||||
HashSet<EntityUid> lightsToEject = [];
|
||||
foreach (var light in replacer.Comp.InsertedBulbs.ContainedEntities)
|
||||
{
|
||||
if (_metaDataQuery.TryComp(light, out var metaData) && metaData.EntityName == args.LightName)
|
||||
lightsToEject.Add(light);
|
||||
}
|
||||
|
||||
foreach (var light in lightsToEject)
|
||||
{
|
||||
_container.Remove(light, replacer.Comp.InsertedBulbs);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSwitchMessage(Entity<LightReplacerComponent> replacer, ref SwitchLightTypeMessage args)
|
||||
{
|
||||
if (args.LightType == LightBulbType.Tube)
|
||||
replacer.Comp.ActiveLightTube = args.LightName;
|
||||
else
|
||||
replacer.Comp.ActiveLightBulb = args.LightName;
|
||||
Dirty(replacer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to replace a light bulb in <paramref name="fixture"/>
|
||||
/// 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="fixture">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?> fixture, EntityUid? userUid = null)
|
||||
{
|
||||
if (!Resolve(replacer, ref replacer.Comp)
|
||||
|| !Resolve(fixture, ref fixture.Comp))
|
||||
return false;
|
||||
|
||||
var activeType = fixture.Comp.BulbType == LightBulbType.Tube
|
||||
? replacer.Comp.ActiveLightTube
|
||||
: replacer.Comp.ActiveLightBulb;
|
||||
|
||||
// check if light bulb is broken or missing
|
||||
var fixtureBulbUid = _poweredLight.GetBulb(fixture, fixture.Comp);
|
||||
if (fixtureBulbUid != null)
|
||||
{
|
||||
if (!_lightBulbQuery.TryComp(fixtureBulbUid.Value, out var fixtureBulb))
|
||||
return false;
|
||||
|
||||
if (fixtureBulb.State == LightBulbState.Normal
|
||||
&& _metaDataQuery.TryComp(fixtureBulbUid, out var metaData)
|
||||
&& metaData.EntityName == activeType)
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString("comp-light-replacer-same-light", ("light-name", fixtureBulbUid)), fixture, userUid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EntityUid? bulb = null;
|
||||
foreach (var insertedBulb in replacer.Comp.InsertedBulbs.ContainedEntities)
|
||||
{
|
||||
if (!_metaDataQuery.TryComp(insertedBulb, out var metaData) || metaData.EntityName != activeType)
|
||||
continue;
|
||||
|
||||
bulb = insertedBulb;
|
||||
break;
|
||||
}
|
||||
|
||||
// found bulb in inserted storage
|
||||
if (bulb.HasValue)
|
||||
{
|
||||
// try to remove it
|
||||
var hasRemoved = _container.Remove(bulb.Value, replacer.Comp.InsertedBulbs);
|
||||
if (!hasRemoved)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (userUid == null)
|
||||
return false;
|
||||
|
||||
var msg = Loc.GetString("comp-light-replacer-missing-light-dv",
|
||||
("light-name", activeType),
|
||||
("light-replacer", replacer));
|
||||
_popup.PopupClient(msg, replacer, userUid.Value);
|
||||
return false;
|
||||
}
|
||||
|
||||
// insert it into fixture
|
||||
var wasReplaced = _poweredLight.ReplaceBulb(fixture, bulb.Value, fixture.Comp);
|
||||
if (wasReplaced)
|
||||
{
|
||||
_audio.PlayPredicted(replacer.Comp.Sound, replacer, userUid);
|
||||
}
|
||||
|
||||
return wasReplaced;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to insert a new bulb inside light replacer
|
||||
/// </summary>
|
||||
/// <param name="replacer">The light replacer to insert a light into.</param>
|
||||
/// <param name="bulb">The light to insert into the replacer.</param>
|
||||
/// <param name="userUid">The user who is inserting the light.</param>
|
||||
/// <param name="showPopup">Whether to show a popup.</param>
|
||||
/// <returns>True if successfully inserted light, false otherwise</returns>
|
||||
public bool TryInsertBulb(Entity<LightReplacerComponent?> replacer, Entity<LightBulbComponent?> bulb, EntityUid? userUid = null, bool showPopup = false)
|
||||
{
|
||||
if (!Resolve(replacer, ref replacer.Comp)
|
||||
|| !Resolve(bulb, ref bulb.Comp))
|
||||
return false;
|
||||
|
||||
// only normal (non-broken) bulbs can be inserted inside light replacer
|
||||
if (bulb.Comp.State != LightBulbState.Normal)
|
||||
{
|
||||
if (!showPopup || userUid == null)
|
||||
return false;
|
||||
|
||||
var error = Loc.GetString("comp-light-replacer-insert-broken-light");
|
||||
_popup.PopupClient(error, replacer, userUid.Value);
|
||||
return false;
|
||||
}
|
||||
// try insert light and show message
|
||||
var hasInsert = _container.Insert(bulb.Owner, replacer.Comp.InsertedBulbs);
|
||||
|
||||
if (!hasInsert || !showPopup || userUid == null)
|
||||
return hasInsert;
|
||||
|
||||
var message = Loc.GetString("comp-light-replacer-insert-light",
|
||||
("light-replacer", replacer), ("bulb", bulb));
|
||||
_popup.PopupClient(message, replacer, userUid.Value);
|
||||
|
||||
return hasInsert;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to insert all light bulbs from storage (for example light tubes box)
|
||||
/// </summary>
|
||||
/// <param name="replacer">The light replacer to insert bulbs into.</param>
|
||||
/// <param name="storage">The storage whose contents should be inserted.</param>
|
||||
/// <param name="userUid">The user who inserts the contents.</param>
|
||||
/// <returns>
|
||||
/// Returns true if storage contained at least one light bulb
|
||||
/// which was successfully inserted inside light replacer
|
||||
/// </returns>
|
||||
public bool TryInsertBulbsFromStorage(Entity<LightReplacerComponent?> replacer, Entity<StorageComponent?> storage, EntityUid? userUid = null)
|
||||
{
|
||||
if (!Resolve(replacer, ref replacer.Comp)
|
||||
|| !Resolve(storage, ref storage.Comp))
|
||||
return false;
|
||||
|
||||
var insertedBulbs = 0;
|
||||
var storedEntities = storage.Comp.Container.ContainedEntities.ToArray();
|
||||
|
||||
foreach (var ent in storedEntities)
|
||||
{
|
||||
if (TryInsertBulb(replacer, ent, userUid))
|
||||
{
|
||||
insertedBulbs++;
|
||||
}
|
||||
}
|
||||
|
||||
// show some message if success
|
||||
if (insertedBulbs > 0 && userUid != null)
|
||||
{
|
||||
var msg = Loc.GetString("comp-light-replacer-refill-from-storage", ("light-replacer", replacer));
|
||||
_popup.PopupClient(msg, replacer, userUid.Value);
|
||||
}
|
||||
|
||||
return insertedBulbs > 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum LightReplacerUiKey : byte
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
using Content.Shared.Light.Components;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._DV.Light.Events;
|
||||
|
||||
/// <summary>
|
||||
/// This message is sent from the client when the player wants to switch the active light bulb.
|
||||
/// </summary>
|
||||
/// <param name="light">A mix of the light name and the light bulb type.</param>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class SwitchLightTypeMessage((string, LightBulbType) light) : BoundUserInterfaceMessage
|
||||
{
|
||||
public string LightName = light.Item1;
|
||||
public LightBulbType LightType = light.Item2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This message is sent from the client when the player wants to eject all lights of a specific type.
|
||||
/// </summary>
|
||||
/// <param name="lightName">The name of the lights to be ejected.</param>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class EjectLightTypeMessage(string lightName) : BoundUserInterfaceMessage
|
||||
{
|
||||
public string LightName = lightName;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
### Interaction Messages
|
||||
|
||||
# Shown when player tries to replace light, but there is no lights left
|
||||
comp-light-replacer-missing-light-dv = No {MAKEPLURAL($light-name)} left in {THE($light-replacer)}.
|
||||
|
||||
# Shown when a player attempts to replace a light with the same color & type as the active light.
|
||||
comp-light-replacer-same-light = This fixture already holds {INDEFINITE($light-name)} {$light-name}!
|
||||
|
||||
# Radial Menu messages
|
||||
comp-light-replacer-eject-specified-lights = Eject all {MAKEPLURAL($light-name)}.
|
||||
comp-light-replacer-select-lights = Select {MAKEPLURAL($light-name)}.
|
||||
comp-light-replacer-open-empty = {CAPITALIZE(THE($light-replacer))} is completely empty!
|
||||
|
||||
# Label
|
||||
comp-light-replacer-label = Tube: {$tube}
|
||||
Bulb: {$bulb}
|
||||
|
||||
### Examine
|
||||
|
||||
comp-light-replacer-light-listing-dv = {$amount ->
|
||||
[one] [color=yellow]{$amount}[/color] [color=gray]{$light-name}[/color]
|
||||
*[other] [color=yellow]{$amount}[/color] [color=gray]{MAKEPLURAL($light-name)}[/color]
|
||||
}
|
||||
|
|
@ -418,7 +418,7 @@
|
|||
- Whistle
|
||||
- BalloonPopper
|
||||
- type: ItemMapper # DeltaV - Custom sprite and item mapper
|
||||
sprite: _DV/Clothing/Belt/belt_overlay.rsi
|
||||
sprite: _DV/Clothing/Belt/belt_overlay.rsi
|
||||
mapLayers:
|
||||
baton:
|
||||
whitelist:
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
light_replacer_storage: !type:Container
|
||||
# Begin DeltaV Additions - Added Radial Menu to Light Replacers
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.LightReplacerUiKey.Key:
|
||||
type: LightReplacerMenuBoundUserInterface
|
||||
# Begin DeltaV Additions - Added Radial Menu to Light Replacers
|
||||
|
||||
- type: entity
|
||||
parent: LightReplacer
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 329 B |
Binary file not shown.
|
After Width: | Height: | Size: 308 B |
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Eject sprites made by SirWarock on Github using sprites from cev-eris at https://github.com/discordia-space/CEV-Eris/commit/740ff31a81313086cf16761f3677cf1e2ab46c93",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "eject-tubes"
|
||||
},
|
||||
{
|
||||
"name": "eject-bulbs"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue