Light replacer cleanup + examine (#16066)

This commit is contained in:
Nemanja
2023-05-03 22:09:35 -04:00
committed by GitHub
parent de5d89dad5
commit e47fb42301
5 changed files with 271 additions and 245 deletions

View File

@@ -1,45 +1,35 @@
using Content.Shared.Light.Component; using Content.Server.Light.EntitySystems;
using Content.Shared.Storage;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Light.Components namespace Content.Server.Light.Components;
/// <summary>
/// Device that allows user to quikly change bulbs in <see cref="PoweredLightComponent"/>
/// Can be reloaded by new light tubes or light bulbs
/// </summary>
[RegisterComponent, Access(typeof(LightReplacerSystem))]
public sealed class LightReplacerComponent : Component
{ {
/// <summary>
/// Device that allows user to quikly change bulbs in <see cref="PoweredLightComponent"/>
/// Can be reloaded by new light tubes or light bulbs
/// </summary>
[RegisterComponent]
public sealed class LightReplacerComponent : Component
{
[DataField("sound")] [DataField("sound")]
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Weapons/click.ogg"); public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Weapons/click.ogg")
{
/// <summary> Params = new()
/// Bulbs that were inside light replacer when it spawned {
/// </summary> Volume = -4f
[DataField("contents")] }
public List<LightReplacerEntity> Contents = new(); };
/// <summary> /// <summary>
/// Bulbs that were inserted inside light replacer /// Bulbs that were inserted inside light replacer
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
public IContainer InsertedBulbs = default!; public Container InsertedBulbs = default!;
[Serializable] /// <summary>
[DataDefinition] /// The default starting bulbs
public sealed class LightReplacerEntity /// </summary>
{ [DataField("contents")]
[DataField("name", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] public List<EntitySpawnEntry> Contents = new();
public string PrototypeName = default!;
[DataField("amount")]
public int Amount;
[DataField("type")]
public LightBulbType Type;
}
}
} }

View File

