Northstar Gloves (#16021)
* Added Gloves of North Star, no sprite or talking yet... * Added sprites for the gloves of the north star... * Replaced more placeholder sprites for northstar gloves... * Added gloves of the north star to uplink... * Added speech on hit, not yet configureable * Not functional yet, but a step in the right direction I hope... * IT WORKS!! * Licensing and cleanup * Reduced attack speed, changed from chat to popup, added some admin logging. It was causing too much adminlog spam otherwise * Reorganized some files, final build?? * Changed the adminlog type from Verb to new type ItemConfigure * More cleanup, fix sprite reference maybe * Keronshb's suggestions, fixed some stuff, made hit sound use the meaty punch sfx * Adds support for hiding speak/whisper/emote from adminlogs, makes northstar speak again! * Some file shuffling, some of Keronshb's requests. Might appear a bit funky in github because vscode kept duplicating files for some reason and I had to delete them * Made it work with the latest changes on Master * Final? cleanup, upped dmg to 8, made ui not activate on activateinhand, instead you need to right click * Set value to 0 credits, that's all * Well that was much easier than I made it out to be. Now you can only activate the gloves with right click, no more mispredicts. * Update MeleeWeaponSystem.cs Iunno why this got changed in the first place, but I'm changin it back * emptycommit * emptycommit * The tiny fixening
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Content.Shared.Speech.Components;
|
||||||
|
|
||||||
|
namespace Content.Client.Weapons.Melee.UI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a <see cref="MeleeSpeechWindow"/> and updates it when new server messages are received.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class MeleeSpeechBoundUserInterface : BoundUserInterface
|
||||||
|
{
|
||||||
|
private MeleeSpeechWindow? _window;
|
||||||
|
|
||||||
|
public MeleeSpeechBoundUserInterface(ClientUserInterfaceComponent owner, Enum uiKey) : base(owner, uiKey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
|
||||||
|
_window = new MeleeSpeechWindow();
|
||||||
|
if (State != null)
|
||||||
|
UpdateState(State);
|
||||||
|
|
||||||
|
_window.OpenCentered();
|
||||||
|
|
||||||
|
_window.OnClose += Close;
|
||||||
|
_window.OnBattlecryEntered += OnBattlecryChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void OnBattlecryChanged(string newBattlecry)
|
||||||
|
{
|
||||||
|
SendMessage(new MeleeSpeechBattlecryChangedMessage(newBattlecry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the UI state based on server-sent info
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="state"></param>
|
||||||
|
protected override void UpdateState(BoundUserInterfaceState state)
|
||||||
|
{
|
||||||
|
base.UpdateState(state);
|
||||||
|
if (_window == null || state is not MeleeSpeechBoundUserInterfaceState cast)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_window.SetCurrentBattlecry(cast.CurrentBattlecry);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
if (!disposing) return;
|
||||||
|
_window?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml
Normal file
8
Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<DefaultWindow xmlns="https://spacestation14.io"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="{Loc north-star-menu-title}">
|
||||||
|
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150" >
|
||||||
|
<Label Name="CurrentBattlecry" Text="{Loc 'north-star-current-battlecry'}" />
|
||||||
|
<LineEdit Name="BattlecryLineEdit" />
|
||||||
|
</BoxContainer>
|
||||||
|
</DefaultWindow>
|
||||||
28
Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml.cs
Normal file
28
Content.Client/Weapons/Melee/UI/MeleeSpeechWindow.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
|
namespace Content.Client.Weapons.Melee.UI;
|
||||||
|
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public sealed partial class MeleeSpeechWindow : DefaultWindow
|
||||||
|
{
|
||||||
|
|
||||||
|
public event Action<string>? OnBattlecryEntered;
|
||||||
|
|
||||||
|
public MeleeSpeechWindow()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
|
||||||
|
BattlecryLineEdit.OnTextEntered += e => OnBattlecryEntered?.Invoke(e.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetCurrentBattlecry(string battlecry)
|
||||||
|
{
|
||||||
|
BattlecryLineEdit.Text = battlecry;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ namespace Content.Server.Chat.Commands
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>()
|
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>()
|
||||||
.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Emote, ChatTransmitRange.Normal, shell, player);
|
.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Emote, ChatTransmitRange.Normal, false, shell, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace Content.Server.Chat.Commands
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>()
|
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>()
|
||||||
.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Speak, ChatTransmitRange.Normal, shell, player);
|
.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Speak, ChatTransmitRange.Normal, false, shell, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace Content.Server.Chat.Commands
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>()
|
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>()
|
||||||
.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Whisper, ChatTransmitRange.Normal, shell, player);
|
.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Whisper, ChatTransmitRange.Normal, false, shell, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,13 +52,14 @@ public partial class ChatSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">The entity that is speaking</param>
|
/// <param name="source">The entity that is speaking</param>
|
||||||
/// <param name="emoteId">The id of emote prototype. Should has valid <see cref="EmotePrototype.ChatMessages"/></param>
|
/// <param name="emoteId">The id of emote prototype. Should has valid <see cref="EmotePrototype.ChatMessages"/></param>
|
||||||
|
/// <param name="hideLog">Whether or not this message should appear in the adminlog window</param>
|
||||||
/// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
|
/// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
|
||||||
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
||||||
public void TryEmoteWithChat(EntityUid source, string emoteId, ChatTransmitRange range = ChatTransmitRange.Normal, string? nameOverride = null)
|
public void TryEmoteWithChat(EntityUid source, string emoteId, ChatTransmitRange range = ChatTransmitRange.Normal, bool hideLog = false, string? nameOverride = null)
|
||||||
{
|
{
|
||||||
if (!_prototypeManager.TryIndex<EmotePrototype>(emoteId, out var proto))
|
if (!_prototypeManager.TryIndex<EmotePrototype>(emoteId, out var proto))
|
||||||
return;
|
return;
|
||||||
TryEmoteWithChat(source, proto, range, nameOverride);
|
TryEmoteWithChat(source, proto, range, hideLog, nameOverride);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -66,15 +67,17 @@ public partial class ChatSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">The entity that is speaking</param>
|
/// <param name="source">The entity that is speaking</param>
|
||||||
/// <param name="emote">The emote prototype. Should has valid <see cref="EmotePrototype.ChatMessages"/></param>
|
/// <param name="emote">The emote prototype. Should has valid <see cref="EmotePrototype.ChatMessages"/></param>
|
||||||
|
/// <param name="hideLog">Whether or not this message should appear in the adminlog window</param>
|
||||||
|
/// <param name="hideChat">Whether or not this message should appear in the chat window</param>
|
||||||
/// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
|
/// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
|
||||||
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
||||||
public void TryEmoteWithChat(EntityUid source, EmotePrototype emote, ChatTransmitRange range = ChatTransmitRange.Normal, string? nameOverride = null)
|
public void TryEmoteWithChat(EntityUid source, EmotePrototype emote, ChatTransmitRange range = ChatTransmitRange.Normal, bool hideLog = false, string? nameOverride = null)
|
||||||
{
|
{
|
||||||
// check if proto has valid message for chat
|
// check if proto has valid message for chat
|
||||||
if (emote.ChatMessages.Count != 0)
|
if (emote.ChatMessages.Count != 0)
|
||||||
{
|
{
|
||||||
var action = _random.Pick(emote.ChatMessages);
|
var action = _random.Pick(emote.ChatMessages);
|
||||||
SendEntityEmote(source, action, range, nameOverride, false);
|
SendEntityEmote(source, action, range, nameOverride, false, hideLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do the rest of emote event logic here
|
// do the rest of emote event logic here
|
||||||
|
|||||||
@@ -120,13 +120,14 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
/// <param name="message">The message being spoken or emoted</param>
|
/// <param name="message">The message being spoken or emoted</param>
|
||||||
/// <param name="desiredType">The chat type</param>
|
/// <param name="desiredType">The chat type</param>
|
||||||
/// <param name="hideChat">Whether or not this message should appear in the chat window</param>
|
/// <param name="hideChat">Whether or not this message should appear in the chat window</param>
|
||||||
|
/// <param name="hideLog">Whether or not this message should appear in the adminlog window</param>
|
||||||
/// <param name="shell"></param>
|
/// <param name="shell"></param>
|
||||||
/// <param name="player">The player doing the speaking</param>
|
/// <param name="player">The player doing the speaking</param>
|
||||||
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
||||||
public void TrySendInGameICMessage(EntityUid source, string message, InGameICChatType desiredType, bool hideChat,
|
public void TrySendInGameICMessage(EntityUid source, string message, InGameICChatType desiredType, bool hideChat, bool hideLog = false,
|
||||||
IConsoleShell? shell = null, IPlayerSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true)
|
IConsoleShell? shell = null, IPlayerSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true)
|
||||||
{
|
{
|
||||||
TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, shell, player, nameOverride, checkRadioPrefix);
|
TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride, checkRadioPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -139,7 +140,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
/// <param name="shell"></param>
|
/// <param name="shell"></param>
|
||||||
/// <param name="player">The player doing the speaking</param>
|
/// <param name="player">The player doing the speaking</param>
|
||||||
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
||||||
public void TrySendInGameICMessage(EntityUid source, string message, InGameICChatType desiredType, ChatTransmitRange range,
|
public void TrySendInGameICMessage(EntityUid source, string message, InGameICChatType desiredType, ChatTransmitRange range, bool hideLog = false,
|
||||||
IConsoleShell? shell = null, IPlayerSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true)
|
IConsoleShell? shell = null, IPlayerSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true)
|
||||||
{
|
{
|
||||||
if (HasComp<GhostComponent>(source))
|
if (HasComp<GhostComponent>(source))
|
||||||
@@ -194,13 +195,13 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
switch (desiredType)
|
switch (desiredType)
|
||||||
{
|
{
|
||||||
case InGameICChatType.Speak:
|
case InGameICChatType.Speak:
|
||||||
SendEntitySpeak(source, message, range, nameOverride);
|
SendEntitySpeak(source, message, range, nameOverride, hideLog);
|
||||||
break;
|
break;
|
||||||
case InGameICChatType.Whisper:
|
case InGameICChatType.Whisper:
|
||||||
SendEntityWhisper(source, message, range, null, nameOverride);
|
SendEntityWhisper(source, message, range, null, nameOverride, hideLog);
|
||||||
break;
|
break;
|
||||||
case InGameICChatType.Emote:
|
case InGameICChatType.Emote:
|
||||||
SendEntityEmote(source, message, range, nameOverride);
|
SendEntityEmote(source, message, range, nameOverride, hideLog);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,7 +295,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
|
|
||||||
#region Private API
|
#region Private API
|
||||||
|
|
||||||
private void SendEntitySpeak(EntityUid source, string originalMessage, ChatTransmitRange range, string? nameOverride)
|
private void SendEntitySpeak(EntityUid source, string originalMessage, ChatTransmitRange range, string? nameOverride, bool hideLog = false)
|
||||||
{
|
{
|
||||||
if (!_actionBlocker.CanSpeak(source))
|
if (!_actionBlocker.CanSpeak(source))
|
||||||
return;
|
return;
|
||||||
@@ -326,7 +327,8 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
RaiseLocalEvent(source, ev, true);
|
RaiseLocalEvent(source, ev, true);
|
||||||
|
|
||||||
// To avoid logging any messages sent by entities that are not players, like vendors, cloning, etc.
|
// To avoid logging any messages sent by entities that are not players, like vendors, cloning, etc.
|
||||||
if (!HasComp<ActorComponent>(source))
|
// Also doesn't log if hideLog is true.
|
||||||
|
if (!HasComp<ActorComponent>(source) || hideLog == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (originalMessage == message)
|
if (originalMessage == message)
|
||||||
@@ -347,7 +349,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendEntityWhisper(EntityUid source, string originalMessage, ChatTransmitRange range, RadioChannelPrototype? channel, string? nameOverride)
|
private void SendEntityWhisper(EntityUid source, string originalMessage, ChatTransmitRange range, RadioChannelPrototype? channel, string? nameOverride, bool hideLog = false)
|
||||||
{
|
{
|
||||||
if (!_actionBlocker.CanSpeak(source))
|
if (!_actionBlocker.CanSpeak(source))
|
||||||
return;
|
return;
|
||||||
@@ -399,7 +401,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
|
|
||||||
var ev = new EntitySpokeEvent(source, message, channel, obfuscatedMessage);
|
var ev = new EntitySpokeEvent(source, message, channel, obfuscatedMessage);
|
||||||
RaiseLocalEvent(source, ev, true);
|
RaiseLocalEvent(source, ev, true);
|
||||||
|
if (!hideLog)
|
||||||
if (originalMessage == message)
|
if (originalMessage == message)
|
||||||
{
|
{
|
||||||
if (name != Name(source))
|
if (name != Name(source))
|
||||||
@@ -418,7 +420,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendEntityEmote(EntityUid source, string action, ChatTransmitRange range, string? nameOverride, bool checkEmote = true)
|
private void SendEntityEmote(EntityUid source, string action, ChatTransmitRange range, string? nameOverride, bool hideLog = false, bool checkEmote = true)
|
||||||
{
|
{
|
||||||
if (!_actionBlocker.CanEmote(source)) return;
|
if (!_actionBlocker.CanEmote(source)) return;
|
||||||
|
|
||||||
@@ -433,7 +435,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
if (checkEmote)
|
if (checkEmote)
|
||||||
TryEmoteChatInput(source, action);
|
TryEmoteChatInput(source, action);
|
||||||
SendInVoiceRange(ChatChannel.Emotes, action, wrappedMessage, source, range);
|
SendInVoiceRange(ChatChannel.Emotes, action, wrappedMessage, source, range);
|
||||||
|
if (!hideLog)
|
||||||
if (name != Name(source))
|
if (name != Name(source))
|
||||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Emote from {ToPrettyString(source):user} as {name}: {action}");
|
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Emote from {ToPrettyString(source):user} as {name}: {action}");
|
||||||
else
|
else
|
||||||
@@ -714,7 +716,7 @@ public sealed class TransformSpeakerNameEvent : EntityEventArgs
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised broadcast in order to transform speech.
|
/// Raised broadcast in order to transform speech.transmit
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class TransformSpeechEvent : EntityEventArgs
|
public sealed class TransformSpeechEvent : EntityEventArgs
|
||||||
{
|
{
|
||||||
|
|||||||
66
Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs
Normal file
66
Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using Content.Server.Administration.Logs;
|
||||||
|
using Content.Shared.Speech.Components;
|
||||||
|
using Content.Shared.Weapons.Melee;
|
||||||
|
using Content.Shared.Database;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Content.Server.Speech.EntitySystems;
|
||||||
|
|
||||||
|
public sealed class MeleeSpeechSystem : SharedMeleeSpeechSystem
|
||||||
|
{
|
||||||
|
|
||||||
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
|
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<MeleeSpeechComponent, MeleeSpeechBattlecryChangedMessage>(OnBattlecryChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void OnBattlecryChanged(EntityUid uid, MeleeSpeechComponent comp, MeleeSpeechBattlecryChangedMessage args)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!TryComp<MeleeSpeechComponent>(uid, out var meleeSpeechUser))
|
||||||
|
return;
|
||||||
|
|
||||||
|
TryChangeBattlecry(uid, args.Battlecry, meleeSpeechUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to change the battlecry of an entity.
|
||||||
|
/// Returns true/false.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If provided with a player's EntityUid to the player parameter, adds the change to the admin logs.
|
||||||
|
/// </remarks>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -42,6 +42,13 @@ namespace Content.Server.UserInterface
|
|||||||
[DataField("requireHands")]
|
[DataField("requireHands")]
|
||||||
public bool RequireHands = true;
|
public bool RequireHands = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether you can activate this ui with activateinhand or not
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("rightClickOnly")]
|
||||||
|
public bool rightClickOnly = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether spectators (non-admin ghosts) should be allowed to view this UI.
|
/// Whether spectators (non-admin ghosts) should be allowed to view this UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
|
|||||||
private void OnUseInHand(EntityUid uid, ActivatableUIComponent component, UseInHandEvent args)
|
private void OnUseInHand(EntityUid uid, ActivatableUIComponent component, UseInHandEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled) return;
|
if (args.Handled) return;
|
||||||
|
if (component.rightClickOnly) return;
|
||||||
args.Handled = InteractUI(args.User, component);
|
args.Handled = InteractUI(args.User, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Body.Components;
|
using Content.Server.Body.Components;
|
||||||
using Content.Server.Body.Systems;
|
using Content.Server.Body.Systems;
|
||||||
|
using Content.Server.Chat.Systems;
|
||||||
using Content.Server.Chemistry.Components;
|
using Content.Server.Chemistry.Components;
|
||||||
using Content.Server.Chemistry.EntitySystems;
|
using Content.Server.Chemistry.EntitySystems;
|
||||||
using Content.Server.CombatMode.Disarm;
|
using Content.Server.CombatMode.Disarm;
|
||||||
using Content.Server.Contests;
|
using Content.Server.Contests;
|
||||||
using Content.Server.Examine;
|
using Content.Server.Examine;
|
||||||
using Content.Server.Movement.Systems;
|
using Content.Server.Movement.Systems;
|
||||||
using Content.Shared.Actions.Events;
|
using Content.Server.Popups;
|
||||||
using Content.Shared.Administration.Components;
|
using Content.Shared.Administration.Components;
|
||||||
|
using Content.Shared.Actions.Events;
|
||||||
using Content.Shared.CombatMode;
|
using Content.Shared.CombatMode;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
@@ -17,6 +19,7 @@ using Content.Shared.Hands.Components;
|
|||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Speech.Components;
|
||||||
using Content.Shared.StatusEffect;
|
using Content.Shared.StatusEffect;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
@@ -42,11 +45,15 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem
|
|||||||
[Dependency] private readonly LagCompensationSystem _lag = default!;
|
[Dependency] private readonly LagCompensationSystem _lag = default!;
|
||||||
[Dependency] private readonly SolutionContainerSystem _solutions = default!;
|
[Dependency] private readonly SolutionContainerSystem _solutions = default!;
|
||||||
[Dependency] private readonly TagSystem _tag = default!;
|
[Dependency] private readonly TagSystem _tag = default!;
|
||||||
|
[Dependency] private readonly ChatSystem _chat = default!;
|
||||||
|
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||||
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<MeleeChemicalInjectorComponent, MeleeHitEvent>(OnChemicalInjectorHit);
|
SubscribeLocalEvent<MeleeChemicalInjectorComponent, MeleeHitEvent>(OnChemicalInjectorHit);
|
||||||
|
SubscribeLocalEvent<MeleeSpeechComponent, MeleeHitEvent>(OnSpeechHit);
|
||||||
SubscribeLocalEvent<MeleeWeaponComponent, GetVerbsEvent<ExamineVerb>>(OnMeleeExaminableVerb);
|
SubscribeLocalEvent<MeleeWeaponComponent, GetVerbsEvent<ExamineVerb>>(OnMeleeExaminableVerb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,6 +272,21 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem
|
|||||||
RaiseNetworkEvent(new MeleeLungeEvent(user, angle, localPos, animation), filter);
|
RaiseNetworkEvent(new MeleeLungeEvent(user, angle, localPos, animation), filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSpeechHit(EntityUid owner, MeleeSpeechComponent comp, MeleeHitEvent args)
|
||||||
|
{
|
||||||
|
if (!args.IsHit ||
|
||||||
|
!args.HitEntities.Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp.Battlecry != null)//If the battlecry is set to empty, doesn't speak
|
||||||
|
{
|
||||||
|
_chat.TrySendInGameICMessage(args.User, comp.Battlecry, InGameICChatType.Speak, true, true); //Speech that isn't sent to chat or adminlogs
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void OnChemicalInjectorHit(EntityUid owner, MeleeChemicalInjectorComponent comp, MeleeHitEvent args)
|
private void OnChemicalInjectorHit(EntityUid owner, MeleeChemicalInjectorComponent comp, MeleeHitEvent args)
|
||||||
{
|
{
|
||||||
if (!args.IsHit ||
|
if (!args.IsHit ||
|
||||||
|
|||||||
@@ -86,4 +86,5 @@ public enum LogType
|
|||||||
Teleport = 81,
|
Teleport = 81,
|
||||||
EntityDelete = 82,
|
EntityDelete = 82,
|
||||||
Vote = 83,
|
Vote = 83,
|
||||||
|
ItemConfigure = 84,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Content.Shared.Clothing.EntitySystems;
|
using Content.Shared.Clothing.EntitySystems;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|||||||
51
Content.Shared/Speech/Components/MeleeSpeechComponent.cs
Normal file
51
Content.Shared/Speech/Components/MeleeSpeechComponent.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using Content.Shared.Speech.EntitySystems;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Speech.Components;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
[AutoGenerateComponentState]
|
||||||
|
[Access(typeof(SharedMeleeSpeechSystem), Other = AccessPermissions.ReadWrite)]
|
||||||
|
public sealed partial class MeleeSpeechComponent : Component
|
||||||
|
{
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("Battlecry")]
|
||||||
|
[AutoNetworkedField]
|
||||||
|
[Access(typeof(SharedMeleeSpeechSystem), Other = AccessPermissions.ReadWrite)]
|
||||||
|
public string? Battlecry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key representing which <see cref="BoundUserInterface"/> is currently open.
|
||||||
|
/// Useful when there are multiple UI for an object. Here it's future-proofing only.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum MeleeSpeechUiKey : byte
|
||||||
|
{
|
||||||
|
Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an <see cref="MeleeSpeechComponent"/> state that can be sent to the client
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class MeleeSpeechBoundUserInterfaceState : BoundUserInterfaceState
|
||||||
|
{
|
||||||
|
public string CurrentBattlecry { get; }
|
||||||
|
|
||||||
|
public MeleeSpeechBoundUserInterfaceState(string currentBattlecry)
|
||||||
|
{
|
||||||
|
CurrentBattlecry = currentBattlecry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class MeleeSpeechBattlecryChangedMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public string Battlecry { get; }
|
||||||
|
public MeleeSpeechBattlecryChangedMessage(string battlecry)
|
||||||
|
{
|
||||||
|
Battlecry = battlecry;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Weapons.Melee;
|
||||||
|
|
||||||
|
public abstract class SharedMeleeSpeechSystem : EntitySystem
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Speech
|
namespace Content.Shared.Speech
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public sealed class MeleeWeaponComponent : Component
|
|||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public bool Attacking = false;
|
public bool Attacking = false;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When did we start a heavy attack.
|
/// When did we start a heavy attack.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
7
Content.Shared/Weapons/Melee/SharedMeleeSpeechSystem.cs
Normal file
7
Content.Shared/Weapons/Melee/SharedMeleeSpeechSystem.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Speech.EntitySystems;
|
||||||
|
|
||||||
|
public abstract class SharedMeleeSpeechSystem : EntitySystem
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
north-star-current-battlecry = Battlecry:
|
||||||
|
north-star-menu-title = Set Battlecry
|
||||||
@@ -20,6 +20,9 @@ uplink-edagger-desc = A small energy blade conveniently disguised in the form of
|
|||||||
uplink-fire-axe-flaming-name = Fire Axe
|
uplink-fire-axe-flaming-name = Fire Axe
|
||||||
uplink-fire-axe-flaming-desc = A classic-style weapon infused with advanced atmos technology to allow it to set targets on fire.
|
uplink-fire-axe-flaming-desc = A classic-style weapon infused with advanced atmos technology to allow it to set targets on fire.
|
||||||
|
|
||||||
|
uplink-gloves-north-star-name = Gloves of the North Star
|
||||||
|
uplink-gloves-north-star-desc = A pair of gloves that reduce your punching cooldown drastically, allowing you to beat people to death in a flurry of punches.
|
||||||
|
|
||||||
# Explosives
|
# Explosives
|
||||||
uplink-explosive-grenade-name = Explosive Grenade
|
uplink-explosive-grenade-name = Explosive Grenade
|
||||||
uplink-explosive-grenade-desc = Grenade that creates a small but devastating explosion.
|
uplink-explosive-grenade-desc = Grenade that creates a small but devastating explosion.
|
||||||
|
|||||||
@@ -75,6 +75,16 @@
|
|||||||
categories:
|
categories:
|
||||||
- UplinkWeapons
|
- UplinkWeapons
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkGlovesNorthStar
|
||||||
|
name: uplink-gloves-north-star-name
|
||||||
|
description: uplink-gloves-north-star-desc
|
||||||
|
productEntity: ClothingHandsGlovesNorthStar
|
||||||
|
cost:
|
||||||
|
Telecrystal: 8
|
||||||
|
categories:
|
||||||
|
- UplinkWeapons
|
||||||
|
|
||||||
# Explosives
|
# Explosives
|
||||||
|
|
||||||
- type: listing
|
- type: listing
|
||||||
|
|||||||
@@ -293,6 +293,40 @@
|
|||||||
components:
|
components:
|
||||||
- type: Unremoveable
|
- type: Unremoveable
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ClothingHandsBase
|
||||||
|
id: ClothingHandsGlovesNorthStar
|
||||||
|
name: gloves of the north star
|
||||||
|
description: These gloves allow you to punch incredibly fast
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Clothing/Hands/Gloves/northstar.rsi
|
||||||
|
- type: Clothing
|
||||||
|
sprite: Clothing/Hands/Gloves/northstar.rsi
|
||||||
|
- type: MeleeWeapon
|
||||||
|
attackRate: 4
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 8
|
||||||
|
soundHit:
|
||||||
|
collection: Punch
|
||||||
|
animation: WeaponArcFist
|
||||||
|
- type: Fiber
|
||||||
|
fiberMaterial: fibers-leather
|
||||||
|
fiberColor: fibers-blue
|
||||||
|
- type: FingerprintMask
|
||||||
|
- type: MeleeSpeech
|
||||||
|
- type: ActivatableUI
|
||||||
|
key: enum.MeleeSpeechUiKey.Key
|
||||||
|
closeOnHandDeselect: false
|
||||||
|
rightClickOnly: true
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.MeleeSpeechUiKey.Key
|
||||||
|
type: MeleeSpeechBoundUserInterface
|
||||||
|
- type: StaticPrice
|
||||||
|
price: 0
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingHandsBase
|
parent: ClothingHandsBase
|
||||||
id: ForensicGloves
|
id: ForensicGloves
|
||||||
@@ -304,3 +338,4 @@
|
|||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/forensic.rsi
|
sprite: Clothing/Hands/Gloves/forensic.rsi
|
||||||
- type: FingerprintMask
|
- type: FingerprintMask
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 434 B |
BIN
Resources/Textures/Clothing/Hands/Gloves/northstar.rsi/icon.png
Normal file
BIN
Resources/Textures/Clothing/Hands/Gloves/northstar.rsi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 289 B |
Binary file not shown.
|
After Width: | Height: | Size: 933 B |
Binary file not shown.
|
After Width: | Height: | Size: 881 B |
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/pull/37864/commits/efdef3f1f997d1c0575c36cd31a5db575d1df0ca#diff-a4eb7c89f7231f0aaf0c2f69d730dea56383019f2aa5c6a1d91a82c781b528e6. Modified by hercoyote23 (github) for SS14",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-HAND",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user