Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Content.Server._Arcane.StationEvents.Events;
using Content.Shared.Dataset;
using Robust.Shared.Prototypes;

namespace Content.Server._Arcane.StationEvents.Components;

[RegisterComponent]
[Access(typeof(WackyLawRule))]
public sealed partial class WackyLawComponent : Component
{
/// <summary>
/// Dataset of objects for event "wacky law"
/// </summary>
[DataField]
public ProtoId<DatasetPrototype> ItemDataset = "ArcaneItem";

/// <summary>
/// Beverage Dataset for event "wacky law" (use text instead of IDs)
/// </summary>
[DataField]
public ProtoId<DatasetPrototype> HalfProhibitionDataset = "ArcaneHalfProhibition";
Comment on lines +14 to +21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Подключите поля датасетов к исполнению или удалите их.

ItemDataset и HalfProhibitionDataset объявлены как настраиваемые [DataField], но WackyLawRule.Started их не читает. Для законов с предметом и напитком система получает ArcaneItem и ArcaneHalfProhibition из ArcaneLaws. Поэтому переопределение этих полей в прототипе игрового правила не действует.

Выберите один контракт: передавайте эти поля в систему или удалите неиспользуемые поля.

Контракт сверен с WackyLawRule.Started и Resources/Prototypes/_Arcane/Datasets/Events/wackylaw.yml.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Content.Server/_Arcane/StationEvents/Components/WackyLawComponent.cs` around
lines 14 - 21, Исправьте контракт между ItemDataset и HalfProhibitionDataset и
методом WackyLawRule.Started: либо передавайте настроенные поля датасетов в
выполнение правила вместо захардкоженных значений из ArcaneLaws, либо удалите
оба неиспользуемых [DataField]. Сохраните единый источник конфигурации, чтобы
переопределение датасетов в прототипе действительно влияло на событие.


/// <summary>
/// Department Dataset for event "wacky law"
/// </summary>
[DataField]
public ProtoId<DatasetPrototype> DepartmentDataset = "ArcaneDepartments";

/// <summary>
/// Laws dataset for event "wacky law"
/// </summary>
[DataField]
public ProtoId<DatasetPrototype> LawsDataset = "ArcaneLaws";

}
97 changes: 97 additions & 0 deletions Content.Server/_Arcane/StationEvents/Events/WackyLawRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

using System.Collections.Generic;
using Content.Server.Fax;
using Content.Server.StationEvents.Events;
using Content.Server._Arcane.StationEvents.Components;
using Content.Shared.Dataset;
using Content.Shared.Fax.Components;
using Content.Shared.GameTicking.Components;
using Content.Shared.Paper;
using Content.Shared.Roles;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;

namespace Content.Server._Arcane.StationEvents.Events;

/// <summary>
/// An event related to a strange law from the Central Command. I tried to set it up so that new laws could be added without having to edit the code. The dataset file contains instructions.
/// </summary>
public sealed class WackyLawRule : StationEventSystem<WackyLawComponent>
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly FaxSystem _fax = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;

private string GetDepartmentText(string department)
{
if (department == "All")
return Loc.GetString("wacky-law-department-all");

var name = _proto.TryIndex<DepartmentPrototype>(department, out var dept)
? Loc.GetString(dept.Name)
: department;

return Loc.GetString(name);
}
Comment on lines +27 to +37

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Не локализуйте имя отдела второй раз.

На строке 33 Loc.GetString(dept.Name) уже возвращает отображаемое имя отдела. Строка 36 передаёт этот текст как идентификатор в Loc.GetString, поэтому законы для любого отдела, кроме All, не получат корректное имя.

Верните первое локализованное значение. Затем оберните его через wacky-law-department-one.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Content.Server/_Arcane/StationEvents/Events/WackyLawRule.cs` around lines 27
- 37, Update GetDepartmentText so the department prototype name is localized
once via Loc.GetString(dept.Name), then returned through the
wacky-law-department-one wrapper; do not pass the already localized text back
into Loc.GetString. Preserve the existing wacky-law-department-all handling and
fallback to the raw department identifier.

private string PickRandomEntityName(ProtoId<DatasetPrototype> datasetId)
{
var dataset = _proto.Index(datasetId);
var protoId = _random.Pick(dataset.Values);

if (_proto.TryIndex<EntityPrototype>(protoId, out var proto) && !string.IsNullOrEmpty(proto.Name))
return Loc.GetString(proto.Name);

return protoId;
}

protected override void Started(EntityUid uid, WackyLawComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);

if (!TryGetRandomStation(out var station))
return;
var lawEntry = _random.Pick(_proto.Index(component.LawsDataset).Values);
var lawParts = lawEntry.Split('|', 2);
var contentLoc = lawParts[0];
var itemName = string.Empty;
if (lawParts.Length == 2 && _proto.TryIndex<DatasetPrototype>(lawParts[1], out _))
itemName = PickRandomEntityName(lawParts[1]);

var departmentEntry = _random.Pick(_proto.Index(component.DepartmentDataset).Values);
var departmentText = GetDepartmentText(departmentEntry);
var content = Loc.GetString(
contentLoc,
("station", MetaData(station.Value).EntityName),
("item", itemName),
("department", departmentText)
);

var documentRelease = new FaxPrintout(
content,
"Указ Центрального Командования",
label: null,
prototypeId: "PaperOffice",
stampState: "paper_stamp-centcom",
stampedBy: new List<StampDisplayInfo>
{
new()
{
StampedName = Loc.GetString("stamp-component-stamped-name-centcom"),
StampedColor = Color.Green,
}
},
locked: true
);

var faxQuery = EntityQueryEnumerator<FaxMachineComponent>();
while (faxQuery.MoveNext(out var faxUid, out var faxComp))
{
if (!faxComp.ReceiveAllStationGoals && !(faxComp.ReceiveStationGoal && StationSystem.GetOwningStation(faxUid) == station.Value))
continue;

_fax.Receive(faxUid, documentRelease, null, faxComp);
}
}
}
83 changes: 83 additions & 0 deletions Resources/Locale/ru-RU/_Arcane/station-events/wacky-law.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Locales must contain { $station}, { $item}, { $department}

