Delta-v/Content.Server/_DV/Addictions/AddictionSystem.cs

109 lines
3.5 KiB
C#

using Content.Shared.Dataset;
using Content.Shared._DV.Addictions;
using Content.Shared.Popups;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Server._DV.Addictions;
public sealed class AddictionSystem : SharedAddictionSystem
{
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IGameTiming _timing = default!;
// Define the numbers, we're not making another DeepFryerSystem.cs
// Minimum time between popups
private const int MinEffectInterval = 10;
// Maximum time between popups
private const int MaxEffectInterval = 41;
// The time to add after the last metabolism cycle
private const int SuppressionDuration = 10;
private EntityQuery<AddictedComponent> _addicted;
private readonly ProtoId<LocalizedDatasetPrototype> _datasetId = "AddictionEffects";
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AddictedComponent, ComponentStartup>(OnInit);
_addicted = GetEntityQuery<AddictedComponent>();
}
protected override void UpdateAddictionSuppression(Entity<AddictedComponent> ent, float duration)
{
var curTime = _timing.CurTime;
var newEndTime = curTime + TimeSpan.FromSeconds(duration);
// Only update if this would extend the suppression
if (newEndTime <= ent.Comp.SuppressionEndTime)
return;
ent.Comp.SuppressionEndTime = newEndTime;
UpdateSuppressed(ent.Comp);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var curTime = _timing.CurTime;
var query = EntityQueryEnumerator<AddictedComponent>();
while (query.MoveNext(out var uid, out var component))
{
// If it's suppressed, check if it's still supposed to be
if (component.Suppressed)
{
UpdateSuppressed(component);
continue;
}
if (curTime < component.NextEffectTime)
continue;
DoAddictionEffect(uid);
component.NextEffectTime = curTime + TimeSpan.FromSeconds(_random.Next(MinEffectInterval, MaxEffectInterval));
}
}
// Make sure we don't get a popup on the first update
private void OnInit(Entity<AddictedComponent> ent, ref ComponentStartup args)
{
var curTime = _timing.CurTime;
ent.Comp.NextEffectTime = curTime + TimeSpan.FromSeconds(_random.Next(MinEffectInterval, MaxEffectInterval));
}
private void UpdateSuppressed(AddictedComponent component)
{
component.Suppressed = (_timing.CurTime < component.SuppressionEndTime);
}
private string GetRandomPopup()
{
return Loc.GetString(_random.Pick(_prototypeManager.Index<LocalizedDatasetPrototype>(_datasetId).Values));
}
private void DoAddictionEffect(EntityUid uid)
{
_popup.PopupEntity(GetRandomPopup(), uid, uid);
}
// Called each time a reagent with the Addicted effect gets metabolized
protected override void UpdateTime(EntityUid uid)
{
if (!_addicted.TryComp(uid, out var component))
return;
component.LastMetabolismTime = _timing.CurTime;
component.SuppressionEndTime = _timing.CurTime + TimeSpan.FromSeconds(SuppressionDuration);
UpdateSuppressed(component);
}
}