Guard bell (#1242)

* add Guard Bell

* revert vanila changes, add same functionality

* revert more vanila changes, replace .ogg, fix locale and locale usage

* Update GuardBell.yml

* Update base.yml

* add attributions.yml for alerts

* try changing to proper license

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
This commit is contained in:
Militore
2025-05-09 15:07:05 +03:00
committed by GitHub
parent d9c2bd8e09
commit aa2e080e31
17 changed files with 278 additions and 4 deletions

View File

@@ -0,0 +1,55 @@
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Communications;
using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
namespace Content.Client._CP14.UserInterface
{
public sealed class GuardBellBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[ViewVariables]
private GuardBellMenu? _menu;
public GuardBellBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_menu = this.CreateWindow<GuardBellMenu>();
_menu.OnAlertLevel += AlertLevelSelected;
}
public void AlertLevelSelected(string level)
{
if (_menu!.AlertLevelSelectable)
{
_menu.CurrentLevel = level;
SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level));
}
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not CommunicationsConsoleInterfaceState commsState)
return;
if (_menu != null)
{
_menu.AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0;
_menu.CurrentLevel = commsState.CurrentAlert;
_menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel);
_menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable;
}
}
}
}

View File

@@ -0,0 +1,28 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'cp14-guard-bell-menu-title'}"
MinSize="200 100">
<!-- Main Container -->
<BoxContainer Orientation="Vertical"
HorizontalExpand="False"
VerticalExpand="True"
Margin="6 6 6 5">
<!-- ButtonsPart -->
<BoxContainer Orientation="Vertical"
VerticalAlignment="Bottom"
SeparationOverride="4">
<!-- AnnouncePart -->
<BoxContainer Orientation="Vertical"
Margin="0 2">
<OptionButton Name="AlertLevelButton"
Access="Public"
ToolTip="{Loc 'cp14-guard-bell-alert-button'}"
StyleClasses="OpenRight"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>

View File

@@ -0,0 +1,86 @@
using System.Globalization;
using Content.Client.UserInterface.Controls;
using Content.Shared.CCVar;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Client._CP14.UserInterface
{
[GenerateTypedNameReferences]
public sealed partial class GuardBellMenu : FancyWindow
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;
public bool AlertLevelSelectable;
public string CurrentLevel = string.Empty;
public event Action<string>? OnAlertLevel;
public GuardBellMenu()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
AlertLevelButton.OnItemSelected += args =>
{
var metadata = AlertLevelButton.GetItemMetadata(args.Id);
if (metadata != null && metadata is string cast)
{
OnAlertLevel?.Invoke(cast);
}
};
AlertLevelButton.Disabled = !AlertLevelSelectable;
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
}
// The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
// If the current alert is unselectable, the only item in the alerts list will be
// the current alert. Otherwise, it will be the list of alerts, with the current alert
// selected.
public void UpdateAlertLevels(List<string>? alerts, string currentAlert)
{
AlertLevelButton.Clear();
if (alerts == null)
{
var name = currentAlert;
if (_loc.TryGetString($"cp14-alert-level-{currentAlert}", out var locName))
{
name = locName;
}
AlertLevelButton.AddItem(name);
AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, currentAlert);
}
else
{
foreach (var alert in alerts)
{
var name = alert;
if (_loc.TryGetString($"cp14-alert-level-{alert}", out var locName))
{
name = locName;
}
AlertLevelButton.AddItem(name);
AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, alert);
if (alert == currentAlert)
{
AlertLevelButton.Select(AlertLevelButton.ItemCount - 1);
}
}
}
}
}
}

View File

@@ -18,7 +18,8 @@ public sealed class AlertLevelSystem : EntitySystem
[Dependency] private readonly StationSystem _stationSystem = default!;
// Until stations are a prototype, this is how it's going to have to be.
public const string DefaultAlertLevelSet = "stationAlerts";
// public const string DefaultAlertLevelSet = "stationAlerts"; // OLD VANILA. Changed by CP14.
public const string DefaultAlertLevelSet = "CP14TownAlerts";
public override void Initialize()
{
@@ -184,7 +185,8 @@ public sealed class AlertLevelSystem : EntitySystem
}
// The full announcement to be spat out into chat.
var announcementFull = Loc.GetString("alert-level-announcement", ("name", name), ("announcement", announcement));
// var announcementFull = Loc.GetString("alert-level-announcement", ("name", name), ("announcement", announcement)); // OLD VANILA. Changed by CP14.
var announcementFull = Loc.GetString("cp14-alert-level-announcement", ("name", name), ("announcement", announcement));
var playDefault = false;
if (playSound)

View File

