mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-20 23:17:43 +03:00
# Description This refactors #510 and #553. #553 specifically was reverted and re-implemented from scratch. As a consequence to all of this, the chat system was refactored a bit too, hopefully for the best. Changes: - InGameICChatType, InGameOOCChatType, ChatTransmitRange were all moved to shared and made serializable - Added a method to wrap whisper messages to reduce code duplication in chat system - Both WrapPublicMethod and WrapWhisperMessage call the same generic WrapMessage method, which allows to add speech verbs to whispers and more. That method is also fully responsible for adding language markers and deducing speech verbs now. - Everything related to speech was moved out of LanguagePrototype and into SpeechOverrideInfo. LanguagePrototype now holds an instance of that. - Added AllowRadio, RequireSpeech, ChatTypeOverride, SpeechVerbOverrides, MessageWrapOverrides to SpeechOverrideInfo, all of which are used in implementing the sign language. - Suffered a lot # TODO - [X] Cry - [X] Fix the sign language not displaying properly over the character. - [X] Find a way to circumvent being unable to speak?? <details><summary><h1>Media</h1></summary><p>  See below </p></details> # Changelog No cl no fun --------- Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com>
108 lines
4.0 KiB
C#
108 lines
4.0 KiB
C#
using Content.Server.Advertise.Components;
|
|
using Content.Server.Chat.Systems;
|
|
using Content.Server.Power.Components;
|
|
using Content.Shared.Chat;
|
|
using Content.Shared.VendingMachines;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Random;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Server.Advertise.EntitySystems;
|
|
|
|
public sealed class AdvertiseSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
[Dependency] private readonly IRobustRandom _random = default!;
|
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
|
[Dependency] private readonly ChatSystem _chat = default!;
|
|
|
|
/// <summary>
|
|
/// The maximum amount of time between checking if advertisements should be displayed
|
|
/// </summary>
|
|
private readonly TimeSpan _maximumNextCheckDuration = TimeSpan.FromSeconds(15);
|
|
|
|
/// <summary>
|
|
/// The next time the game will check if advertisements should be displayed
|
|
/// </summary>
|
|
private TimeSpan _nextCheckTime = TimeSpan.MinValue;
|
|
|
|
public override void Initialize()
|
|
{
|
|
SubscribeLocalEvent<AdvertiseComponent, MapInitEvent>(OnMapInit);
|
|
|
|
SubscribeLocalEvent<ApcPowerReceiverComponent, AttemptAdvertiseEvent>(OnPowerReceiverAttemptAdvertiseEvent);
|
|
SubscribeLocalEvent<VendingMachineComponent, AttemptAdvertiseEvent>(OnVendingAttemptAdvertiseEvent);
|
|
|
|
_nextCheckTime = TimeSpan.MinValue;
|
|
}
|
|
|
|
private void OnMapInit(EntityUid uid, AdvertiseComponent advert, MapInitEvent args)
|
|
{
|
|
var prewarm = advert.Prewarm;
|
|
RandomizeNextAdvertTime(advert, prewarm);
|
|
_nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime);
|
|
}
|
|
|
|
private void RandomizeNextAdvertTime(AdvertiseComponent advert, bool prewarm = false)
|
|
{
|
|
var minDuration = prewarm ? 0 : Math.Max(1, advert.MinimumWait);
|
|
var maxDuration = Math.Max(minDuration, advert.MaximumWait);
|
|
var waitDuration = TimeSpan.FromSeconds(_random.Next(minDuration, maxDuration));
|
|
|
|
advert.NextAdvertisementTime = _gameTiming.CurTime + waitDuration;
|
|
}
|
|
|
|
public void SayAdvertisement(EntityUid uid, AdvertiseComponent? advert = null)
|
|
{
|
|
if (!Resolve(uid, ref advert))
|
|
return;
|
|
|
|
var attemptEvent = new AttemptAdvertiseEvent(uid);
|
|
RaiseLocalEvent(uid, ref attemptEvent);
|
|
if (attemptEvent.Cancelled)
|
|
return;
|
|
|
|
if (_prototypeManager.TryIndex(advert.Pack, out var advertisements))
|
|
_chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.Messages)), InGameICChatType.Speak, hideChat: true);
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
var currentGameTime = _gameTiming.CurTime;
|
|
if (_nextCheckTime > currentGameTime)
|
|
return;
|
|
|
|
// _nextCheckTime starts at TimeSpan.MinValue, so this has to SET the value, not just increment it.
|
|
_nextCheckTime = currentGameTime + _maximumNextCheckDuration;
|
|
|
|
var query = EntityQueryEnumerator<AdvertiseComponent>();
|
|
while (query.MoveNext(out var uid, out var advert))
|
|
{
|
|
if (currentGameTime > advert.NextAdvertisementTime)
|
|
{
|
|
SayAdvertisement(uid, advert);
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
[ByRefEvent]
|
|
public record struct AttemptAdvertiseEvent(EntityUid? Advertiser)
|
|
{
|
|
public bool Cancelled = false;
|
|
}
|