@@ -1,34 +1,70 @@
using System.Linq; using System.Linq;
using Content.Server.Light.Components; using Content.Server.Light.Components;
using Content.Server.Storage.Components; using Content.Server.Storage.Components;
using Content.Shared.Examine;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Light.Component; using Content.Shared.Light.Component;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Storage;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Player;
namespace Content.Server.Light.EntitySystems namespace Content.Server.Light.EntitySystems;
[UsedImplicitly]
public sealed class LightReplacerSystem : EntitySystem
{ {
[UsedImplicitly]
public sealed class LightReplacerSystem : EntitySystem
{
[Dependency] private readonly PoweredLightSystem _poweredLight = default!; [Dependency] private readonly PoweredLightSystem _poweredLight = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<LightReplacerComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<LightReplacerComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<LightReplacerComponent, ComponentInit>(OnInit); SubscribeLocalEvent<LightReplacerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<LightReplacerComponent, InteractUsingEvent>(HandleInteract); SubscribeLocalEvent<LightReplacerComponent, InteractUsingEvent>(HandleInteract);
SubscribeLocalEvent<LightReplacerComponent, AfterInteractEvent>(HandleAfterInteract); SubscribeLocalEvent<LightReplacerComponent, AfterInteractEvent>(HandleAfterInteract);
} }
private void OnExamined(EntityUid uid, LightReplacerComponent component, ExaminedEvent args)
{
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) private void OnInit(EntityUid uid, LightReplacerComponent replacer, ComponentInit args)
{ {
replacer.InsertedBulbs = ContainerHelpers.EnsureContainer<Container>(replacer.Owner, "light_replacer_storage"); replacer.InsertedBulbs = _container.EnsureContainer<Container>(uid, "light_replacer_storage");
} }
private void HandleAfterInteract(EntityUid uid, LightReplacerComponent component, AfterInteractEvent eventArgs) private void HandleAfterInteract(EntityUid uid, LightReplacerComponent component, AfterInteractEvent eventArgs)
@@ -37,7 +73,8 @@ namespace Content.Server.Light.EntitySystems
return; return;
// standard interaction checks // standard interaction checks
if (!eventArgs.CanReach) return; if (!eventArgs.CanReach)
return;
// behaviour will depends on target type // behaviour will depends on target type
if (eventArgs.Target != null) if (eventArgs.Target != null)
@@ -45,10 +82,10 @@ namespace Content.Server.Light.EntitySystems
var targetUid = (EntityUid) eventArgs.Target; var targetUid = (EntityUid) eventArgs.Target;
// replace broken light in fixture? // replace broken light in fixture?
if (EntityManager.TryGetComponent(targetUid, out PoweredLightComponent? fixture)) if (TryComp<PoweredLightComponent>(targetUid, out var fixture))
eventArgs.Handled = TryReplaceBulb(uid, targetUid, eventArgs.User, component, fixture); eventArgs.Handled = TryReplaceBulb(uid, targetUid, eventArgs.User, component, fixture);
// add new bulb to light replacer container? // add new bulb to light replacer container?
else if (EntityManager.TryGetComponent(targetUid, out LightBulbComponent? bulb)) else if (TryComp<LightBulbComponent>(targetUid, out var bulb))
eventArgs.Handled = TryInsertBulb(uid, targetUid, eventArgs.User, true, component, bulb); eventArgs.Handled = TryInsertBulb(uid, targetUid, eventArgs.User, true, component, bulb);
} }
} }
@@ -61,10 +98,10 @@ namespace Content.Server.Light.EntitySystems
var usedUid = eventArgs.Used; var usedUid = eventArgs.Used;
// want to insert a new light bulb? // want to insert a new light bulb?
if (EntityManager.TryGetComponent(usedUid, out LightBulbComponent? bulb)) if (TryComp<LightBulbComponent>(usedUid, out var bulb))
eventArgs.Handled = TryInsertBulb(uid, usedUid, eventArgs.User, true, component, bulb); eventArgs.Handled = TryInsertBulb(uid, usedUid, eventArgs.User, true, component, bulb);
// add bulbs from storage? // add bulbs from storage?
else if (EntityManager.TryGetComponent(usedUid, out ServerStorageComponent? storage)) else if (TryComp<ServerStorageComponent>(usedUid, out var storage))
eventArgs.Handled = TryInsertBulbsFromStorage(uid, usedUid, eventArgs.User, component, storage); eventArgs.Handled = TryInsertBulbsFromStorage(uid, usedUid, eventArgs.User, component, storage);
} }
@@ -82,10 +119,10 @@ namespace Content.Server.Light.EntitySystems
return false; return false;
// check if light bulb is broken or missing // check if light bulb is broken or missing
var fixtureBulbUid = _poweredLight.GetBulb(fixture.Owner, fixture); var fixtureBulbUid = _poweredLight.GetBulb(fixtureUid, fixture);
if (fixtureBulbUid != null) if (fixtureBulbUid != null)
{ {
if (!EntityManager.TryGetComponent(fixtureBulbUid.Value, out LightBulbComponent? fixtureBulb)) if (!TryComp<LightBulbComponent>(fixtureBulbUid.Value, out var fixtureBulb))
return false; return false;
if (fixtureBulb.State == LightBulbState.Normal) if (fixtureBulb.State == LightBulbState.Normal)
return false; return false;
@@ -93,7 +130,7 @@ namespace Content.Server.Light.EntitySystems
// try get first inserted bulb of the same type as targeted light fixtutre // try get first inserted bulb of the same type as targeted light fixtutre
var bulb = replacer.InsertedBulbs.ContainedEntities.FirstOrDefault( var bulb = replacer.InsertedBulbs.ContainedEntities.FirstOrDefault(
(e) => EntityManager.GetComponentOrNull<LightBulbComponent>(e)?.Type == fixture.BulbType); e => CompOrNull<LightBulbComponent>(e)?.Type == fixture.BulbType);
// found bulb in inserted storage // found bulb in inserted storage
if (bulb.Valid) // FirstOrDefault can return default/invalid uid. if (bulb.Valid) // FirstOrDefault can return default/invalid uid.
@@ -103,39 +140,24 @@ namespace Content.Server.Light.EntitySystems
if (!hasRemoved) if (!hasRemoved)
return false; return false;
} }
// try to create new instance of bulb from LightReplacerEntity
else
{
var bulbEnt = replacer.Contents.FirstOrDefault((e) => e.Type == fixture.BulbType && e.Amount > 0);
// found right bulb, let's spawn it
if (bulbEnt != null)
{
bulb = EntityManager.SpawnEntity(bulbEnt.PrototypeName, EntityManager.GetComponent<TransformComponent>(replacer.Owner).Coordinates);
bulbEnt.Amount--;
}
// not found any light bulbs
else else
{ {
if (userUid != null) if (userUid != null)
{ {
var msg = Loc.GetString("comp-light-replacer-missing-light", var msg = Loc.GetString("comp-light-replacer-missing-light",
("light-replacer", replacer.Owner)); ("light-replacer", replacerUid));
_popupSystem.PopupEntity(msg, replacerUid, userUid.Value); _popupSystem.PopupEntity(msg, replacerUid, userUid.Value);
} }
return false; return false;
} }
}
// insert it into fixture // insert it into fixture
var wasReplaced = _poweredLight.ReplaceBulb(fixtureUid, bulb, fixture); var wasReplaced = _poweredLight.ReplaceBulb(fixtureUid, bulb, fixture);
if (wasReplaced) if (wasReplaced)
{ {
SoundSystem.Play(replacer.Sound.GetSound(), _audio.PlayPvs(replacer.Sound, replacerUid);
Filter.Pvs(replacerUid), replacerUid, AudioParams.Default.WithVolume(-4f));
} }
return wasReplaced; return wasReplaced;
} }
@@ -164,11 +186,11 @@ namespace Content.Server.Light.EntitySystems
} }
// try insert light and show message // try insert light and show message
var hasInsert = replacer.InsertedBulbs.Insert(bulb.Owner); var hasInsert = replacer.InsertedBulbs.Insert(bulbUid);
if (hasInsert && showTooltip && userUid != null) if (hasInsert && showTooltip && userUid != null)
{ {
var msg = Loc.GetString("comp-light-replacer-insert-light", var msg = Loc.GetString("comp-light-replacer-insert-light",
("light-replacer", replacer.Owner), ("bulb", bulb.Owner)); ("light-replacer", replacerUid), ("bulb", bulbUid));
_popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium); _popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium);
} }
@@ -197,21 +219,18 @@ namespace Content.Server.Light.EntitySystems
var storagedEnts = storage.StoredEntities.ToArray(); var storagedEnts = storage.StoredEntities.ToArray();
foreach (var ent in storagedEnts) foreach (var ent in storagedEnts)
{ {
if (EntityManager.TryGetComponent(ent, out LightBulbComponent? bulb)) if (TryComp<LightBulbComponent>(ent, out var bulb) &&
{ TryInsertBulb(replacerUid, ent, userUid, false, replacer, bulb))
if (TryInsertBulb(replacerUid, ent, userUid, false, replacer, bulb))
insertedBulbs++; insertedBulbs++;
} }
}
// show some message if success // show some message if success
if (insertedBulbs > 0 && userUid != null) if (insertedBulbs > 0 && userUid != null)
{ {
var msg = Loc.GetString("comp-light-replacer-refill-from-storage", ("light-replacer", storage.Owner)); var msg = Loc.GetString("comp-light-replacer-refill-from-storage", ("light-replacer", storageUid));
_popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium); _popupSystem.PopupEntity(msg, replacerUid, userUid.Value, PopupType.Medium);
} }
return insertedBulbs > 0; return insertedBulbs > 0;
} }
}
} }