station-event-wacky-law-announcement = Внимание, экипаж. Центральное Командование издало новый указ для вашей станции. Копия документа выслана на факс Капитана станции. Слава НТ.

wacky-law-paper-name = указ Центрального Командования

wacky-law-department-all = весь персонал станции

# compulsion to wear an item

wacky-law-content-force-item = ███░███░░░░██░░░░
░██░████░░░██░░░░ [head=3]Бланк документа[/head]
░░█░██░██░░██░█░░ [head=3]НаноТрейзен[/head]
░░░░██░░██░██░██░ [bold]ЦК-КОМ[/bold]
░░░░██░░░████░
================================================[bold]
УКАЗ
================================================[/bold]
Настоящим указом Центральное Командование ПРЕДПИСЫВАЕТ:
С момента получения документа сотрудники станции { $station } ОБЯЗАНЫ носить при себе следующий предмет: [bold]{ $item }[/bold].
Данный указ распространяется на { $department }
Отсутствие указанного предмета при себе приравнивается к нарушению корпоративного законодательства и подлежит рассмотрению службой безопасности.
Контроль исполнения возлагается на капитана и службу безопасности станции. Указ вступает в силу немедленно.
Слава НаноТрейзен!
================================================[italic]
Место для печати[/italic]

# Prohibition on Carrying an Item

wacky-law-content-ban-item = ███░███░░░░██░░░░
░██░████░░░██░░░░ [head=3]Бланк документа[/head]
░░█░██░██░░██░█░░ [head=3]НаноТрейзен[/head]
░░░░██░░██░██░██░ [bold]ЦК-КОМ[/bold]
░░░░██░░░████░
================================================[bold]
УКАЗ
================================================[/bold]
Настоящим указом Центральное Командование ЗАПРЕЩАЕТ:
С момента получения документа ношение, хранение и использование предмета [bold]{ $item }[/bold] на территории станции { $station } строго воспрещается.
Данный указ распространяется на { $department }
Все обнаруженные экземпляры подлежат изъятию службой безопасности и утилизации.
Контроль исполнения возлагается на капитана и службу безопасности станции. Указ вступает в силу немедленно.
Слава НаноТрейзен!
================================================[italic]
Место для печати[/italic]

