parrotMemory is onGetVerbs now in shared (#39341)

* parrotMemory is onGetVerbs now in shared

* code review

* code review popup on client rename parrotMemoryComponent

* code rev create client system

* forgot usings

* is server now
This commit is contained in:
Token
2025-08-03 05:27:49 +05:00
committed by GitHub
parent c538d7fb2b
commit 9d3edeb641
4 changed files with 71 additions and 40 deletions

View File

@@ -0,0 +1,5 @@
using Content.Shared.Animals.Systems;
namespace Content.Client.Animals.Systems;
public sealed class ParrotMemorySystem : SharedParrotMemorySystem;

View File

@@ -8,10 +8,10 @@ using Content.Server.Radio;
using Content.Server.Speech; using Content.Server.Speech;
using Content.Server.Speech.Components; using Content.Server.Speech.Components;
using Content.Server.Vocalization.Systems; using Content.Server.Vocalization.Systems;
using Content.Shared.Animals.Components;
using Content.Shared.Animals.Systems;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Popups;
using Content.Shared.Verbs;
using Content.Shared.Whitelist; using Content.Shared.Whitelist;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Random; using Robust.Shared.Random;
@@ -25,7 +25,7 @@ namespace Content.Server.Animals.Systems;
/// (radiovocalizer) and stores them in a list. When an entity with a VocalizerComponent attempts to vocalize, this will /// (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. /// try to set the message from memory.
/// </summary> /// </summary>
public sealed partial class ParrotMemorySystem : EntitySystem public sealed partial class ParrotMemorySystem : SharedParrotMemorySystem
{ {
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!; [Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!;
@@ -42,8 +42,6 @@ public sealed partial class ParrotMemorySystem : EntitySystem
SubscribeLocalEvent<EraseEvent>(OnErase); SubscribeLocalEvent<EraseEvent>(OnErase);
SubscribeLocalEvent<ParrotMemoryComponent, GetVerbsEvent<Verb>>(OnGetVerbs);
SubscribeLocalEvent<ParrotListenerComponent, MapInitEvent>(ListenerOnMapInit); SubscribeLocalEvent<ParrotListenerComponent, MapInitEvent>(ListenerOnMapInit);
SubscribeLocalEvent<ParrotListenerComponent, ListenEvent>(OnListen); SubscribeLocalEvent<ParrotListenerComponent, ListenEvent>(OnListen);
@@ -57,30 +55,6 @@ public sealed partial class ParrotMemorySystem : EntitySystem
DeletePlayerMessages(args.PlayerNetUserId); 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) private void ListenerOnMapInit(Entity<ParrotListenerComponent> entity, ref MapInitEvent args)
{ {
// If an entity has a ParrotListenerComponent it really ought to have an ActiveListenerComponent // If an entity has a ParrotListenerComponent it really ought to have an ActiveListenerComponent

View File

@@ -1,57 +1,61 @@
using Content.Shared.Animals.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.Animals.Components; namespace Content.Shared.Animals.Components;
/// <summary> /// <summary>
/// Makes an entity able to memorize chat/radio messages /// Makes an entity able to memorize chat/radio messages.
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent, NetworkedComponent]
[AutoGenerateComponentPause] [AutoGenerateComponentPause]
public sealed partial class ParrotMemoryComponent : Component public sealed partial class ParrotMemoryComponent : Component
{ {
/// <summary> /// <summary>
/// List of SpeechMemory records this entity has learned /// List of SpeechMemory records this entity has learned.
/// </summary> /// </summary>
[DataField] [DataField]
public List<SpeechMemory> SpeechMemories = []; public List<SpeechMemory> SpeechMemories = new();
/// <summary> /// <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> /// </summary>
[DataField] [DataField]
public float LearnChance = 0.6f; public float LearnChance = 0.6f;
/// <summary> /// <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> /// </summary>
[DataField] [DataField]
public TimeSpan LearnCooldown = TimeSpan.FromMinutes(1); public TimeSpan LearnCooldown = TimeSpan.FromMinutes(1);
/// <summary> /// <summary>
/// Next time at which the parrot can attempt to learn something /// Next time at which the parrot can attempt to learn something.
/// </summary> /// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[AutoPausedField] [AutoPausedField]
public TimeSpan NextLearnInterval = TimeSpan.Zero; public TimeSpan NextLearnInterval = TimeSpan.Zero;
/// <summary> /// <summary>
/// The number of speech entries that are remembered /// The number of speech entries that are remembered.
/// </summary> /// </summary>
[DataField] [DataField]
public int MaxSpeechMemory = 50; public int MaxSpeechMemory = 50;
/// <summary> /// <summary>
/// Minimum length of a speech entry /// Minimum length of a speech entry.
/// </summary> /// </summary>
[DataField] [DataField]
public int MinEntryLength = 4; public int MinEntryLength = 4;
/// <summary> /// <summary>
/// Maximum length of a speech entry /// Maximum length of a speech entry.
/// </summary> /// </summary>
[DataField] [DataField]
public int MaxEntryLength = 50; public int MaxEntryLength = 50;
} }
[Serializable, NetSerializable]
public record struct SpeechMemory(NetUserId? NetUserId, string Message); public record struct SpeechMemory(NetUserId? NetUserId, string Message);

View File

@@ -0,0 +1,48 @@
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);
}
}