diff --git a/Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml b/Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml
index 5f5e324962..76ae8a331d 100644
--- a/Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml
+++ b/Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml
@@ -1,8 +1,8 @@
+ Title="{Loc melee-speech-menu-title}">
-
+
diff --git a/Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs b/Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs
index 65cde8f8f4..4e884f5f3b 100644
--- a/Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs
+++ b/Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs
@@ -1,76 +1,83 @@
using Content.Server.Administration.Logs;
+using Content.Shared.Actions;
using Content.Shared.Speech.Components;
using Content.Shared.Speech.EntitySystems;
using Content.Shared.Database;
-
+using Robust.Server.GameObjects;
namespace Content.Server.Speech.EntitySystems;
public sealed class MeleeSpeechSystem : SharedMeleeSpeechSystem
{
-
- [Dependency] private readonly IAdminLogManager _adminLogger = default!;
-
-
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent(OnBattlecryChanged);
- }
-
-
- private void OnBattlecryChanged(EntityUid uid, MeleeSpeechComponent comp, MeleeSpeechBattlecryChangedMessage args)
- {
-
+ [Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly SharedActionsSystem _actionSystem = default!;
+ [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnBattlecryChanged);
+ SubscribeLocalEvent(OnConfigureAction);
+ SubscribeLocalEvent(OnGetActions);
+ SubscribeLocalEvent(OnComponentInit);
+ }
+ private void OnComponentInit(EntityUid uid, MeleeSpeechComponent component, ComponentInit args)
+ {
+ if (component.ConfigureAction != null)
+ _actionSystem.AddAction(uid, component.ConfigureAction, uid);
+ }
+ private void OnGetActions(EntityUid uid, MeleeSpeechComponent component, GetItemActionsEvent args)
+ {
+ if (component.ConfigureAction != null)
+ args.Actions.Add(component.ConfigureAction);
+ }
+ private void OnBattlecryChanged(EntityUid uid, MeleeSpeechComponent comp, MeleeSpeechBattlecryChangedMessage args)
+ {
if (!TryComp(uid, out var meleeSpeechUser))
- return;
-
- string battlecry = args.Battlecry;
-
+ return;
+ var battlecry = args.Battlecry;
if (battlecry.Length > comp.MaxBattlecryLength)
battlecry = battlecry[..comp.MaxBattlecryLength];
-
TryChangeBattlecry(uid, battlecry, meleeSpeechUser);
- }
-
-
-
-
- ///
- /// Attempts to change the battlecry of an entity.
- /// Returns true/false.
- ///
- ///
- /// If provided with a player's EntityUid to the player parameter, adds the change to the admin logs.
- ///
- public bool TryChangeBattlecry(EntityUid uid, string? battlecry, MeleeSpeechComponent? meleeSpeechComp = null)
- {
-
+ }
+ ///
+ /// Attempts to open the Battlecry UI.
+ ///
+ private void OnConfigureAction(EntityUid uid, MeleeSpeechComponent comp, MeleeSpeechConfigureActionEvent args)
+ {
+ TryOpenUi(args.Performer, uid, comp);
+ }
+ public void TryOpenUi(EntityUid user, EntityUid source, MeleeSpeechComponent? component = null)
+ {
+ if (!Resolve(source, ref component))
+ return;
+ if (!TryComp(user, out var actor))
+ return;
+ _uiSystem.TryToggleUi(source, MeleeSpeechUiKey.Key, actor.PlayerSession);
+ }
+ ///
+ /// Attempts to change the battlecry of an entity.
+ /// Returns true/false.
+ ///
+ ///
+ /// Logs changes to an entity's battlecry
+ ///
+ public bool TryChangeBattlecry(EntityUid uid, string? battlecry, MeleeSpeechComponent? meleeSpeechComp = null)
+ {
if (!Resolve(uid, ref meleeSpeechComp))
- return false;
-
- if (!string.IsNullOrWhiteSpace(battlecry))
- {
- battlecry = battlecry.Trim();
-
-
- }
- else
- {
- battlecry = null;
- }
-
- if (meleeSpeechComp.Battlecry == battlecry)
-
- return true;
-
-
-
- meleeSpeechComp.Battlecry = battlecry;
- Dirty(meleeSpeechComp);
-
- _adminLogger.Add(LogType.ItemConfigure, LogImpact.Medium, $" {ToPrettyString(uid):entity}'s battlecry has been changed to {battlecry}");
- return true;
- }
+ return false;
+ if (!string.IsNullOrWhiteSpace(battlecry))
+ {
+ battlecry = battlecry.Trim();
+ }
+ else
+ {
+ battlecry = null;
+ }
+ if (meleeSpeechComp.Battlecry == battlecry)
+ return true;
+ meleeSpeechComp.Battlecry = battlecry;
+ Dirty(uid, meleeSpeechComp);
+ _adminLogger.Add(LogType.ItemConfigure, LogImpact.Medium, $" {ToPrettyString(uid):entity}'s battlecry has been changed to {battlecry}");
+ return true;
+ }
}
-
diff --git a/Content.Shared/Speech/Components/MeleeSpeechComponent.cs b/Content.Shared/Speech/Components/MeleeSpeechComponent.cs
index 060d44974d..8dfc2b971f 100644
--- a/Content.Shared/Speech/Components/MeleeSpeechComponent.cs
+++ b/Content.Shared/Speech/Components/MeleeSpeechComponent.cs
@@ -1,21 +1,43 @@
-using Content.Shared.Speech.EntitySystems;
+using Content.Shared.Actions;
+using Content.Shared.Actions.ActionTypes;
+using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
-
namespace Content.Shared.Speech.Components;
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
+
public sealed partial class MeleeSpeechComponent : Component
{
+ ///
+ /// The battlecry to be said when an entity attacks with this component
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("Battlecry")]
+ [AutoNetworkedField]
+ public string? Battlecry;
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("Battlecry")]
- [AutoNetworkedField]
- public string? Battlecry;
-
+ ///
+ /// The maximum amount of characters allowed in a battlecry
+ ///
[ViewVariables(VVAccess.ReadWrite)]
[DataField("MaxBattlecryLength")]
+ [AutoNetworkedField]
public int MaxBattlecryLength = 12;
+
+ ///
+ /// The action to open the battlecry UI
+ ///
+ [DataField("configureAction")]
+ public InstantAction ConfigureAction = new()
+ {
+ UseDelay = TimeSpan.FromSeconds(1),
+ ItemIconStyle = ItemActionIconStyle.BigItem,
+ DisplayName = "melee-speech-config",
+ Description = "melee-speech-config-desc",
+ Priority = -20,
+ Event = new MeleeSpeechConfigureActionEvent(),
+ };
}
///
@@ -35,7 +57,6 @@ public enum MeleeSpeechUiKey : byte
public sealed class MeleeSpeechBoundUserInterfaceState : BoundUserInterfaceState
{
public string CurrentBattlecry { get; }
-
public MeleeSpeechBoundUserInterfaceState(string currentBattlecry)
{
CurrentBattlecry = currentBattlecry;
@@ -51,3 +72,5 @@ public sealed class MeleeSpeechBattlecryChangedMessage : BoundUserInterfaceMessa
Battlecry = battlecry;
}
}
+
+public sealed partial class MeleeSpeechConfigureActionEvent : InstantActionEvent { }
diff --git a/Resources/Locale/en-US/clothing/components/northstar-component.ftl b/Resources/Locale/en-US/clothing/components/northstar-component.ftl
deleted file mode 100644
index ba54ed3c11..0000000000
--- a/Resources/Locale/en-US/clothing/components/northstar-component.ftl
+++ /dev/null
@@ -1,2 +0,0 @@
-north-star-current-battlecry = Battlecry:
-north-star-menu-title = Set Battlecry
diff --git a/Resources/Locale/en-US/speech/melee-speech.ftl b/Resources/Locale/en-US/speech/melee-speech.ftl
new file mode 100644
index 0000000000..a8696719e6
--- /dev/null
+++ b/Resources/Locale/en-US/speech/melee-speech.ftl
@@ -0,0 +1,4 @@
+melee-speech-config = Set Battlecry
+melee-speech-config-desc = Set a custom battlecry for when you attack!
+melee-speech-current-battlecry = Battlecry:
+melee-speech-menu-title = Set Battlecry
\ No newline at end of file
diff --git a/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml b/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml
index a7fae03d35..5f81f3ad1b 100644
--- a/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml
+++ b/Resources/Prototypes/Entities/Clothing/Hands/gloves.yml
@@ -322,6 +322,7 @@
components:
- type: Unremoveable
+
- type: entity
parent: ClothingHandsBase
id: ClothingHandsGlovesNorthStar
@@ -349,6 +350,7 @@
key: enum.MeleeSpeechUiKey.Key
closeOnHandDeselect: false
rightClickOnly: true
+ - type: Actions
- type: UserInterface
interfaces:
- key: enum.MeleeSpeechUiKey.Key
diff --git a/Resources/Prototypes/Entities/Mobs/Player/guardian.yml b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml
index 0e07bb4acf..f4c611874d 100644
--- a/Resources/Prototypes/Entities/Mobs/Player/guardian.yml
+++ b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml
@@ -89,6 +89,11 @@
damage:
types:
Blunt: 20
+ - type: MeleeSpeech
+ - type: UserInterface
+ interfaces:
+ - key: enum.MeleeSpeechUiKey.Key
+ type: MeleeSpeechBoundUserInterface
- type: Actions
- type: Guardian
- type: InteractionPopup