| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- using System.Linq;
- using Content.Shared.Chat.Prototypes;
- using Robust.Shared.Prototypes;
- using Robust.Shared.Random;
- using Robust.Shared.Timing;
- using Robust.Shared.Utility;
- namespace Content.Server.Chat.Systems;
- public sealed class AutoEmoteSystem : EntitySystem
- {
- [Dependency] private readonly IGameTiming _gameTiming = default!;
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- [Dependency] private readonly IRobustRandom _random = default!;
- [Dependency] private readonly ChatSystem _chatSystem = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<AutoEmoteComponent, MapInitEvent>(OnMapInit);
- SubscribeLocalEvent<AutoEmoteComponent, EntityUnpausedEvent>(OnUnpaused);
- }
- public override void Update(float frameTime)
- {
- base.Update(frameTime);
- var curTime = _gameTiming.CurTime;
- var query = EntityQueryEnumerator<AutoEmoteComponent>();
- while (query.MoveNext(out var uid, out var autoEmote))
- {
- if (autoEmote.NextEmoteTime > curTime)
- continue;
- foreach (var (key, time) in autoEmote.EmoteTimers)
- {
- if (time > curTime)
- continue;
- var autoEmotePrototype = _prototypeManager.Index<AutoEmotePrototype>(key);
- ResetTimer(uid, key, autoEmote, autoEmotePrototype);
- if (!_random.Prob(autoEmotePrototype.Chance))
- continue;
- if (autoEmotePrototype.WithChat)
- {
- _chatSystem.TryEmoteWithChat(uid, autoEmotePrototype.EmoteId, autoEmotePrototype.HiddenFromChatWindow ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal);
- }
- else
- {
- _chatSystem.TryEmoteWithoutChat(uid, autoEmotePrototype.EmoteId);
- }
- }
- }
- }
- private void OnMapInit(EntityUid uid, AutoEmoteComponent autoEmote, MapInitEvent args)
- {
- // Start timers
- foreach (var autoEmotePrototypeId in autoEmote.Emotes)
- {
- ResetTimer(uid, autoEmotePrototypeId, autoEmote);
- }
- }
- private void OnUnpaused(EntityUid uid, AutoEmoteComponent autoEmote, ref EntityUnpausedEvent args)
- {
- foreach (var key in autoEmote.EmoteTimers.Keys)
- {
- autoEmote.EmoteTimers[key] += args.PausedTime;
- }
- autoEmote.NextEmoteTime += args.PausedTime;
- }
- /// <summary>
- /// Try to add an emote to the entity, which will be performed at an interval.
- /// </summary>
- public bool AddEmote(EntityUid uid, string autoEmotePrototypeId, AutoEmoteComponent? autoEmote = null)
- {
- if (!Resolve(uid, ref autoEmote, logMissing: false))
- return false;
- DebugTools.Assert(autoEmote.LifeStage <= ComponentLifeStage.Running);
- if (autoEmote.Emotes.Contains(autoEmotePrototypeId))
- return false;
- autoEmote.Emotes.Add(autoEmotePrototypeId);
- ResetTimer(uid, autoEmotePrototypeId, autoEmote);
- return true;
- }
- /// <summary>
- /// Stop preforming an emote. Note that by default this will queue empty components for removal.
- /// </summary>
- public bool RemoveEmote(EntityUid uid, string autoEmotePrototypeId, AutoEmoteComponent? autoEmote = null, bool removeEmpty = true)
- {
- if (!Resolve(uid, ref autoEmote, logMissing: false))
- return false;
- DebugTools.Assert(_prototypeManager.HasIndex<AutoEmotePrototype>(autoEmotePrototypeId), "Prototype not found. Did you make a typo?");
- if (!autoEmote.EmoteTimers.Remove(autoEmotePrototypeId))
- return false;
- if (autoEmote.EmoteTimers.Count > 0)
- autoEmote.NextEmoteTime = autoEmote.EmoteTimers.Values.Min();
- else if (removeEmpty)
- RemCompDeferred(uid, autoEmote);
- else
- autoEmote.NextEmoteTime = TimeSpan.MaxValue;
- return true;
- }
- /// <summary>
- /// Reset the timer for a specific emote, or return false if it doesn't exist.
- /// </summary>
- public bool ResetTimer(EntityUid uid, string autoEmotePrototypeId, AutoEmoteComponent? autoEmote = null, AutoEmotePrototype? autoEmotePrototype = null)
- {
- if (!Resolve(uid, ref autoEmote))
- return false;
- if (!autoEmote.Emotes.Contains(autoEmotePrototypeId))
- return false;
- autoEmotePrototype ??= _prototypeManager.Index<AutoEmotePrototype>(autoEmotePrototypeId);
- var curTime = _gameTiming.CurTime;
- var time = curTime + autoEmotePrototype.Interval;
- autoEmote.EmoteTimers[autoEmotePrototypeId] = time;
- if (autoEmote.NextEmoteTime > time || autoEmote.NextEmoteTime <= curTime)
- autoEmote.NextEmoteTime = time;
- return true;
- }
- }
|