Speech verbs & conditional markup modification (#18980)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Speech;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -26,6 +27,9 @@ public abstract class SharedChatSystem : EntitySystem
|
||||
|
||||
public static string DefaultChannelPrefix = $"{RadioChannelPrefix}{DefaultChannelKey}";
|
||||
|
||||
[ValidatePrototypeId<SpeechVerbPrototype>]
|
||||
public const string DefaultSpeechVerb = "Default";
|
||||
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
@@ -63,6 +67,30 @@ public abstract class SharedChatSystem : EntitySystem
|
||||
_prototypeManager.PrototypesReloaded -= OnPrototypeReload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to find an applicable <see cref="SpeechVerbPrototype"/> for a speaking entity's message.
|
||||
/// If one is not found, returns <see cref="DefaultSpeechVerb"/>.
|
||||
/// </summary>
|
||||
public SpeechVerbPrototype GetSpeechVerb(EntityUid source, string message, SpeechComponent? speech = null)
|
||||
{
|
||||
if (!Resolve(source, ref speech, false))
|
||||
return _prototypeManager.Index<SpeechVerbPrototype>(DefaultSpeechVerb);
|
||||
|
||||
// check for a suffix-applicable speech verb
|
||||
SpeechVerbPrototype? current = null;
|
||||
foreach (var (str, id) in speech.SuffixSpeechVerbs)
|
||||
{
|
||||
var proto = _prototypeManager.Index<SpeechVerbPrototype>(id);
|
||||
if (message.EndsWith(Loc.GetString(str)) && proto.Priority >= (current?.Priority ?? 0))
|
||||
{
|
||||
current = proto;
|
||||
}
|
||||
}
|
||||
|
||||
// if no applicable suffix verb return the normal one used by the entity
|
||||
return current ?? _prototypeManager.Index<SpeechVerbPrototype>(speech.SpeechVerb);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve radio prefixes in chat messages (e.g., remove a leading ":e" and resolve the requested
|
||||
/// channel. Returns true if a radio message was attempted, even if the channel is invalid.
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
using System.Collections.Specialized;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||
|
||||
namespace Content.Shared.Speech
|
||||
{
|
||||
/// <summary>
|
||||
/// Component required for entities to be able to speak. (TODO: Entities can speak fine without this, this only forbids them speak if they have it and enabled is false.)
|
||||
/// Contains the option to let entities make noise when speaking, datafields for the sounds in question, and relevant AudioParams.
|
||||
/// Contains the option to let entities make noise when speaking, change speech verbs, datafields for the sounds in question, and relevant AudioParams.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed class SpeechComponent : Component
|
||||
@@ -20,6 +22,25 @@ namespace Content.Shared.Speech
|
||||
[DataField("speechSounds", customTypeSerializer:typeof(PrototypeIdSerializer<SpeechSoundsPrototype>))]
|
||||
public string? SpeechSounds;
|
||||
|
||||
/// <summary>
|
||||
/// What speech verb prototype should be used by default for displaying this entity's messages?
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("speechVerb", customTypeSerializer:typeof(PrototypeIdSerializer<SpeechVerbPrototype>))]
|
||||
public string SpeechVerb = "Default";
|
||||
|
||||
/// <summary>
|
||||
/// A mapping from chat suffixes loc strings to speech verb prototypes that should be conditionally used.
|
||||
/// For things like '?' changing to 'asks' or '!!' making text bold and changing to 'yells'. Can be overridden if necessary.
|
||||
/// </summary>
|
||||
[DataField("suffixSpeechVerbs", customTypeSerializer:typeof(PrototypeIdValueDictionarySerializer<string, SpeechVerbPrototype>))]
|
||||
public Dictionary<string, string> SuffixSpeechVerbs = new()
|
||||
{
|
||||
{ "chat-speech-verb-suffix-exclamation-strong", "DefaultExclamationStrong" },
|
||||
{ "chat-speech-verb-suffix-exclamation", "DefaultExclamation" },
|
||||
{ "chat-speech-verb-suffix-question", "DefaultQuestion" },
|
||||
};
|
||||
|
||||
[DataField("audioParams")]
|
||||
public AudioParams AudioParams = AudioParams.Default.WithVolume(6f).WithRolloffFactor(4.5f);
|
||||
|
||||
|
||||
47
Content.Shared/Speech/SpeechVerbPrototype.cs
Normal file
47
Content.Shared/Speech/SpeechVerbPrototype.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Shared.Speech;
|
||||
|
||||
/// <summary>
|
||||
/// Handles replacing speech verbs and other conditional chat modifications like bolding or font type depending
|
||||
/// on punctuation or by directly overriding the prototype.
|
||||
/// </summary>
|
||||
[Prototype("speechVerb")]
|
||||
public sealed class SpeechVerbPrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Loc strings to be passed to the chat wrapper. 'says', 'states', etc.
|
||||
/// Picks one at random if there are multiple.
|
||||
/// </summary>
|
||||
[DataField("speechVerbStrings", required: true)]
|
||||
public List<string> SpeechVerbStrings = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Should use of this speech verb bold the corresponding message?
|
||||
/// </summary>
|
||||
[DataField("bold")]
|
||||
public bool Bold = false;
|
||||
|
||||
/// <summary>
|
||||
/// What font size should be used for the message contents?
|
||||
/// </summary>
|
||||
[DataField("fontSize")]
|
||||
public int FontSize = 12;
|
||||
|
||||
/// <summary>
|
||||
/// What font prototype ID should be used for the message contents?
|
||||
/// </summary>
|
||||
/// font proto is client only so cant lint this lol sorry
|
||||
[DataField("fontId")]
|
||||
public string FontId = "Default";
|
||||
|
||||
/// <summary>
|
||||
/// If multiple applicable speech verb protos are found (i.e. through speech suffixes) this will determine
|
||||
/// which one is picked. Higher = more priority.
|
||||
/// </summary>
|
||||
[DataField("priority")]
|
||||
public int Priority = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user