@@ -0,0 +1,16 @@
# Attempted to keep the files in alphabetical order so its easier to audit.
# Finding individual authors is an unfeasible task. If you can reference the author please do so.
- files: ["safe-alert.ogg"]
license: "CC-BY-4.0"
copyright: "Created by kevp888"
source: "https://freesound.org/s/688445"
- files: ["minor-alert.ogg"]
license: "CC0-1.0"
copyright: "Created by Horrormarkus"
source: "https://freesound.org/s/659672"
- files: ["major-alert.ogg"]
license: "CC0-1.0"
copyright: "Created by Aeonomi"
source: "https://freesound.org/s/180329"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,10 @@
cp14-alert-level-announcement = Attention! Towns threat level is now {$name}! {$announcement}
cp14-alert-level-safe = Safe
cp14-alert-level-safe-announcement = There is no threat to the town. Town folk may return to their duties safely.
cp14-alert-level-minor = Minor
cp14-alert-level-minor-announcement = There is a minor threat to the town. Townsfolk should return to the town for their own safety. Guards are to be at their posts armed and combat ready.
cp14-alert-level-major = Major
cp14-alert-level-major-announcement = There is a major threat to the town. Everyone must return to the town and protect it.

View File

@@ -0,0 +1,2 @@
cp14-guard-bell-menu-title = Guard Bell
cp14-guard-bell-alert-button = Change the towns threat level.

View File

@@ -0,0 +1,10 @@
cp14-alert-level-announcement = Внимание! Уровень угрозы города теперь { $name }! { $announcement }
cp14-alert-level-safe = Безопасно
cp14-alert-level-safe-announcement = Угрозы городу нет. Горожане могут спокойно вернуться к своим обязанностям.
cp14-alert-level-minor = Незначительная угроза
cp14-alert-level-minor-announcement = Городу предстоит небольшая угроза. Горожанам рекомендуется быть внимательными и не покидать пределы города в темное время суток. Стража должна находиться на своих постах вооруженными и готовыми к бою.
cp14-alert-level-major = Большая угроза
cp14-alert-level-major-announcement = Городу предстоит большая угроза! Призываем всех жителей объединиться и подготовиться к защите своих домов и семей.

View File

@@ -0,0 +1,2 @@
cp14-guard-bell-menu-title = Колокол стражи
cp14-guard-bell-alert-button = Изменяет уровень угрозы города.

View File

@@ -0,0 +1,22 @@
- type: alertLevels
id: CP14TownAlerts
defaultLevel: safe
levels:
safe:
announcement: cp14-alert-level-safe-announcement
sound: /Audio/_CP14/Misc/safe-alert.ogg
color: Green
emergencyLightColor: LawnGreen
shuttleTime: 600
minor:
announcement: cp14-alert-level-minor-announcement
sound: /Audio/_CP14/Misc/minor-alert.ogg
color: DodgerBlue
emergencyLightColor: DodgerBlue
shuttleTime: 600
major:
announcement: cp14-alert-level-major-announcement
sound: /Audio/_CP14/Misc/major-alert.ogg
color: Red
emergencyLightColor: Red
shuttleTime: 600

View File

@@ -0,0 +1,20 @@
- type: entity
parent: BaseStructure
id: CP14GuardBell
name: guard bell
description: A bell used to set the appropriate alert level.
categories: [ ForkFiltered ]
components:
- type: Sprite
drawdepth: Mobs
sprite: _CP14/Structures/Specific/Guard/guard_bell.rsi
layers:
- state: base
- type: ActivatableUI
key: enum.CommunicationsConsoleUiKey.Key
- type: CommunicationsConsole
title: cp14-guard-bell-menu-title
- type: UserInterface
interfaces:
enum.CommunicationsConsoleUiKey.Key:
type: GuardBellBoundUserInterface

View File

@@ -5,7 +5,7 @@
- BaseStation
- BaseStationAllEventsEligible
- BaseStationJobsSpawning
- BaseStationAlertLevels #Checks fail without it
- CP14BaseTownAlerts
- BaseStationRecords # Required for lobby manifest + cryo leave
- CP14BaseStationCommonObjectives
- CP14BaseStationSalary
@@ -26,8 +26,15 @@
salary:
CP14Guard: 550
- type: entity
id: CP14BaseTownAlerts
abstract: true
components:
- type: AlertLevel
alertLevelPrototype: CP14TownAlerts
- type: entity
id: CP14BaseStationDemiplaneMap
abstract: true
components:
- type: CP14StationDemiplaneMap
- type: CP14StationDemiplaneMap

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,14 @@
{
"version": 1,
"license": "All right reserved",
"copyright": "Created by Militore for CrystallEdge",
"size": {
"x": 32,
"y": 48
},
"states": [
{
"name": "base"
}
]
}