# semi-dry law (ban on alcohol at the bar)

wacky-law-content-half-prohibition = ███░███░░░░██░░░░
░██░████░░░██░░░░ [head=3]Бланк документа[/head]
░░█░██░██░░██░█░░ [head=3]НаноТрейзен[/head]
░░░░██░░██░██░██░ [bold]ЦК-КОМ[/bold]
░░░░██░░░████░
================================================[bold]
УКАЗ
================================================[/bold]
В рамках программы повышения трудоспособности экипажа Центральное Командование вводит ЧАСТИЧНЫЙ запрет:
Барменам воспрещается подавать сотрудникам { $department } { $item }
Нарушители подлежат взысканию по корпоративному законодательству.
Указ вступает в силу немедленно.
Слава НаноТрейзен!
================================================[italic]
Место для печати[/italic]

# Prohibition

wacky-law-content-full-prohibition = ███░███░░░░██░░░░
░██░████░░░██░░░░ [head=3]Бланк документа[/head]
░░█░██░██░░██░█░░ [head=3]НаноТрейзен[/head]
░░░░██░░██░██░██░ [bold]ЦК-КОМ[/bold]
░░░░██░░░████░
================================================[bold]
УКАЗ
================================================[/bold]
В целях поддержания трудовой дисциплины Центральное Командование вводит СУХОЙ ЗАКОН:
С момента получения документа хранение, распитие, продажа и передача любых алкогольных напитков на территории станции { $station } строго запрещается до конца смены.
Бар и иные точки раздачи алкоголя подлежат чуткому надзору сил безопасности станции.
Нарушители задерживаются службой безопасности. Указ вступает в силу немедленно.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Слава НаноТрейзен!
================================================[italic]
Место для печати[/italic]
Comment on lines +3 to +81

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Завершите локализацию события.

Событие содержит только ru-RU строки, raw-значения напитков и raw-заголовок документа. На сервере с en-US идентификаторы законов не имеют перевода, а напитки всегда выводятся по-русски.

  • Resources/Locale/ru-RU/_Arcane/station-events/wacky-law.ftl#L3-L83: добавьте совпадающие ключи в Resources/Locale/en-US/_Arcane/station-events/wacky-law.ftl.
  • Resources/Prototypes/_Arcane/Datasets/Events/wackylaw.yml#L50-L61: замените отображаемые названия напитков на FTL-идентификаторы.
  • Content.Server/_Arcane/StationEvents/Events/WackyLawRule.cs#L38-L46: локализуйте выбранный идентификатор напитка через Loc.GetString.
  • Content.Server/_Arcane/StationEvents/Events/WackyLawRule.cs#L71-L85: используйте Loc.GetString("wacky-law-paper-name") вместо raw-строки.

As per coding guidelines: “Every player-facing string must be localized.”