View File

@@ -1,14 +1,23 @@
### Interaction Messages ### Interaction Messages
# Shown when player tries to replace light, but there is no lighs left # Shown when player tries to replace light, but there is no lights left
comp-light-replacer-missing-light = No lights left in {$light-replacer}. comp-light-replacer-missing-light = No lights left in {THE($light-replacer)}.
# Shown when player inserts light bulb inside light replacer # Shown when player inserts light bulb inside light replacer
comp-light-replacer-insert-light = You insert {$bulb} into {$light-replacer}. comp-light-replacer-insert-light = You insert {$bulb} into {THE($light-replacer)}.
# Shown when player tries to insert in light replacer brolen light bulb # Shown when player tries to insert in light replacer brolen light bulb
comp-light-replacer-insert-broken-light = You can't insert broken lights! comp-light-replacer-insert-broken-light = You can't insert broken lights!
# Shown when player refill light from light box # Shown when player refill light from light box
comp-light-replacer-refill-from-storage = You refill {$light-replacer}. comp-light-replacer-refill-from-storage = You refill {THE($light-replacer)}.
### Examine
comp-light-replacer-no-lights = It's empty.
comp-light-replacer-has-lights = It contains the following:
comp-light-replacer-light-listing = {$amount ->
[one] [color=yellow]{$amount}[/color] [color=gray]{$name}[/color]
*[other] [color=yellow]{$amount}[/color] [color=gray]{$name}s[/color]
}

View File

@@ -11,12 +11,10 @@
sprite: Objects/Specific/Janitorial/light_replacer.rsi sprite: Objects/Specific/Janitorial/light_replacer.rsi
- type: LightReplacer - type: LightReplacer
contents: contents:
- name: LightTube - id: LightTube
amount: 8 amount: 8
type: Tube - id: LightBulb
- name: LightBulb
amount: 5 amount: 5
type: Bulb
- type: Tag - type: Tag
tags: tags:
- DroneUsable - DroneUsable
@@ -25,3 +23,13 @@
- type: ContainerContainer - type: ContainerContainer
containers: containers:
light_replacer_storage: !type:Container light_replacer_storage: !type:Container
- type: entity
parent: LightReplacer
id: LightReplacerEmpty
suffix: Empty
components:
- type: LightReplacer
contents:
- id: LightTube
amount: 0

View File

@@ -50,11 +50,11 @@
- type: latheRecipe - type: latheRecipe
id: LightReplacer id: LightReplacer
result: LightReplacer result: LightReplacerEmpty
completetime: 2.4 completetime: 2.4
materials: materials:
Steel: 100 Steel: 100
Glass: 1000 Glass: 500
- type: latheRecipe - type: latheRecipe
id: AdvMopItem id: AdvMopItem