Refactored AdvertiseComponent (#26598)
* Made it better * ok * alright --------- Co-authored-by: wrexbe <wrexbe@protonmail.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
using Content.Server.Advertise.EntitySystems;
|
using Content.Server.Advertise.EntitySystems;
|
||||||
using Content.Shared.Advertise;
|
using Content.Shared.Advertise;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
|
|
||||||
namespace Content.Server.Advertise.Components;
|
namespace Content.Server.Advertise.Components;
|
||||||
|
|
||||||
@@ -37,9 +36,4 @@ public sealed partial class AdvertiseComponent : Component
|
|||||||
[DataField]
|
[DataField]
|
||||||
public TimeSpan NextAdvertisementTime { get; set; } = TimeSpan.Zero;
|
public TimeSpan NextAdvertisementTime { get; set; } = TimeSpan.Zero;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the entity will say advertisements or not.
|
|
||||||
/// </summary>
|
|
||||||
[DataField]
|
|
||||||
public bool Enabled { get; set; } = true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,112 +28,78 @@ public sealed class AdvertiseSystem : EntitySystem
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<AdvertiseComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<AdvertiseComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<AdvertiseComponent, PowerChangedEvent>(OnPowerChanged);
|
|
||||||
|
|
||||||
SubscribeLocalEvent<ApcPowerReceiverComponent, AdvertiseEnableChangeAttemptEvent>(OnPowerReceiverEnableChangeAttempt);
|
SubscribeLocalEvent<ApcPowerReceiverComponent, AttemptAdvertiseEvent>(OnPowerReceiverAttemptAdvertiseEvent);
|
||||||
SubscribeLocalEvent<VendingMachineComponent, AdvertiseEnableChangeAttemptEvent>(OnVendingEnableChangeAttempt);
|
SubscribeLocalEvent<VendingMachineComponent, AttemptAdvertiseEvent>(OnVendingAttemptAdvertiseEvent);
|
||||||
|
|
||||||
// Force it to check on the next update.
|
|
||||||
_nextCheckTime = TimeSpan.MinValue;
|
_nextCheckTime = TimeSpan.MinValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapInit(EntityUid uid, AdvertiseComponent advertise, MapInitEvent args)
|
private void OnMapInit(EntityUid uid, AdvertiseComponent advert, MapInitEvent args)
|
||||||
{
|
{
|
||||||
RefreshTimer(uid, advertise);
|
RandomizeNextAdvertTime(advert);
|
||||||
|
_nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPowerChanged(EntityUid uid, AdvertiseComponent advertise, ref PowerChangedEvent args)
|
private void RandomizeNextAdvertTime(AdvertiseComponent advert)
|
||||||
{
|
{
|
||||||
SetEnabled(uid, args.Powered, advertise);
|
var minDuration = Math.Max(1, advert.MinimumWait);
|
||||||
}
|
var maxDuration = Math.Max(minDuration, advert.MaximumWait);
|
||||||
|
|
||||||
public void RefreshTimer(EntityUid uid, AdvertiseComponent? advertise = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref advertise))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!advertise.Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var minDuration = Math.Max(1, advertise.MinimumWait);
|
|
||||||
var maxDuration = Math.Max(minDuration, advertise.MaximumWait);
|
|
||||||
var waitDuration = TimeSpan.FromSeconds(_random.Next(minDuration, maxDuration));
|
var waitDuration = TimeSpan.FromSeconds(_random.Next(minDuration, maxDuration));
|
||||||
var nextTime = _gameTiming.CurTime + waitDuration;
|
|
||||||
|
|
||||||
advertise.NextAdvertisementTime = nextTime;
|
advert.NextAdvertisementTime = _gameTiming.CurTime + waitDuration;
|
||||||
|
|
||||||
_nextCheckTime = MathHelper.Min(nextTime, _nextCheckTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SayAdvertisement(EntityUid uid, AdvertiseComponent? advertise = null)
|
public void SayAdvertisement(EntityUid uid, AdvertiseComponent? advert = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref advertise))
|
if (!Resolve(uid, ref advert))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_prototypeManager.TryIndex(advertise.Pack, out var advertisements))
|
var attemptEvent = new AttemptAdvertiseEvent(uid);
|
||||||
_chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.Messages)), InGameICChatType.Speak, hideChat: true);
|
RaiseLocalEvent(uid, ref attemptEvent);
|
||||||
}
|
|
||||||
|
|
||||||
public void SetEnabled(EntityUid uid, bool enable, AdvertiseComponent? advertise = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref advertise))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (advertise.Enabled == enable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var attemptEvent = new AdvertiseEnableChangeAttemptEvent(enable);
|
|
||||||
RaiseLocalEvent(uid, attemptEvent);
|
|
||||||
|
|
||||||
if (attemptEvent.Cancelled)
|
if (attemptEvent.Cancelled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
advertise.Enabled = enable;
|
if (_prototypeManager.TryIndex(advert.Pack, out var advertisements))
|
||||||
RefreshTimer(uid, advertise);
|
_chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.Messages)), InGameICChatType.Speak, hideChat: true);
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnPowerReceiverEnableChangeAttempt(EntityUid uid, ApcPowerReceiverComponent component, AdvertiseEnableChangeAttemptEvent args)
|
|
||||||
{
|
|
||||||
if (args.Enabling && !component.Powered)
|
|
||||||
args.Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnVendingEnableChangeAttempt(EntityUid uid, VendingMachineComponent component, AdvertiseEnableChangeAttemptEvent args)
|
|
||||||
{
|
|
||||||
if (args.Enabling && component.Broken)
|
|
||||||
args.Cancel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
var curTime = _gameTiming.CurTime;
|
var currentGameTime = _gameTiming.CurTime;
|
||||||
if (_nextCheckTime > curTime)
|
if (_nextCheckTime > currentGameTime)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Note that as _nextCheckTime currently starts at TimeSpan.MinValue, so this has to SET the value, not just
|
// _nextCheckTime starts at TimeSpan.MinValue, so this has to SET the value, not just increment it.
|
||||||
// increment it.
|
_nextCheckTime = currentGameTime + _maximumNextCheckDuration;
|
||||||
_nextCheckTime = curTime + _maximumNextCheckDuration;
|
|
||||||
|
|
||||||
var query = EntityQueryEnumerator<AdvertiseComponent>();
|
var query = EntityQueryEnumerator<AdvertiseComponent>();
|
||||||
while (query.MoveNext(out var uid, out var advert))
|
while (query.MoveNext(out var uid, out var advert))
|
||||||
{
|
{
|
||||||
if (!advert.Enabled)
|
if (currentGameTime > advert.NextAdvertisementTime)
|
||||||
continue;
|
|
||||||
|
|
||||||
// If this isn't advertising yet
|
|
||||||
if (advert.NextAdvertisementTime > curTime)
|
|
||||||
{
|
{
|
||||||
_nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime);
|
SayAdvertisement(uid, advert);
|
||||||
continue;
|
// The timer is always refreshed when it expires, to prevent mass advertising (ex: all the vending machines have no power, and get it back at the same time).
|
||||||
|
RandomizeNextAdvertTime(advert);
|
||||||
}
|
}
|
||||||
|
_nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime);
|
||||||
SayAdvertisement(uid, advert);
|
|
||||||
RefreshTimer(uid, advert);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void OnPowerReceiverAttemptAdvertiseEvent(EntityUid uid, ApcPowerReceiverComponent powerReceiver, ref AttemptAdvertiseEvent args)
|
||||||
|
{
|
||||||
|
args.Cancelled |= !powerReceiver.Powered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnVendingAttemptAdvertiseEvent(EntityUid uid, VendingMachineComponent machine, ref AttemptAdvertiseEvent args)
|
||||||
|
{
|
||||||
|
args.Cancelled |= machine.Broken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class AdvertiseEnableChangeAttemptEvent(bool enabling) : CancellableEntityEventArgs
|
[ByRefEvent]
|
||||||
|
public record struct AttemptAdvertiseEvent(EntityUid? Advertiser)
|
||||||
{
|
{
|
||||||
public bool Enabling { get; } = enabling;
|
public bool Cancelled = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user