📍 Affects 3 files
  • Resources/Locale/ru-RU/_Arcane/station-events/wacky-law.ftl#L3-L83 (this comment)
  • Resources/Prototypes/_Arcane/Datasets/Events/wackylaw.yml#L50-L61
  • Content.Server/_Arcane/StationEvents/Events/WackyLawRule.cs#L38-L46
  • Content.Server/_Arcane/StationEvents/Events/WackyLawRule.cs#L71-L85
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Resources/Locale/ru-RU/_Arcane/station-events/wacky-law.ftl` around lines 3 -
83, Complete localization of the Wacky Law event: add matching English FTL keys
for the Russian entries in
Resources/Locale/ru-RU/_Arcane/station-events/wacky-law.ftl (anchor, lines
3-83); replace raw drink names with FTL identifiers in
Resources/Prototypes/_Arcane/Datasets/Events/wackylaw.yml (lines 50-61);
localize the selected drink identifier via Loc.GetString in WackyLawRule.cs
(lines 38-46); and obtain the paper title through
Loc.GetString("wacky-law-paper-name") instead of a raw string in WackyLawRule.cs
(lines 71-85).

Source: Coding guidelines



18 changes: 18 additions & 0 deletions Resources/Prototypes/GameRules/events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
- id: FloorGoblinMidRound # Goobstation
- id: ClownGoblinMigration # Goobstation - New Midrounds
# - id: SantaClausSpawn # Goobstation, remove after new year
- id: WackyCentComLaw # Arcane

- type: entityTable
id: BasicAntagEventsTable
Expand Down Expand Up @@ -1096,3 +1097,20 @@
min: 1
max: 1
pickPlayer: false

# Arcane-start
- type: entity
id: WackyCentComLaw
parent: BaseGameRule
components:
- type: StationEvent
startAnnouncement: station-event-wacky-law-announcement
weight: 5
duration: 1
earliestStart: 10
reoccurrenceDelay: 30
eventType: Chaotic
- type: GameRule
chaosScore: 50
- type: WackyLaw
# Arcane-end
82 changes: 82 additions & 0 deletions Resources/Prototypes/_Arcane/Datasets/Events/wackylaw.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# To add a new rule, you need to specify its locale from the FTL and the dataset that will be used.
# All of this needs to be specified in “ArcaneLaws”; if the law does not specify the use of any particular dataset, just leave the locale as is.
# To increase the hit rate, add it to the dataset again
Comment thread
4Gebura marked this conversation as resolved.

- type: dataset
id: ArcaneItem
values:
- ClothingUniformJumpsuitColorTeal
- ClothingSocksAssBlastUSAThigh
- ClothingHandsBDSMgloves
- ClothingJumpsuitBDSMress
- ClothingUniformJumpsuitTurtleneckWhite
- ClothingUniformJumpsuitColorWhite
- ClothingOuterHospitalGown
- ClothingHeadHatWitch
- ClothingUniformJumpskirtMaidLong
- ClothingOuterWinterRobo
- ClothingHandsGlovesCaptain
- ClothingUniformJumpsuitRoboticist
- ClothingUniformJumpsuitAviator
- ClothingCloakHOSRed
- ClothingShoesBootsWinterMed
- ClothingHandsGlovesNitrile
- ClothingEyesHudBeer
- ClothingSocksBeer
- ClothingUniformJumpskirtJanimaid
- ClothingBeltJanitor
- ClothingHandsGlovesJanitor
- ClothingHandsGlovesRobohands
- ClothingUniformJumpskirtMaidPink
- BlowPink
- BlowGreen
- BlowPurple
- PussyVulpaBlue
- PussyVulpaBlue
- OnaholeGreen
- SlimeDildo
- DogDildo
- ClothingWristsClockworkSlab
- ClothingNeckStoleChaplain
- ClothingSocksThinThigh
- ClothingShoesColorBlack
- ClothingSocksThigh
- ClothingSocksCandyCaneGreenThigh
- ClothingUnderwearPantiesCommie
- ClothingUnderwearPantiesFishnetLowerAlt

- type: dataset
id: ArcaneHalfProhibition
values:
- "Вермут"
- "Вино"
- "Виски"
- "Водка"
- "Джин"
- "Коньяк"
- "Кофейный ликёр"
- "Медовуха"
- "Пиво"
- "Ром"
- "Текила"
- "Эль"

- type: dataset
id: ArcaneDepartments
values:
- All
- Cargo
- Command
- Engineering
- Medical
- Science
- Security
- Service

- type: dataset
id: ArcaneLaws
values:
- "wacky-law-content-force-item|ArcaneItem"
- "wacky-law-content-ban-item|ArcaneItem"
- "wacky-law-content-half-prohibition|ArcaneHalfProhibition"
- "wacky-law-content-full-prohibition"
Loading