@@ -39,6 +39,7 @@
|
|||||||
<CheckBox Name="ViewportLowResCheckBox" Text="{Loc 'ui-options-vp-low-res'}" />
|
<CheckBox Name="ViewportLowResCheckBox" Text="{Loc 'ui-options-vp-low-res'}" />
|
||||||
<CheckBox Name="ParallaxLowQualityCheckBox" Text="{Loc 'ui-options-parallax-low-quality'}" />
|
<CheckBox Name="ParallaxLowQualityCheckBox" Text="{Loc 'ui-options-parallax-low-quality'}" />
|
||||||
<CheckBox Name="FpsCounterCheckBox" Text="{Loc 'ui-options-fps-counter'}" />
|
<CheckBox Name="FpsCounterCheckBox" Text="{Loc 'ui-options-fps-counter'}" />
|
||||||
|
<CheckBox Name="LogInChatCheckBox" Text="Логировать действия в чат" />
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
<controls:StripeBack HasBottomEdge="False" HasMargins="False">
|
<controls:StripeBack HasBottomEdge="False" HasMargins="False">
|
||||||
<Button Name="ApplyButton"
|
<Button Name="ApplyButton"
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
|
using Content.Shared.HUD;
|
||||||
|
using Content.Shared.White;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
@@ -71,6 +73,7 @@ namespace Content.Client.Options.UI.Tabs
|
|||||||
ViewportLowResCheckBox.OnToggled += OnCheckBoxToggled;
|
ViewportLowResCheckBox.OnToggled += OnCheckBoxToggled;
|
||||||
ParallaxLowQualityCheckBox.OnToggled += OnCheckBoxToggled;
|
ParallaxLowQualityCheckBox.OnToggled += OnCheckBoxToggled;
|
||||||
FpsCounterCheckBox.OnToggled += OnCheckBoxToggled;
|
FpsCounterCheckBox.OnToggled += OnCheckBoxToggled;
|
||||||
|
LogInChatCheckBox.OnToggled += OnCheckBoxToggled;
|
||||||
ApplyButton.OnPressed += OnApplyButtonPressed;
|
ApplyButton.OnPressed += OnApplyButtonPressed;
|
||||||
VSyncCheckBox.Pressed = _cfg.GetCVar(CVars.DisplayVSync);
|
VSyncCheckBox.Pressed = _cfg.GetCVar(CVars.DisplayVSync);
|
||||||
FullscreenCheckBox.Pressed = ConfigIsFullscreen;
|
FullscreenCheckBox.Pressed = ConfigIsFullscreen;
|
||||||
@@ -82,6 +85,7 @@ namespace Content.Client.Options.UI.Tabs
|
|||||||
ViewportLowResCheckBox.Pressed = !_cfg.GetCVar(CCVars.ViewportScaleRender);
|
ViewportLowResCheckBox.Pressed = !_cfg.GetCVar(CCVars.ViewportScaleRender);
|
||||||
ParallaxLowQualityCheckBox.Pressed = _cfg.GetCVar(CCVars.ParallaxLowQuality);
|
ParallaxLowQualityCheckBox.Pressed = _cfg.GetCVar(CCVars.ParallaxLowQuality);
|
||||||
FpsCounterCheckBox.Pressed = _cfg.GetCVar(CCVars.HudFpsCounterVisible);
|
FpsCounterCheckBox.Pressed = _cfg.GetCVar(CCVars.HudFpsCounterVisible);
|
||||||
|
LogInChatCheckBox.Pressed = _cfg.GetCVar(WhiteCVars.LogInChat);
|
||||||
ViewportWidthSlider.Value = _cfg.GetCVar(CCVars.ViewportWidth);
|
ViewportWidthSlider.Value = _cfg.GetCVar(CCVars.ViewportWidth);
|
||||||
|
|
||||||
_cfg.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportWidthRange());
|
_cfg.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportWidthRange());
|
||||||
@@ -114,6 +118,7 @@ namespace Content.Client.Options.UI.Tabs
|
|||||||
_cfg.SetCVar(CCVars.ViewportScaleRender, !ViewportLowResCheckBox.Pressed);
|
_cfg.SetCVar(CCVars.ViewportScaleRender, !ViewportLowResCheckBox.Pressed);
|
||||||
_cfg.SetCVar(CCVars.ParallaxLowQuality, ParallaxLowQualityCheckBox.Pressed);
|
_cfg.SetCVar(CCVars.ParallaxLowQuality, ParallaxLowQualityCheckBox.Pressed);
|
||||||
_cfg.SetCVar(CCVars.HudFpsCounterVisible, FpsCounterCheckBox.Pressed);
|
_cfg.SetCVar(CCVars.HudFpsCounterVisible, FpsCounterCheckBox.Pressed);
|
||||||
|
_cfg.SetCVar(WhiteCVars.LogInChat, LogInChatCheckBox.Pressed);
|
||||||
_cfg.SetCVar(CCVars.ViewportWidth, (int) ViewportWidthSlider.Value);
|
_cfg.SetCVar(CCVars.ViewportWidth, (int) ViewportWidthSlider.Value);
|
||||||
|
|
||||||
_cfg.SaveToFile();
|
_cfg.SaveToFile();
|
||||||
@@ -143,6 +148,7 @@ namespace Content.Client.Options.UI.Tabs
|
|||||||
var isVPResSame = ViewportLowResCheckBox.Pressed == !_cfg.GetCVar(CCVars.ViewportScaleRender);
|
var isVPResSame = ViewportLowResCheckBox.Pressed == !_cfg.GetCVar(CCVars.ViewportScaleRender);
|
||||||
var isPLQSame = ParallaxLowQualityCheckBox.Pressed == _cfg.GetCVar(CCVars.ParallaxLowQuality);
|
var isPLQSame = ParallaxLowQualityCheckBox.Pressed == _cfg.GetCVar(CCVars.ParallaxLowQuality);
|
||||||
var isFpsCounterVisibleSame = FpsCounterCheckBox.Pressed == _cfg.GetCVar(CCVars.HudFpsCounterVisible);
|
var isFpsCounterVisibleSame = FpsCounterCheckBox.Pressed == _cfg.GetCVar(CCVars.HudFpsCounterVisible);
|
||||||
|
var isLogInChatSame = LogInChatCheckBox.Pressed == _cfg.GetCVar(WhiteCVars.LogInChat);
|
||||||
var isWidthSame = (int) ViewportWidthSlider.Value == _cfg.GetCVar(CCVars.ViewportWidth);
|
var isWidthSame = (int) ViewportWidthSlider.Value == _cfg.GetCVar(CCVars.ViewportWidth);
|
||||||
|
|
||||||
ApplyButton.Disabled = isVSyncSame &&
|
ApplyButton.Disabled = isVSyncSame &&
|
||||||
@@ -155,7 +161,8 @@ namespace Content.Client.Options.UI.Tabs
|
|||||||
isVPResSame &&
|
isVPResSame &&
|
||||||
isPLQSame &&
|
isPLQSame &&
|
||||||
isFpsCounterVisibleSame &&
|
isFpsCounterVisibleSame &&
|
||||||
isWidthSame;
|
isWidthSame &&
|
||||||
|
isLogInChatSame;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ConfigIsFullscreen =>
|
private bool ConfigIsFullscreen =>
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Client.Examine;
|
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Interaction;
|
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Client.Chat.Managers;
|
||||||
|
using Content.Shared.Chat;
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.White;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Input;
|
using Robust.Client.Input;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
@@ -27,6 +30,7 @@ namespace Content.Client.Popups
|
|||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||||
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
|
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
|
||||||
|
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||||
|
|
||||||
public IReadOnlyList<WorldPopupLabel> WorldLabels => _aliveWorldLabels;
|
public IReadOnlyList<WorldPopupLabel> WorldLabels => _aliveWorldLabels;
|
||||||
public IReadOnlyList<CursorPopupLabel> CursorLabels => _aliveCursorLabels;
|
public IReadOnlyList<CursorPopupLabel> CursorLabels => _aliveCursorLabels;
|
||||||
@@ -38,6 +42,8 @@ namespace Content.Client.Popups
|
|||||||
public const float MaximumPopupLifetime = 5f;
|
public const float MaximumPopupLifetime = 5f;
|
||||||
public const float PopupLifetimePerCharacter = 0.04f;
|
public const float PopupLifetimePerCharacter = 0.04f;
|
||||||
|
|
||||||
|
private bool isLogging;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeNetworkEvent<PopupCursorEvent>(OnPopupCursorEvent);
|
SubscribeNetworkEvent<PopupCursorEvent>(OnPopupCursorEvent);
|
||||||
@@ -46,6 +52,9 @@ namespace Content.Client.Popups
|
|||||||
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundRestart);
|
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundRestart);
|
||||||
_overlay
|
_overlay
|
||||||
.AddOverlay(new PopupOverlay(_configManager, EntityManager, _playerManager, _prototype, _resource, _uiManager, this));
|
.AddOverlay(new PopupOverlay(_configManager, EntityManager, _playerManager, _prototype, _resource, _uiManager, this));
|
||||||
|
|
||||||
|
isLogging = _configManager.GetCVar(WhiteCVars.LogInChat);
|
||||||
|
_configManager.OnValueChanged(WhiteCVars.LogInChat, (log) => { isLogging = log; });
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
@@ -72,6 +81,11 @@ namespace Content.Client.Popups
|
|||||||
};
|
};
|
||||||
|
|
||||||
_aliveWorldLabels.Add(label);
|
_aliveWorldLabels.Add(label);
|
||||||
|
|
||||||
|
if (isLogging)
|
||||||
|
{
|
||||||
|
_chatManager.SendMessage($"notice {message}", ChatSelectChannel.Console);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Abstract Method Implementations
|
#region Abstract Method Implementations
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public sealed partial class TapeCreatorMenu : DefaultWindow
|
|||||||
_huetaSystem = _entityManager.System<CheZaHuetaSystem>();
|
_huetaSystem = _entityManager.System<CheZaHuetaSystem>();
|
||||||
_popupSystem = _entityManager.System<SharedPopupSystem>();
|
_popupSystem = _entityManager.System<SharedPopupSystem>();
|
||||||
|
|
||||||
_cfg.OnValueChanged(WhiteCVars.MaxJukeboxSongSizeInMB, x => _maxFileSize = x, true);
|
_cfg.OnValueChanged(WhiteCVars.MaxJukeboxSongSizeInMb, x => _maxFileSize = x, true);
|
||||||
|
|
||||||
_component = component;
|
_component = component;
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,11 @@ namespace Content.Server.Body.Systems
|
|||||||
if (_gameTiming.CurTime >= respirator.LastGaspPopupTime + respirator.GaspPopupCooldown)
|
if (_gameTiming.CurTime >= respirator.LastGaspPopupTime + respirator.GaspPopupCooldown)
|
||||||
{
|
{
|
||||||
respirator.LastGaspPopupTime = _gameTiming.CurTime;
|
respirator.LastGaspPopupTime = _gameTiming.CurTime;
|
||||||
_popupSystem.PopupEntity(Loc.GetString("lung-behavior-gasp"), uid);
|
|
||||||
|
if (TryComp<MetaDataComponent>(uid, out var metaDataComponent))
|
||||||
|
{
|
||||||
|
_popupSystem.PopupEntity($"{metaDataComponent.EntityName} задыхается!", uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TakeSuffocationDamage(uid, respirator);
|
TakeSuffocationDamage(uid, respirator);
|
||||||
|
|||||||
@@ -159,9 +159,10 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
IConsoleShell? shell = null,
|
IConsoleShell? shell = null,
|
||||||
ICommonSession? player = null, string? nameOverride = null,
|
ICommonSession? player = null, string? nameOverride = null,
|
||||||
bool checkRadioPrefix = true,
|
bool checkRadioPrefix = true,
|
||||||
bool ignoreActionBlocker = false)
|
bool ignoreActionBlocker = false,
|
||||||
|
bool force = false)
|
||||||
{
|
{
|
||||||
TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride, checkRadioPrefix, ignoreActionBlocker);
|
TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride, checkRadioPrefix, ignoreActionBlocker, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -242,7 +243,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
// Was there an emote in the message? If so, send it.
|
// Was there an emote in the message? If so, send it.
|
||||||
if (emoteStr != message && emoteStr != null)
|
if (emoteStr != message && emoteStr != null)
|
||||||
{
|
{
|
||||||
SendEntityEmote(source, emoteStr, range, nameOverride, ignoreActionBlocker, force: force);
|
SendEntityEmote(source, emoteStr, range, nameOverride, ignoreActionBlocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This can happen if the entire string is sanitized out.
|
// This can happen if the entire string is sanitized out.
|
||||||
@@ -273,7 +274,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker);
|
SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker);
|
||||||
break;
|
break;
|
||||||
case InGameICChatType.Emote:
|
case InGameICChatType.Emote:
|
||||||
SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, ignoreActionBlocker: ignoreActionBlocker, force: force);
|
SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, ignoreActionBlocker: ignoreActionBlocker);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,8 +597,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
bool hideLog = false,
|
bool hideLog = false,
|
||||||
bool checkEmote = true,
|
bool checkEmote = true,
|
||||||
bool ignoreActionBlocker = false,
|
bool ignoreActionBlocker = false,
|
||||||
NetUserId? author = null,
|
NetUserId? author = null
|
||||||
bool force = false
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!_actionBlocker.CanEmote(source) && !ignoreActionBlocker)
|
if (!_actionBlocker.CanEmote(source) && !ignoreActionBlocker)
|
||||||
|
|||||||
43
Content.Server/White/Commands/NoticeCommand.cs
Normal file
43
Content.Server/White/Commands/NoticeCommand.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using Content.Server.Chat.Managers;
|
||||||
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.Chat;
|
||||||
|
using Robust.Server.Player;
|
||||||
|
using Robust.Shared.Console;
|
||||||
|
using Robust.Shared.Enums;
|
||||||
|
|
||||||
|
namespace Content.Server.White.Commands;
|
||||||
|
|
||||||
|
[AnyCommand]
|
||||||
|
internal sealed class NoticeCommand : IConsoleCommand
|
||||||
|
{
|
||||||
|
public string Command => "notice";
|
||||||
|
public string Description => "Send a chat message to self.";
|
||||||
|
public string Help => "notice <text>";
|
||||||
|
|
||||||
|
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||||
|
{
|
||||||
|
if (shell.Player is not IPlayerSession player)
|
||||||
|
{
|
||||||
|
shell.WriteError("This command cannot be run from the server.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.Status != SessionStatus.InGame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (player.AttachedEntity is not { } playerEntity)
|
||||||
|
{
|
||||||
|
shell.WriteError("You don't have an entity!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var message = string.Join(" ", args).Trim();
|
||||||
|
if (string.IsNullOrEmpty(message))
|
||||||
|
return;
|
||||||
|
|
||||||
|
IoCManager.Resolve<IChatManager>().ChatMessageToOne(ChatChannel.Emotes, message, message, EntityUid.Invalid, false, player.ConnectedClient, recordReplay: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -129,7 +129,7 @@ public sealed class ERTRecruitmentRule : StationEventSystem<ERTRecruitmentRuleCo
|
|||||||
|
|
||||||
private void OnStartAttempt(RoundStartAttemptEvent ev)
|
private void OnStartAttempt(RoundStartAttemptEvent ev)
|
||||||
{
|
{
|
||||||
if(_cfgManager.GetCVar(WhiteCVars.LoadERTMap))
|
if(_cfgManager.GetCVar(WhiteCVars.LoadErtMap))
|
||||||
SpawnMap();
|
SpawnMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
76
Content.Server/White/Other/CritMobActionsSystem.cs
Normal file
76
Content.Server/White/Other/CritMobActionsSystem.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using Content.Server.Administration;
|
||||||
|
using Content.Server.Chat.Systems;
|
||||||
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Mobs.Systems;
|
||||||
|
using Content.Shared.White.Other;
|
||||||
|
using Robust.Server.Console;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.White.Other;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles performing crit-specific actions.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CritMobActionsSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ChatSystem _chat = default!;
|
||||||
|
[Dependency] private readonly IServerConsoleHost _host = default!;
|
||||||
|
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||||
|
[Dependency] private readonly QuickDialogSystem _quickDialog = default!;
|
||||||
|
|
||||||
|
private const int MaxLastWordsLength = 30;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<MobStateActionsComponent, CritSuccumbEvent>(OnSuccumb);
|
||||||
|
SubscribeLocalEvent<MobStateActionsComponent, CritLastWordsEvent>(OnLastWords);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSuccumb(EntityUid uid, MobStateActionsComponent component, CritSuccumbEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<ActorComponent>(uid, out var actor) || !_mobState.IsCritical(uid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_host.ExecuteCommand(actor.PlayerSession, "ghost");
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLastWords(EntityUid uid, MobStateActionsComponent component, CritLastWordsEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<ActorComponent>(uid, out var actor))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_quickDialog.OpenDialog(actor.PlayerSession, Loc.GetString("action-name-crit-last-words"), "",
|
||||||
|
(string lastWords) =>
|
||||||
|
{
|
||||||
|
if (actor.PlayerSession.AttachedEntity != uid
|
||||||
|
|| !_mobState.IsCritical(uid))
|
||||||
|
return;
|
||||||
|
if (lastWords.Length > MaxLastWordsLength)
|
||||||
|
{
|
||||||
|
lastWords = lastWords.Substring(0, MaxLastWordsLength);
|
||||||
|
}
|
||||||
|
lastWords += "...";
|
||||||
|
_chat.TrySendInGameICMessage(uid, lastWords, InGameICChatType.Whisper, ChatTransmitRange.Normal, force: true);
|
||||||
|
_host.ExecuteCommand(actor.PlayerSession, "ghost");
|
||||||
|
});
|
||||||
|
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only applies to mobs in crit capable of ghosting/succumbing
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CritSuccumbEvent : InstantActionEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only applies to mobs capable of speaking, as a last resort in crit
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CritLastWordsEvent : InstantActionEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -4,21 +4,39 @@ using Robust.Shared.Enums;
|
|||||||
using Content.Shared.Humanoid;
|
using Content.Shared.Humanoid;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.PDA;
|
using Content.Shared.PDA;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.Console;
|
||||||
|
|
||||||
namespace Content.Server.White.Other.ExamineSystem
|
namespace Content.Server.White.Other.ExamineSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//^.^
|
||||||
public sealed class ExamineSystem : EntitySystem
|
public sealed class ExamineSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||||
[Dependency] private readonly EntityManager _entityManager = default!;
|
[Dependency] private readonly EntityManager _entityManager = default!;
|
||||||
|
[Dependency] private readonly IConsoleHost _consoleHost = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<ExaminableClothesComponent, ExaminedEvent>(HandleExamine);
|
SubscribeLocalEvent<ExaminableClothesComponent, ExaminedEvent>(HandleExamine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SendNoticeMessage(ActorComponent actorComponent, string message)
|
||||||
|
=> _consoleHost.RemoteExecuteCommand(actorComponent.PlayerSession, $"notice {message}");
|
||||||
|
|
||||||
private void HandleExamine(EntityUid uid, ExaminableClothesComponent comp, ExaminedEvent args)
|
private void HandleExamine(EntityUid uid, ExaminableClothesComponent comp, ExaminedEvent args)
|
||||||
{
|
{
|
||||||
|
var infoLines = new List<string>();
|
||||||
|
|
||||||
|
infoLines.Add("⠀"); // :D DA POEBAT MNE
|
||||||
|
|
||||||
|
if (TryComp<ActorComponent>(args.Examiner, out var actorComponent) &&
|
||||||
|
TryComp<MetaDataComponent>(uid, out var metaDataComponent))
|
||||||
|
{
|
||||||
|
infoLines.Add($"Это же [bold]{metaDataComponent.EntityName}[/bold]!");
|
||||||
|
}
|
||||||
|
|
||||||
var slotLabels = new Dictionary<string, string>
|
var slotLabels = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ "head", "head-" },
|
{ "head", "head-" },
|
||||||
@@ -62,15 +80,29 @@ namespace Content.Server.White.Other.ExamineSystem
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_entityManager.TryGetComponent<MetaDataComponent>(slotEntity, out var metaData))
|
if (_entityManager.TryGetComponent<MetaDataComponent>(slotEntity, out var metaData))
|
||||||
args.PushMarkup($"[color=silver]{Loc.GetString(slotLabel)} [/color][font size=11][bold][color=lightgray]{metaData.EntityName}[/color][/bold][/font].");
|
{
|
||||||
|
var item = $"[color=silver]{Loc.GetString(slotLabel)} [/color][font size=11][bold][color=lightgray]{metaData.EntityName}[/color][/bold][/font].";
|
||||||
|
args.PushMarkup(item);
|
||||||
|
infoLines.Add(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var id = GetInfo(uid);
|
var idInfoString = GetInfo(uid);
|
||||||
if (id != null)
|
if (!string.IsNullOrEmpty(idInfoString))
|
||||||
args.PushMarkup(id);
|
{
|
||||||
|
infoLines.Add(idInfoString);
|
||||||
|
args.PushMarkup(idInfoString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? GetInfo(EntityUid uid)
|
var combinedInfo = string.Join("\n", infoLines);
|
||||||
|
|
||||||
|
if (actorComponent != null)
|
||||||
|
{
|
||||||
|
SendNoticeMessage(actorComponent, combinedInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetInfo(EntityUid uid)
|
||||||
{
|
{
|
||||||
if (_inventorySystem.TryGetSlotEntity(uid, "id", out var idUid))
|
if (_inventorySystem.TryGetSlotEntity(uid, "id", out var idUid))
|
||||||
{
|
{
|
||||||
@@ -86,12 +118,12 @@ namespace Content.Server.White.Other.ExamineSystem
|
|||||||
return GetNameAndJob(id);
|
return GetNameAndJob(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetNameAndJob(IdCardComponent id)
|
private string GetNameAndJob(IdCardComponent id)
|
||||||
{
|
{
|
||||||
var jobSuffix = string.IsNullOrWhiteSpace(id.JobTitle) ? string.Empty : $" ({id.JobTitle})";
|
var jobSuffix = string.IsNullOrWhiteSpace(id.JobTitle) ? "" : $" ({id.JobTitle})";
|
||||||
|
|
||||||
var val = string.IsNullOrWhiteSpace(id.FullName)
|
var val = string.IsNullOrWhiteSpace(id.FullName)
|
||||||
? Loc.GetString("access-id-card-component-owner-name-job-title-text",
|
? Loc.GetString("access-id-card-component-owner-name-job-title-text",
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ public sealed class TTSManager
|
|||||||
/// <exception cref="Exception">Throws if url or token CCVar not set or http request failed</exception>
|
/// <exception cref="Exception">Throws if url or token CCVar not set or http request failed</exception>
|
||||||
public async Task<byte[]?> ConvertTextToSpeech(string speaker, string text, string pitch, string rate)
|
public async Task<byte[]?> ConvertTextToSpeech(string speaker, string text, string pitch, string rate)
|
||||||
{
|
{
|
||||||
var url = _cfg.GetCVar(WhiteCVars.TTSApiUrl);
|
var url = _cfg.GetCVar(WhiteCVars.TtsApiUrl);
|
||||||
var maxCacheSize = _cfg.GetCVar(WhiteCVars.TTSMaxCacheSize);
|
var maxCacheSize = _cfg.GetCVar(WhiteCVars.TtsMaxCacheSize);
|
||||||
if (string.IsNullOrWhiteSpace(url))
|
if (string.IsNullOrWhiteSpace(url))
|
||||||
{
|
{
|
||||||
throw new Exception("TTS Api url not specified");
|
throw new Exception("TTS Api url not specified");
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ public sealed partial class TTSSystem : EntitySystem
|
|||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_cfg.OnValueChanged(WhiteCVars.TTSEnabled, v => _isEnabled = v, true);
|
_cfg.OnValueChanged(WhiteCVars.TtsEnabled, v => _isEnabled = v, true);
|
||||||
_cfg.OnValueChanged(WhiteCVars.TTSApiUrl, url => _apiUrl = url, true);
|
_cfg.OnValueChanged(WhiteCVars.TtsApiUrl, url => _apiUrl = url, true);
|
||||||
|
|
||||||
SubscribeLocalEvent<TransformSpeechEvent>(OnTransformSpeech);
|
SubscribeLocalEvent<TransformSpeechEvent>(OnTransformSpeech);
|
||||||
SubscribeLocalEvent<TTSComponent, EntitySpokeEvent>(OnEntitySpoke);
|
SubscribeLocalEvent<TTSComponent, EntitySpokeEvent>(OnEntitySpoke);
|
||||||
@@ -116,7 +116,7 @@ public sealed partial class TTSSystem : EntitySystem
|
|||||||
|
|
||||||
private async void OnRequestTTS(MsgRequestTTS ev)
|
private async void OnRequestTTS(MsgRequestTTS ev)
|
||||||
{
|
{
|
||||||
var url = _cfg.GetCVar(WhiteCVars.TTSApiUrl);
|
var url = _cfg.GetCVar(WhiteCVars.TtsApiUrl);
|
||||||
if (string.IsNullOrWhiteSpace(url))
|
if (string.IsNullOrWhiteSpace(url))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
27
Content.Shared/White/Other/MobStateActionsComponent.cs
Normal file
27
Content.Shared/White/Other/MobStateActionsComponent.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using Content.Shared.Mobs;
|
||||||
|
|
||||||
|
namespace Content.Shared.White.Other;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used for specifying actions that should be automatically added/removed on mob state transitions
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Mostly for crit-specific actions.
|
||||||
|
/// </remarks>
|
||||||
|
/// <see cref="MobStateActionsSystem"/>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class MobStateActionsComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies a list of actions that should be available if a mob is in a given state.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// actions:
|
||||||
|
/// Critical:
|
||||||
|
/// - CritSuccumb
|
||||||
|
/// Alive:
|
||||||
|
/// - AnimalLayEgg
|
||||||
|
/// </example>
|
||||||
|
[DataField("actions")]
|
||||||
|
public Dictionary<MobState, List<string>> Actions = new();
|
||||||
|
}
|
||||||
54
Content.Shared/White/Other/MobStateActionsSystem.cs
Normal file
54
Content.Shared/White/Other/MobStateActionsSystem.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Actions.ActionTypes;
|
||||||
|
using Content.Shared.Mobs;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.White.Other;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds and removes defined actions when a mob's <see cref="MobState"/> changes.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class MobStateActionsSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
|
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<MobStateActionsComponent, MobStateChangedEvent>(OnMobStateChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMobStateChanged(EntityUid uid, MobStateActionsComponent component, MobStateChangedEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<ActionsComponent>(uid, out var action))
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var (state, acts) in component.Actions)
|
||||||
|
{
|
||||||
|
if (state != args.NewMobState && state != args.OldMobState)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var item in acts)
|
||||||
|
{
|
||||||
|
if (!_proto.TryIndex<InstantActionPrototype>(item, out var proto))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var instance = new InstantAction(proto);
|
||||||
|
if (state == args.OldMobState)
|
||||||
|
{
|
||||||
|
// Don't remove actions that would be getting readded anyway
|
||||||
|
if (component.Actions.TryGetValue(args.NewMobState, out var value)
|
||||||
|
&& value.Contains(item))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_actions.RemoveAction(uid, instance, action);
|
||||||
|
}
|
||||||
|
else if (state == args.NewMobState)
|
||||||
|
{
|
||||||
|
_actions.AddAction(uid, instance, null, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,13 +90,13 @@ public sealed class WhiteCVars
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// URL of the TTS server API.
|
/// URL of the TTS server API.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<bool> TTSEnabled =
|
public static readonly CVarDef<bool> TtsEnabled =
|
||||||
CVarDef.Create("tts.enabled", true, CVar.SERVERONLY);
|
CVarDef.Create("tts.enabled", true, CVar.SERVERONLY);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// URL of the TTS server API.
|
/// URL of the TTS server API.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<string> TTSApiUrl =
|
public static readonly CVarDef<string> TtsApiUrl =
|
||||||
CVarDef.Create("tts.api_url", "", CVar.SERVERONLY);
|
CVarDef.Create("tts.api_url", "", CVar.SERVERONLY);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -108,7 +108,7 @@ public sealed class WhiteCVars
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// TTS Cache
|
/// TTS Cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<int> TTSMaxCacheSize =
|
public static readonly CVarDef<int> TtsMaxCacheSize =
|
||||||
CVarDef.Create("tts.max_cash_size", 200, CVar.SERVERONLY | CVar.ARCHIVE);
|
CVarDef.Create("tts.max_cash_size", 200, CVar.SERVERONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ public sealed class WhiteCVars
|
|||||||
* Jukebox
|
* Jukebox
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static readonly CVarDef<float> MaxJukeboxSongSizeInMB = CVarDef.Create("white.max_jukebox_song_size",
|
public static readonly CVarDef<float> MaxJukeboxSongSizeInMb = CVarDef.Create("white.max_jukebox_song_size",
|
||||||
3.5f, CVar.SERVER | CVar.REPLICATED | CVar.ARCHIVE);
|
3.5f, CVar.SERVER | CVar.REPLICATED | CVar.ARCHIVE);
|
||||||
|
|
||||||
public static readonly CVarDef<float> MaxJukeboxSoundRange = CVarDef.Create("white.max_jukebox_sound_range", 20f,
|
public static readonly CVarDef<float> MaxJukeboxSoundRange = CVarDef.Create("white.max_jukebox_sound_range", 20f,
|
||||||
@@ -299,4 +299,7 @@ public sealed class WhiteCVars
|
|||||||
/// Should load a ERT map?
|
/// Should load a ERT map?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<bool> LoadERTMap = CVarDef.Create("white.ert_load", false, CVar.SERVERONLY);
|
public static readonly CVarDef<bool> LoadERTMap = CVarDef.Create("white.ert_load", false, CVar.SERVERONLY);
|
||||||
|
|
||||||
|
public static readonly CVarDef<bool> LogInChat =
|
||||||
|
CVarDef.Create("white.log_in_chat", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,3 +108,12 @@ cult-role-greeting =
|
|||||||
В ваш рюкзак были добавлены предметы, которые помогут вам.
|
В ваш рюкзак были добавлены предметы, которые помогут вам.
|
||||||
И помните - вы не единственный.
|
И помните - вы не единственный.
|
||||||
Слава Нар`си!
|
Слава Нар`си!
|
||||||
|
|
||||||
|
|
||||||
|
# MobStateShit
|
||||||
|
|
||||||
|
action-name-crit-succumb = Succumb
|
||||||
|
action-description-crit-succumb = Accept your fate.
|
||||||
|
|
||||||
|
action-name-crit-last-words = Say Last Words
|
||||||
|
action-description-crit-last-words = Whisper your last words to anyone nearby, and then succumb to your fate. You only have 30 characters to work with.
|
||||||
|
|||||||
@@ -234,6 +234,11 @@
|
|||||||
- type: ExaminableClothes
|
- type: ExaminableClothes
|
||||||
- type: CharacterInformation
|
- type: CharacterInformation
|
||||||
- type: Penetrated
|
- type: Penetrated
|
||||||
|
- type: MobStateActions
|
||||||
|
actions:
|
||||||
|
Critical:
|
||||||
|
- CritSuccumb
|
||||||
|
- CritLastWords
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
save: false
|
save: false
|
||||||
|
|||||||
Reference in New Issue
Block a user