mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 21:48:58 +03:00
These are all essentially just random systems that scaled directly with player count (or were on my list of the top 50 anyways). So just a couple systems that had very inefficient enumerators being swapped out with significantly more efficient ones, plus a few swaps from O(n) to O(m) m << n. A big one was DrainSystem, which was querrying all possible entities, rather than doing so from the "set of all static objects", which is significantly smaller. Puddles are always static objects, so it doesn't make sense to have the drains check for anything other than static. We can also use DirtyField to save on performance costs of Dirty(uid, component) in cases where the Dirty is only networking a single component field. no CL this isn't player facing.
207 lines
7.6 KiB
C#
207 lines
7.6 KiB
C#
using Content.Server.Light.Components;
|
|
using Content.Shared.Clothing.Components;
|
|
using Content.Shared.Clothing.EntitySystems;
|
|
using Content.Shared.Interaction.Events;
|
|
using Content.Shared.Item;
|
|
using Content.Shared.Light.Components;
|
|
using Content.Shared.Tag;
|
|
using Content.Shared.Temperature;
|
|
using Content.Shared.Verbs;
|
|
using JetBrains.Annotations;
|
|
using Robust.Server.GameObjects;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Server.Light.EntitySystems
|
|
{
|
|
[UsedImplicitly]
|
|
public sealed class ExpendableLightSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedItemSystem _item = default!;
|
|
[Dependency] private readonly ClothingSystem _clothing = default!;
|
|
[Dependency] private readonly TagSystem _tagSystem = default!;
|
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
|
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<ExpendableLightComponent, ComponentInit>(OnExpLightInit);
|
|
SubscribeLocalEvent<ExpendableLightComponent, UseInHandEvent>(OnExpLightUse);
|
|
SubscribeLocalEvent<ExpendableLightComponent, GetVerbsEvent<ActivationVerb>>(AddIgniteVerb);
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
var query = EntityQueryEnumerator<ActiveExpendableLightComponent>();
|
|
while (query.MoveNext(out var uid, out var _))
|
|
{
|
|
if (!TryComp(uid, out ExpendableLightComponent? light))
|
|
{
|
|
RemCompDeferred<ActiveExpendableLightComponent>(uid);
|
|
continue;
|
|
}
|
|
|
|
UpdateLight((uid, light), frameTime);
|
|
}
|
|
}
|
|
|
|
private void UpdateLight(Entity<ExpendableLightComponent> ent, float frameTime)
|
|
{
|
|
var component = ent.Comp;
|
|
component.StateExpiryTime -= frameTime;
|
|
|
|
if (component.StateExpiryTime <= 0f)
|
|
{
|
|
switch (component.CurrentState)
|
|
{
|
|
case ExpendableLightState.Lit:
|
|
component.CurrentState = ExpendableLightState.Fading;
|
|
component.StateExpiryTime = component.FadeOutDuration;
|
|
|
|
UpdateVisualizer(ent);
|
|
|
|
break;
|
|
|
|
default:
|
|
case ExpendableLightState.Fading:
|
|
component.CurrentState = ExpendableLightState.Dead;
|
|
var meta = MetaData(ent);
|
|
_metaData.SetEntityName(ent, Loc.GetString(component.SpentName), meta);
|
|
_metaData.SetEntityDescription(ent, Loc.GetString(component.SpentDesc), meta);
|
|
|
|
_tagSystem.AddTag(ent, "Trash");
|
|
|
|
UpdateSounds(ent);
|
|
UpdateVisualizer(ent);
|
|
|
|
if (TryComp<ItemComponent>(ent, out var item))
|
|
{
|
|
_item.SetHeldPrefix(ent, "unlit", component: item);
|
|
}
|
|
|
|
RemCompDeferred<ActiveExpendableLightComponent>(ent);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enables the light if it is not active. Once active it cannot be turned off.
|
|
/// </summary>
|
|
public bool TryActivate(Entity<ExpendableLightComponent> ent)
|
|
{
|
|
var component = ent.Comp;
|
|
if (!component.Activated && component.CurrentState == ExpendableLightState.BrandNew)
|
|
{
|
|
if (TryComp<ItemComponent>(ent, out var item))
|
|
{
|
|
_item.SetHeldPrefix(ent, "lit", component: item);
|
|
}
|
|
|
|
var isHotEvent = new IsHotEvent() { IsHot = true };
|
|
RaiseLocalEvent(ent, isHotEvent);
|
|
|
|
component.CurrentState = ExpendableLightState.Lit;
|
|
component.StateExpiryTime = component.GlowDuration;
|
|
|
|
UpdateSounds(ent);
|
|
UpdateVisualizer(ent);
|
|
EnsureComp<ActiveExpendableLightComponent>(ent);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void UpdateVisualizer(Entity<ExpendableLightComponent> ent, AppearanceComponent? appearance = null)
|
|
{
|
|
var component = ent.Comp;
|
|
if (!Resolve(ent, ref appearance, false))
|
|
return;
|
|
|
|
_appearance.SetData(ent, ExpendableLightVisuals.State, component.CurrentState, appearance);
|
|
|
|
switch (component.CurrentState)
|
|
{
|
|
case ExpendableLightState.Lit:
|
|
_appearance.SetData(ent, ExpendableLightVisuals.Behavior, component.TurnOnBehaviourID, appearance);
|
|
break;
|
|
|
|
case ExpendableLightState.Fading:
|
|
_appearance.SetData(ent, ExpendableLightVisuals.Behavior, component.FadeOutBehaviourID, appearance);
|
|
break;
|
|
|
|
case ExpendableLightState.Dead:
|
|
_appearance.SetData(ent, ExpendableLightVisuals.Behavior, string.Empty, appearance);
|
|
var isHotEvent = new IsHotEvent() { IsHot = true };
|
|
RaiseLocalEvent(ent, isHotEvent);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void UpdateSounds(Entity<ExpendableLightComponent> ent)
|
|
{
|
|
var component = ent.Comp;
|
|
|
|
switch (component.CurrentState)
|
|
{
|
|
case ExpendableLightState.Lit:
|
|
_audio.PlayPvs(component.LitSound, ent);
|
|
break;
|
|
case ExpendableLightState.Fading:
|
|
break;
|
|
default:
|
|
_audio.PlayPvs(component.DieSound, ent);
|
|
break;
|
|
}
|
|
|
|
if (TryComp<ClothingComponent>(ent, out var clothing))
|
|
{
|
|
_clothing.SetEquippedPrefix(ent, component.Activated ? "Activated" : string.Empty, clothing);
|
|
}
|
|
}
|
|
|
|
private void OnExpLightInit(EntityUid uid, ExpendableLightComponent component, ComponentInit args)
|
|
{
|
|
if (TryComp<ItemComponent>(uid, out var item))
|
|
{
|
|
_item.SetHeldPrefix(uid, "unlit", component: item);
|
|
}
|
|
|
|
component.CurrentState = ExpendableLightState.BrandNew;
|
|
EntityManager.EnsureComponent<PointLightComponent>(uid);
|
|
}
|
|
|
|
private void OnExpLightUse(Entity<ExpendableLightComponent> ent, ref UseInHandEvent args)
|
|
{
|
|
if (args.Handled)
|
|
return;
|
|
|
|
if (TryActivate(ent))
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void AddIgniteVerb(Entity<ExpendableLightComponent> ent, ref GetVerbsEvent<ActivationVerb> args)
|
|
{
|
|
if (!args.CanAccess || !args.CanInteract)
|
|
return;
|
|
|
|
if (ent.Comp.CurrentState != ExpendableLightState.BrandNew)
|
|
return;
|
|
|
|
// Ignite the flare or make the glowstick glow.
|
|
// Also hot damn, those are some shitty glowsticks, we need to get a refund.
|
|
ActivationVerb verb = new()
|
|
{
|
|
Text = Loc.GetString("expendable-light-start-verb"),
|
|
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/light.svg.192dpi.png")),
|
|
Act = () => TryActivate(ent)
|
|
};
|
|
args.Verbs.Add(verb);
|
|
}
|
|
}
|
|
}
|