CatStation/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs
AftrLite 42729fe109
Add support for dialogue variation for SpeakOnActionSystem (#46106)
* add support for dialogue variation for SpeakOnAction

* Requested Changes - replace random with PredictedRandom

* Requested Changes - use ProtoMan instead of dependency on IprototypeManager

* adjust field name, un-nullify speakchance, add the system's functionality to Fireball

* Update Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs

Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com>

---------

Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com>
2026-09-22 01:35:19 +00:00

45 lines
1.5 KiB
C#

using Content.Shared.Speech.Components;
using Content.Shared.Actions.Events;
using Content.Shared.ActionBlocker;
using Content.Shared.Chat;
using Content.Shared.Dataset;
using Content.Shared.Random.Helpers;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Shared.Speech.EntitySystems;
public sealed partial class SpeakOnActionSystem : EntitySystem
{
[Dependency] private ActionBlockerSystem _actionBlocker = default!;
[Dependency] private SharedChatSystem _chat = default!;
[Dependency] private IGameTiming _timing = default!;
[SubscribeLocalEvent]
private void OnActionPerformed(Entity<SpeakOnActionComponent> ent, ref ActionPerformedEvent args)
{
var user = args.Performer;
var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent));
// If we can't speak, we can't speak.
if (!HasComp<SpeechComponent>(user) || !_actionBlocker.CanSpeak(user))
return;
if (!random.Prob(ent.Comp.SpeakChance))
return;
var randomSentence = GetDialogue(ent.Comp.DialogueDataset, random) ?? ent.Comp.Sentence;
if (!string.IsNullOrWhiteSpace(randomSentence))
_chat.TrySendInGameICMessage(user, Loc.GetString(randomSentence), InGameICChatType.Speak, false);
}
private string? GetDialogue(ProtoId<LocalizedDatasetPrototype>? dialogue, IRobustRandom random)
{
if (!ProtoMan.TryIndex(dialogue, out var proto))
return null;
return random.Pick(proto.Values);
}
}