--- /dev/null
+using Content.Shared.Animals.Systems;
+
+namespace Content.Client.Animals.Systems;
+
+public sealed class ParrotMemorySystem : SharedParrotMemorySystem;
using Content.Server.Speech;
using Content.Server.Speech.Components;
using Content.Server.Vocalization.Systems;
+using Content.Shared.Animals.Components;
+using Content.Shared.Animals.Systems;
using Content.Shared.Database;
using Content.Shared.Mobs.Systems;
-using Content.Shared.Popups;
-using Content.Shared.Verbs;
using Content.Shared.Whitelist;
using Robust.Shared.Network;
using Robust.Shared.Random;
/// (radiovocalizer) and stores them in a list. When an entity with a VocalizerComponent attempts to vocalize, this will
/// try to set the message from memory.
/// </summary>
-public sealed partial class ParrotMemorySystem : EntitySystem
+public sealed partial class ParrotMemorySystem : SharedParrotMemorySystem
{
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
SubscribeLocalEvent<EraseEvent>(OnErase);
- SubscribeLocalEvent<ParrotMemoryComponent, GetVerbsEvent<Verb>>(OnGetVerbs);
-
SubscribeLocalEvent<ParrotListenerComponent, MapInitEvent>(ListenerOnMapInit);
SubscribeLocalEvent<ParrotListenerComponent, ListenEvent>(OnListen);
DeletePlayerMessages(args.PlayerNetUserId);
}
- private void OnGetVerbs(Entity<ParrotMemoryComponent> entity, ref GetVerbsEvent<Verb> args)
- {
- var user = args.User;
-
- // limit this to admins
- if (!_admin.IsAdmin(user))
- return;
-
- // simple verb that just clears the memory list
- var clearMemoryVerb = new Verb()
- {
- Text = Loc.GetString("parrot-verb-clear-memory"),
- Category = VerbCategory.Admin,
- Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/clear-parrot.png")),
- Act = () =>
- {
- entity.Comp.SpeechMemories.Clear();
- _popup.PopupEntity(Loc.GetString("parrot-popup-memory-cleared"), entity, user, PopupType.Medium);
- },
- };
-
- args.Verbs.Add(clearMemoryVerb);
- }
-
private void ListenerOnMapInit(Entity<ParrotListenerComponent> entity, ref MapInitEvent args)
{
// If an entity has a ParrotListenerComponent it really ought to have an ActiveListenerComponent
+using Content.Shared.Animals.Systems;
+using Robust.Shared.GameStates;
using Robust.Shared.Network;
+using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
-namespace Content.Server.Animals.Components;
+namespace Content.Shared.Animals.Components;
/// <summary>
-/// Makes an entity able to memorize chat/radio messages
+/// Makes an entity able to memorize chat/radio messages.
/// </summary>
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentPause]
public sealed partial class ParrotMemoryComponent : Component
{
/// <summary>
- /// List of SpeechMemory records this entity has learned
+ /// List of SpeechMemory records this entity has learned.
/// </summary>
[DataField]
- public List<SpeechMemory> SpeechMemories = [];
+ public List<SpeechMemory> SpeechMemories = new();
/// <summary>
- /// The % chance an entity with this component learns a phrase when learning is off cooldown
+ /// The % chance an entity with this component learns a phrase when learning is off cooldown.
/// </summary>
[DataField]
public float LearnChance = 0.6f;
/// <summary>
- /// Time after which another attempt can be made at learning a phrase
+ /// Time after which another attempt can be made at learning a phrase.
/// </summary>
[DataField]
public TimeSpan LearnCooldown = TimeSpan.FromMinutes(1);
/// <summary>
- /// Next time at which the parrot can attempt to learn something
+ /// Next time at which the parrot can attempt to learn something.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[AutoPausedField]
public TimeSpan NextLearnInterval = TimeSpan.Zero;
/// <summary>
- /// The number of speech entries that are remembered
+ /// The number of speech entries that are remembered.
/// </summary>
[DataField]
public int MaxSpeechMemory = 50;
/// <summary>
- /// Minimum length of a speech entry
+ /// Minimum length of a speech entry.
/// </summary>
[DataField]
public int MinEntryLength = 4;
/// <summary>
- /// Maximum length of a speech entry
+ /// Maximum length of a speech entry.
/// </summary>
[DataField]
public int MaxEntryLength = 50;
}
+[Serializable, NetSerializable]
public record struct SpeechMemory(NetUserId? NetUserId, string Message);
--- /dev/null
+using Content.Shared.Administration.Managers;
+using Content.Shared.Animals.Components;
+using Content.Shared.Popups;
+using Content.Shared.Verbs;
+using Robust.Shared.Network;
+using Robust.Shared.Utility;
+
+namespace Content.Shared.Animals.Systems;
+
+public abstract class SharedParrotMemorySystem : EntitySystem
+{
+ [Dependency] private readonly SharedPopupSystem _popup = default!;
+ [Dependency] private readonly ISharedAdminManager _admin = default!;
+ [Dependency] private readonly INetManager _net = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<ParrotMemoryComponent, GetVerbsEvent<Verb>>(OnGetVerbs);
+ }
+
+ private void OnGetVerbs(Entity<ParrotMemoryComponent> entity, ref GetVerbsEvent<Verb> args)
+ {
+ var user = args.User;
+
+ // limit this to admins
+ if (!_admin.IsAdmin(user))
+ return;
+
+ // simple verb that just clears the memory list
+ var clearMemoryVerb = new Verb()
+ {
+ Text = Loc.GetString("parrot-verb-clear-memory"),
+ Category = VerbCategory.Admin,
+ Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/clear-parrot.png")),
+ Act = () =>
+ {
+ _popup.PopupClient(Loc.GetString("parrot-popup-memory-cleared"), entity.Owner, user);
+
+ if (_net.IsServer)
+ entity.Comp.SpeechMemories.Clear();
+ },
+ };
+
+ args.Verbs.Add(clearMemoryVerb);
+ }
+}