From 4951b7d2d5e85cce3c39b58d231de02355e3c2a4 Mon Sep 17 00:00:00 2001 From: portfiend <109661617+portfiend@users.noreply.github.com> Date: Fri, 16 Aug 2024 08:24:04 -0400 Subject: [PATCH 01/14] Courier performancer tracker (#1472) * add MailMetricsCartridge prototype using the CrimeAssist UI until i make the courier performance ui * add sprite for mail courier cartridge * Add MailMetricUI YAYYYYY IT WORKS UI Contents pending * Mail earnings live update mailmetrics * LO can have mailmetrics too * Add rest of mail metrics Also removes some loggers * Add additional metrics to MailMetric Also fixes some bugs related to stat counting * MailMetric updates on mail added * change sprite credit name decided id rather be credited as Portfiend * display all mail numbers now * remove comment * style mailmetrics, add heading * mailmetric UI polish * fixed unopened mail counting bug oopsie * wtf is this import get out of here * move StationLogisticStats to BaseStationMail * FOUR SPACES sirry * fix: newlines * address reviews * address reviews SORRYYYY this is unexpectedly big * wtf * semicolon --------- Co-authored-by: byte <50130120+huckleton@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> --- .../Cartridges/MailMetricUi.cs | 28 +++ .../Cartridges/MailMetricUiFragment.xaml | 183 ++++++++++++++++++ .../Cartridges/MailMetricUiFragment.xaml.cs | 105 ++++++++++ .../StationLogisticStatsDatabaseComponent.cs | 14 ++ .../Cargo/Systems/LogisticStatsSystem.cs | 68 +++++++ .../MailMetricsCartridgeComponent.cs | 11 ++ .../Cartridges/MailMetricsCartridgeSystem.cs | 83 ++++++++ Content.Server/Nyanotrasen/Mail/MailSystem.cs | 61 +++++- .../Cartridges/MailMetricUiState.cs | 50 +++++ .../deltav/cartridge-loader/cartridges.ftl | 13 ++ .../Entities/Objects/Devices/cartridges.yml | 21 ++ .../Entities/Objects/Devices/pda.yml | 6 + .../Nyanotrasen/Entities/Stations/mail.yml | 1 + .../Devices/cartridge.rsi/cart-mail.png | Bin 0 -> 242 bytes .../Objects/Devices/cartridge.rsi/meta.json | 7 +- 15 files changed, 647 insertions(+), 4 deletions(-) create mode 100644 Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs create mode 100644 Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml create mode 100644 Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs create mode 100644 Content.Server/DeltaV/Cargo/Components/StationLogisticStatsDatabaseComponent.cs create mode 100644 Content.Server/DeltaV/Cargo/Systems/LogisticStatsSystem.cs create mode 100644 Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs create mode 100644 Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs create mode 100644 Content.Shared/DeltaV/CartridgeLoader/Cartridges/MailMetricUiState.cs create mode 100644 Resources/Textures/DeltaV/Objects/Devices/cartridge.rsi/cart-mail.png diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs new file mode 100644 index 00000000000..f1688c8dab4 --- /dev/null +++ b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs @@ -0,0 +1,28 @@ +using Robust.Client.UserInterface; +using Content.Client.UserInterface.Fragments; +using Content.Shared.CartridgeLoader.Cartridges; + +namespace Content.Client.DeltaV.CartridgeLoader.Cartridges; + +public sealed partial class MailMetricUi : UIFragment +{ + private MailMetricUiFragment? _fragment; + + public override Control GetUIFragmentRoot() + { + return _fragment!; + } + + public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner) + { + _fragment = new MailMetricUiFragment(); + } + + public override void UpdateState(BoundUserInterfaceState state) + { + if (state is MailMetricUiState cast) + { + _fragment?.UpdateState(cast); + } + } +} diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml new file mode 100644 index 00000000000..c31a1c6063d --- /dev/null +++ b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs new file mode 100644 index 00000000000..d1560b53668 --- /dev/null +++ b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs @@ -0,0 +1,105 @@ +using System.Runtime.CompilerServices; +using Content.Shared.CartridgeLoader.Cartridges; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.DeltaV.CartridgeLoader.Cartridges; + +[GenerateTypedNameReferences] +public sealed partial class MailMetricUiFragment : BoxContainer +{ + + private OpenedMailPercentGrade? _successGrade; + + public MailMetricUiFragment() + { + RobustXamlLoader.Load(this); + + // This my way of adding multiple classes to a XAML control. + // Haha Batman I'm going to blow up Gotham City + OpenedMailCount.StyleClasses.Add("Good"); + OpenedMailSpesos.StyleClasses.Add("Good"); + TamperedMailCount.StyleClasses.Add("Danger"); + TamperedMailSpesos.StyleClasses.Add("Danger"); + ExpiredMailCount.StyleClasses.Add("Danger"); + ExpiredMailSpesos.StyleClasses.Add("Danger"); + DamagedMailCount.StyleClasses.Add("Danger"); + DamagedMailSpesos.StyleClasses.Add("Danger"); + UnopenedMailCount.StyleClasses.Add("Caution"); + } + + public void UpdateState(MailMetricUiState state) + { + UpdateTextLabels(state); + UpdateSuccessGrade(state); + } + + public void UpdateTextLabels(MailMetricUiState state) + { + var stats = state.Metrics; + + OpenedMailCount.Text = stats.OpenedCount.ToString(); + OpenedMailSpesos.Text = stats.Earnings.ToString(); + TamperedMailCount.Text = stats.TamperedCount.ToString(); + TamperedMailSpesos.Text = stats.TamperedLosses.ToString(); + ExpiredMailCount.Text = stats.ExpiredCount.ToString(); + ExpiredMailSpesos.Text = stats.ExpiredLosses.ToString(); + DamagedMailCount.Text = stats.DamagedCount.ToString(); + DamagedMailSpesos.Text = stats.DamagedLosses.ToString(); + UnopenedMailCount.Text = state.UnopenedMailCount.ToString(); + TotalMailCount.Text = state.TotalMail.ToString(); + TotalMailSpesos.Text = stats.TotalIncome.ToString(); + SuccessRateCounts.Text = Loc.GetString("mail-metrics-progress", + ("opened", stats.OpenedCount), + ("total", state.TotalMail)); + SuccessRatePercent.Text = Loc.GetString("mail-metrics-progress-percent", + ("successRate", state.SuccessRate)); + } + + public void UpdateSuccessGrade(MailMetricUiState state) + { + var previousGrade = _successGrade; + _successGrade = GetSuccessRateGrade(state.SuccessRate); + + // No need to update if they're the same + if (previousGrade == _successGrade) + return; + + var previousGradeClass = GetClassForGrade(previousGrade); + if (previousGradeClass != string.Empty) + { + SuccessRatePercent.StyleClasses.Remove(previousGradeClass); + } + + SuccessRatePercent.StyleClasses.Add(GetClassForGrade(_successGrade)); + } + + private static OpenedMailPercentGrade GetSuccessRateGrade(double successRate) + { + return successRate switch + { + > 75 => OpenedMailPercentGrade.Good, + > 50 => OpenedMailPercentGrade.Average, + _ => OpenedMailPercentGrade.Bad, + }; + } + + private string GetClassForGrade(OpenedMailPercentGrade? grade) + { + return grade switch + { + OpenedMailPercentGrade.Good => "Good", + OpenedMailPercentGrade.Average => "Caution", + OpenedMailPercentGrade.Bad => "Danger", + _ => string.Empty, + }; + } +} + +enum OpenedMailPercentGrade +{ + Good, + Average, + Bad +} diff --git a/Content.Server/DeltaV/Cargo/Components/StationLogisticStatsDatabaseComponent.cs b/Content.Server/DeltaV/Cargo/Components/StationLogisticStatsDatabaseComponent.cs new file mode 100644 index 00000000000..2890d54025a --- /dev/null +++ b/Content.Server/DeltaV/Cargo/Components/StationLogisticStatsDatabaseComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Cargo; +using Content.Shared.CartridgeLoader.Cartridges; + +namespace Content.Server.DeltaV.Cargo.Components; + +/// +/// Added to the abstract representation of a station to track stats related to mail delivery and income +/// +[RegisterComponent, Access(typeof(SharedCargoSystem))] +public sealed partial class StationLogisticStatsComponent : Component +{ + [DataField] + public MailStats Metrics { get; set; } +} \ No newline at end of file diff --git a/Content.Server/DeltaV/Cargo/Systems/LogisticStatsSystem.cs b/Content.Server/DeltaV/Cargo/Systems/LogisticStatsSystem.cs new file mode 100644 index 00000000000..e18bd4c7cf2 --- /dev/null +++ b/Content.Server/DeltaV/Cargo/Systems/LogisticStatsSystem.cs @@ -0,0 +1,68 @@ +using Content.Server.DeltaV.Cargo.Components; +using Content.Shared.Cargo; +using JetBrains.Annotations; + +namespace Content.Server.DeltaV.Cargo.Systems; + +public sealed partial class LogisticStatsSystem : SharedCargoSystem +{ + public override void Initialize() + { + base.Initialize(); + } + + [PublicAPI] + public void AddOpenedMailEarnings(EntityUid uid, StationLogisticStatsComponent component, int earnedMoney) + { + component.Metrics = component.Metrics with + { + Earnings = component.Metrics.Earnings + earnedMoney, + OpenedCount = component.Metrics.OpenedCount + 1 + }; + UpdateLogisticsStats(uid); + } + + [PublicAPI] + public void AddExpiredMailLosses(EntityUid uid, StationLogisticStatsComponent component, int lostMoney) + { + component.Metrics = component.Metrics with + { + ExpiredLosses = component.Metrics.ExpiredLosses + lostMoney, + ExpiredCount = component.Metrics.ExpiredCount + 1 + }; + UpdateLogisticsStats(uid); + } + + [PublicAPI] + public void AddDamagedMailLosses(EntityUid uid, StationLogisticStatsComponent component, int lostMoney) + { + component.Metrics = component.Metrics with + { + DamagedLosses = component.Metrics.DamagedLosses + lostMoney, + DamagedCount = component.Metrics.DamagedCount + 1 + }; + UpdateLogisticsStats(uid); + } + + [PublicAPI] + public void AddTamperedMailLosses(EntityUid uid, StationLogisticStatsComponent component, int lostMoney) + { + component.Metrics = component.Metrics with + { + TamperedLosses = component.Metrics.TamperedLosses + lostMoney, + TamperedCount = component.Metrics.TamperedCount + 1 + }; + UpdateLogisticsStats(uid); + } + + private void UpdateLogisticsStats(EntityUid uid) => RaiseLocalEvent(new LogisticStatsUpdatedEvent(uid)); +} + +public sealed class LogisticStatsUpdatedEvent : EntityEventArgs +{ + public EntityUid Station; + public LogisticStatsUpdatedEvent(EntityUid station) + { + Station = station; + } +} diff --git a/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs b/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs new file mode 100644 index 00000000000..11a6c5c5bb1 --- /dev/null +++ b/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Server.DeltaV.CartridgeLoader.Cartridges; + +[RegisterComponent, Access(typeof(MailMetricsCartridgeSystem))] +public sealed partial class MailMetricsCartridgeComponent : Component +{ + /// + /// Station entity keeping track of logistics stats + /// + [DataField] + public EntityUid? Station; +} diff --git a/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs b/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs new file mode 100644 index 00000000000..905e3854ee8 --- /dev/null +++ b/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs @@ -0,0 +1,83 @@ +using Content.Server.DeltaV.Cargo.Components; +using Content.Server.DeltaV.Cargo.Systems; +using Content.Server.Station.Systems; +using Content.Server.CartridgeLoader; +using Content.Shared.CartridgeLoader; +using Content.Shared.CartridgeLoader.Cartridges; +using Content.Server.Mail.Components; + +namespace Content.Server.DeltaV.CartridgeLoader.Cartridges; + +public sealed class MailMetricsCartridgeSystem : EntitySystem +{ + [Dependency] private readonly CartridgeLoaderSystem _cartridgeLoader = default!; + [Dependency] private readonly StationSystem _station = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUiReady); + SubscribeLocalEvent(OnLogisticsStatsUpdated); + SubscribeLocalEvent(OnMapInit); + } + + private void OnUiReady(Entity ent, ref CartridgeUiReadyEvent args) + { + UpdateUI(ent, args.Loader); + } + + private void OnLogisticsStatsUpdated(LogisticStatsUpdatedEvent args) + { + UpdateAllCartridges(args.Station); + } + + private void OnMapInit(EntityUid uid, MailComponent mail, MapInitEvent args) + { + if (_station.GetOwningStation(uid) is { } station) + UpdateAllCartridges(station); + } + + private void UpdateAllCartridges(EntityUid station) + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp, out var cartridge)) + { + if (cartridge.LoaderUid is not { } loader || comp.Station != station) + continue; + UpdateUI((uid, comp), loader); + } + } + + private void UpdateUI(Entity ent, EntityUid loader) + { + if (_station.GetOwningStation(loader) is { } station) + ent.Comp.Station = station; + + if (!TryComp(ent.Comp.Station, out var logiStats)) + return; + + // Get station's logistic stats + var unopenedMailCount = GetUnopenedMailCount(ent.Comp.Station); + + // Send logistic stats to cartridge client + var state = new MailMetricUiState(logiStats.Metrics, unopenedMailCount); + _cartridgeLoader.UpdateCartridgeUiState(loader, state); + } + + + private int GetUnopenedMailCount(EntityUid? station) + { + var unopenedMail = 0; + + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var uid, out var comp)) + { + if (comp.IsLocked && _station.GetOwningStation(uid) == station) + unopenedMail++; + } + + return unopenedMail; + } +} diff --git a/Content.Server/Nyanotrasen/Mail/MailSystem.cs b/Content.Server/Nyanotrasen/Mail/MailSystem.cs index 05cd0c88a72..afbc1f0c82f 100644 --- a/Content.Server/Nyanotrasen/Mail/MailSystem.cs +++ b/Content.Server/Nyanotrasen/Mail/MailSystem.cs @@ -12,6 +12,7 @@ using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.Chemistry.EntitySystems; using Content.Server.Damage.Components; +using Content.Server.DeltaV.Cargo.Components; using Content.Server.Destructible; using Content.Server.Destructible.Thresholds; using Content.Server.Destructible.Thresholds.Behaviors; @@ -53,6 +54,7 @@ using Content.Shared.Tag; using Robust.Shared.Audio.Systems; using Timer = Robust.Shared.Timing.Timer; +using Content.Server.DeltaV.Cargo.Systems; namespace Content.Server.Mail { @@ -78,6 +80,9 @@ public sealed class MailSystem : EntitySystem [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly MetaDataSystem _metaDataSystem = default!; + // DeltaV - system that keeps track of mail and cargo stats + [Dependency] private readonly LogisticStatsSystem _logisticsStatsSystem = default!; + private ISawmill _sawmill = default!; public override void Initialize() @@ -222,6 +227,13 @@ private void OnAfterInteractUsing(EntityUid uid, MailComponent component, AfterI } } + // DeltaV - Add earnings to logistic stats + ExecuteForEachLogisticsStats(uid, (station, logisticStats) => + { + _logisticsStatsSystem.AddOpenedMailEarnings(station, + logisticStats, + component.IsProfitable ? component.Bounty : 0); + }); UnlockMail(uid, component); if (!component.IsProfitable) @@ -241,7 +253,6 @@ private void OnAfterInteractUsing(EntityUid uid, MailComponent component, AfterI continue; _cargoSystem.UpdateBankAccount(station, account, component.Bounty); - return; } } @@ -306,7 +317,17 @@ public void PenalizeStationFailedDelivery(EntityUid uid, MailComponent component private void OnDestruction(EntityUid uid, MailComponent component, DestructionEventArgs args) { if (component.IsLocked) + { + // DeltaV - Tampered mail recorded to logistic stats + ExecuteForEachLogisticsStats(uid, (station, logisticStats) => + { + _logisticsStatsSystem.AddTamperedMailLosses(station, + logisticStats, + component.IsProfitable ? component.Penalty : 0); + }); + PenalizeStationFailedDelivery(uid, component, "mail-penalty-lock"); + } if (component.IsEnabled) OpenMail(uid, component); @@ -335,7 +356,17 @@ private void OnBreak(EntityUid uid, MailComponent component, BreakageEventArgs a _appearanceSystem.SetData(uid, MailVisuals.IsBroken, true); if (component.IsFragile) + { + // DeltaV - Broken mail recorded to logistic stats + ExecuteForEachLogisticsStats(uid, (station, logisticStats) => + { + _logisticsStatsSystem.AddDamagedMailLosses(station, + logisticStats, + component.IsProfitable ? component.Penalty : 0); + }); + PenalizeStationFailedDelivery(uid, component, "mail-penalty-fragile"); + } } private void OnMailEmagged(EntityUid uid, MailComponent component, ref GotEmaggedEvent args) @@ -486,7 +517,18 @@ public void SetupMail(EntityUid uid, MailTeleporterComponent component, MailReci mailComp.priorityCancelToken = new CancellationTokenSource(); Timer.Spawn((int) component.priorityDuration.TotalMilliseconds, - () => PenalizeStationFailedDelivery(uid, mailComp, "mail-penalty-expired"), + () => + { + // DeltaV - Expired mail recorded to logistic stats + ExecuteForEachLogisticsStats(uid, (station, logisticStats) => + { + _logisticsStatsSystem.AddExpiredMailLosses(station, + logisticStats, + mailComp.IsProfitable ? mailComp.Penalty : 0); + }); + + PenalizeStationFailedDelivery(uid, mailComp, "mail-penalty-expired"); + }, mailComp.priorityCancelToken.Token); } @@ -713,6 +755,21 @@ private void UpdateMailTrashState(EntityUid uid, bool isTrash) { _appearanceSystem.SetData(uid, MailVisuals.IsTrash, isTrash); } + + // DeltaV - Helper function that executes for each StationLogisticsStatsComponent + // For updating MailMetrics stats + private void ExecuteForEachLogisticsStats(EntityUid uid, + Action action) + { + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var station, out var logisticStats)) + { + if (_stationSystem.GetOwningStation(uid) != station) + continue; + action(station, logisticStats); + } + } } public struct MailRecipient( diff --git a/Content.Shared/DeltaV/CartridgeLoader/Cartridges/MailMetricUiState.cs b/Content.Shared/DeltaV/CartridgeLoader/Cartridges/MailMetricUiState.cs new file mode 100644 index 00000000000..69506f5d0c2 --- /dev/null +++ b/Content.Shared/DeltaV/CartridgeLoader/Cartridges/MailMetricUiState.cs @@ -0,0 +1,50 @@ +using Content.Shared.Security; +using Robust.Shared.Serialization; + +namespace Content.Shared.CartridgeLoader.Cartridges; + +[Serializable, NetSerializable] +public sealed class MailMetricUiState : BoundUserInterfaceState +{ + public readonly MailStats Metrics; + public int UnopenedMailCount { get; } + public int TotalMail { get; } + public double SuccessRate { get; } + + public MailMetricUiState(MailStats metrics, int unopenedMailCount) + { + Metrics = metrics; + UnopenedMailCount = unopenedMailCount; + TotalMail = metrics.TotalMail(unopenedMailCount); + SuccessRate = metrics.SuccessRate(unopenedMailCount); + } +} + +[DataDefinition] +[Serializable, NetSerializable] +public partial record struct MailStats +{ + public int Earnings { get; init; } + public int DamagedLosses { get; init; } + public int ExpiredLosses { get; init; } + public int TamperedLosses { get; init; } + public int OpenedCount { get; init; } + public int DamagedCount { get; init; } + public int ExpiredCount { get; init; } + public int TamperedCount { get; init; } + + public readonly int TotalMail(int unopenedCount) + { + return OpenedCount + unopenedCount; + } + + public readonly int TotalIncome => Earnings + DamagedLosses + ExpiredLosses + TamperedLosses; + + public readonly double SuccessRate(int unopenedCount) + { + var totalMail = TotalMail(unopenedCount); + return (totalMail > 0) + ? Math.Round((double)OpenedCount / totalMail * 100, 2) + : 0; + } +} \ No newline at end of file diff --git a/Resources/Locale/en-US/deltav/cartridge-loader/cartridges.ftl b/Resources/Locale/en-US/deltav/cartridge-loader/cartridges.ftl index 9b4c59d001d..ede1a36b8ee 100644 --- a/Resources/Locale/en-US/deltav/cartridge-loader/cartridges.ftl +++ b/Resources/Locale/en-US/deltav/cartridge-loader/cartridges.ftl @@ -118,3 +118,16 @@ crime-assist-sophont-explanation = A sophont is described as any entity with the • [bold]Sentience[/bold]: the entity has the capacity to process an emotion or lack thereof, or at a minimum the ability to recognise its own pain. • [bold]Self-awareness[/bold]: the entity is capable of altering its behaviour in a reasonable fashion as a result of stimuli, or at a minimum is capable of recognising its own sapience and sentience. Any sophont is considered a legal person, regardless of origin or prior cognitive status. Much like any other intelligent organic, a sophont may press charges against crew and be tried for crimes. + +mail-metrics-program-name = MailMetrics +mail-metrics-header = Income from Mail Deliveries +mail-metrics-opened = Earnings (Opened) +mail-metrics-expired = Losses (Expired) +mail-metrics-damaged = Losses (Damaged) +mail-metrics-tampered = Losses (Tampered) +mail-metrics-unopened = Unopened +mail-metrics-count-header = Packages +mail-metrics-money-header = Spesos +mail-metrics-total = Total +mail-metrics-progress = {$opened} out of {$total} packages opened! +mail-metrics-progress-percent = Success rate: {$successRate}% diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml index def215cee43..3cf293ff3c2 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml @@ -38,3 +38,24 @@ sprite: Objects/Weapons/Melee/stunbaton.rsi state: stunbaton_on - type: SecWatchCartridge + +- type: entity + parent: BaseItem + id: MailMetricsCartridge + name: mail metrics cartridge + description: A cartridge that tracks statistics related to mail deliveries. + components: + - type: Sprite + sprite: DeltaV/Objects/Devices/cartridge.rsi + state: cart-mail + - type: Icon + sprite: DeltaV/Objects/Devices/cartridge.rsi + state: cart-mail + - type: UIFragment + ui: !type:MailMetricUi + - type: MailMetricsCartridge + - type: Cartridge + programName: mail-metrics-program-name + icon: + sprite: Nyanotrasen/Objects/Specific/Mail/mail.rsi + state: icon diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 1a388997835..d9538f57649 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -358,6 +358,12 @@ accentVColor: "#a23e3e" - type: Icon state: pda-qm + - type: CartridgeLoader # DeltaV - MailMetrics courier tracker + preinstalled: + - CrewManifestCartridge + - NotekeeperCartridge + - NewsReaderCartridge + - MailMetricsCartridge - type: entity parent: BasePDA diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Stations/mail.yml b/Resources/Prototypes/Nyanotrasen/Entities/Stations/mail.yml index ceb87bbaa1b..b85cfef87ab 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Stations/mail.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Stations/mail.yml @@ -3,3 +3,4 @@ abstract: true components: - type: StationMailRouter + - type: StationLogisticStats # DeltaV - Tracks statistics related to mail and income diff --git a/Resources/Textures/DeltaV/Objects/Devices/cartridge.rsi/cart-mail.png b/Resources/Textures/DeltaV/Objects/Devices/cartridge.rsi/cart-mail.png new file mode 100644 index 0000000000000000000000000000000000000000..5734abb6fd1b5b7e9caefc5898adfe5d454c4759 GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCiji0(?STO$?F~(`I`6H?_1h^!In~*|X!ujVnM&R>^4*K#HRz$S?Rm1Tfrd z-Wv%N<1FxqEM{QfI|9OtQ?>b|fr9>?E{-7<{%_A)@*Pm%aS0U8|GwXlaSexe#+{{) z%A4a7Pju@={N>T;+IdTCt41fwJV}N#N@o~4X0236Sk-n=n&~O;Q+=%uqWqgp{9+A? Z-mhttJo_hemJQHo22WQ%mvv4FO#p~3QWO9H literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Objects/Devices/cartridge.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Devices/cartridge.rsi/meta.json index 293870d3a3b..4a4ba3352f8 100644 --- a/Resources/Textures/DeltaV/Objects/Devices/cartridge.rsi/meta.json +++ b/Resources/Textures/DeltaV/Objects/Devices/cartridge.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Timfa", + "copyright": "Timfa, plus edits by portfiend", "size": { "x": 32, "y": 32 @@ -9,6 +9,9 @@ "states": [ { "name": "cart-cri" + }, + { + "name": "cart-mail" } ] -} \ No newline at end of file +} From f6ad7ea68b1dd41fdf4a5be639e08bcc38db218a Mon Sep 17 00:00:00 2001 From: Adeinitas <147965189+adeinitas@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:14:05 -0300 Subject: [PATCH 02/14] Frontier Mail (#1652) * Does all the under the hood changes to mail components before I EVEN start thinking about MailSystem * Mail Handheld Rapid Parcel Delivery System (#974) * Mail RPDS * removed sizes, more items go in capsules * fixed error * capsule resprite, added it to service techfab * Update after upstream merge * glass * Update frontier.yml * tag fix --------- Co-authored-by: Dvir * Mail Buff (#1473) * MailUp * Update base_mail.yml * Update base_mail.yml * Update MailTeleporterComponent.cs * Update MailComponent.cs * Update base_mail.yml * Update base_mail.yml * Update Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml Sure Co-authored-by: Whatstone <166147148+whatston3@users.noreply.github.com> --------- Co-authored-by: Whatstone <166147148+whatston3@users.noreply.github.com> * Mail table rework (#1477) * Mail table, system for smoke prank * Format mail messages * DelayedItemSystem cleanup, more mail table entries * More mail table entries * Remove hoverbike from mail pool * Add large mail. FIXME: mail_large.rsi has no copyright info * Default mail isLarge to false, comment cleanup * More mail types * Add optional large mail flag to admin mailto cmd * mail_large copyright * admin cmd fix, new mail types, const cleanup * Mail: new components, weighting, a few new items * Fix merge conflict, add placeholder pipebomb mail * Format mail text, separate sword mail from knives * Mail: fix exp. welder ID, split up Dan's cigs * Fourth muffin, decrease captain's sabre chance * yaml fixes * Add ShowJobIcons component to mail hud * Reorganize mail items, add build-a-buddy mail * Build-a-Buddy fixes, slime & vulp versions, text * Reptillian->Reptilian * More signatures, label necrosol bottle, bigger emp * lowercase i * extra premium cigars, premium liquors * Cleanup * Fixups And Edits * Remove kendo hakama, jabroni comment, fix cigars * Platinum cigars, fix sprites * fix premium absinthe ID * Remove cyberpen, add BibleUserImplanter, ATV mail Also adjusts weights for TacticalMaid (missing a zero), Restraints (cut in half) * kendo mail order, more mail comments * Remove Nyano mail lists & parcels, move into _NF/ * True to true, cigars aren't fragile --------- Co-authored-by: Dvir Co-authored-by: Whatstone * Kills accidentally cherrypicked platinum cig, makes mail be sorted into 5 ymls again * THE MAIL TABLE!!!!! AHHHHHHHHHHHHHHHHHHHH * NUKES two UNNECCESSARY RANDOMLY PASTED BRACKETS FUCK YOU BUILD ERROR !!! EAT SHIT * a semicolon for good measure Adei versus the one silly * Fuck is this? Why is it in my mail? * Pro forgot values for two of the engineering mails :skull: * First pass to fix various mail bugs + editing of papers * obliterates a random S in a C# file, also returns the mail teleporter to how it was * Nukes the platinum cigar's YAML Since there's no intent for it to spawn in the mail, might as well. * Milon's Review Does some shit to the mail / courierdrobe and gets rid of string keys. Thanks Milon * Milon's Review 2, Electric Boogaloo * Various YAML fixes as I try to satisfy the Linter and fail * Fixes Mail.yml / If I get rid of the EMP china lake does it fix things? Let's find out! * Cleans up more C# at Milon's behest * TORTUGAAAAAAAAAAAAAAAAAAAA!!!! Why is this mapped in? * Revert "TORTUGAAAAAAAAAAAAAAAAAAAA!!!!" This reverts commit b1d415a7be6e5193fc77424b2847ff7babdf6cfa. * Migrations * Does a bit more fixing * Update Resources/Locale/en-US/_NF/mail/mail.ftl Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Signed-off-by: Adeinitas <147965189+adeinitas@users.noreply.github.com> * Update Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Signed-off-by: Adeinitas <147965189+adeinitas@users.noreply.github.com> * Fixes Mail Capsule / Creates frontierMigrations Blame Velcro for frontierMigrations. * Update Resources/Migrations/deltaMigrations.yml Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Signed-off-by: Adeinitas <147965189+adeinitas@users.noreply.github.com> * Rewords that one fucking comment I made 2 months ago about MIT / AGPL * Just gives the delayed smoke prank and delayed EMP effects the instant effect sprites * Where the fuck are these random curly braces from?? * An attempt to satisfy the Yaml Linter * Revert "Update Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl" This reverts commit 0ee3869d76cc7633be5fd26d303221e79ab04c77. * Revert "Update Resources/Locale/en-US/_NF/mail/mail.ftl" This reverts commit 29129df9d66079c9df0e4b1ccf5818b0cb230234. * Mail FTL fixes / I think I know what the linter wants * will this sprite be valid pretty please? * Does a first pass on noSpawn for all mails. ANOTHER COMMIT FOR THE PILE. * Unfucks noSpawn from the mail prototypes --------- Signed-off-by: Adeinitas <147965189+adeinitas@users.noreply.github.com> Co-authored-by: ErhardSteinhauer <65374927+ErhardSteinhauer@users.noreply.github.com> Co-authored-by: Dvir Co-authored-by: Dvir <39403717+dvir001@users.noreply.github.com> Co-authored-by: Whatstone <166147148+whatston3@users.noreply.github.com> Co-authored-by: Whatstone Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> --- .../Mail/Components/MailComponent.cs | 35 +- .../Components/MailTeleporterComponent.cs | 20 +- .../Nyanotrasen/Mail/MailCommands.cs | 20 +- Content.Server/Nyanotrasen/Mail/MailSystem.cs | 18 +- .../_NF/Mail/DelayedItemComponent.cs | 16 + Content.Server/_NF/Mail/DelayedItemSystem.cs | 56 + Content.Server/_NF/Mail/MailConstants.cs | 38 + Resources/Locale/en-US/_NF/mail/mail.ftl | 9 + .../en-US/{ => nyanotrasen}/Mail/mail.ftl | 11 +- Resources/Migrations/frontierMigrations.yml | 2 + .../Inventories/courierdrobe.yml | 2 + .../Entities/Objects/Specific/Mail/mail.yml | 1525 +++++++++++++++++ .../Objects/Specific/Mail/mail_civilian.yml | 89 +- .../Objects/Specific/Mail/mail_command.yml | 32 + .../Specific/Mail/mail_engineering.yml | 175 ++ .../Specific/Mail/mail_epistemology.yml | 10 - .../Objects/Specific/Mail/mail_medical.yml | 17 + .../Objects/Specific/Mail/mail_security.yml | 88 + .../Prototypes/DeltaV/Mail/mailDeliveries.yml | 145 ++ .../Fills/Vending/Inventories/maildrobe.yml | 2 + .../Objects/Specific/Mail/base_mail.yml | 18 +- .../Entities/Objects/Specific/Mail/mail.yml | 835 --------- .../Objects/Specific/Mail/mail_command.yml | 9 - .../Specific/Mail/mail_engineering.yml | 45 - .../Objects/Specific/Mail/mail_security.yml | 56 - .../Specific/Mail/mail_specific_items.yml | 169 -- .../Entities/Objects/Misc/mail_capsule.yml | 139 ++ .../Objects/Specific/Mail/base_mail_large.yml | 79 + .../Weapons/Guns/Launchers/launchers.yml | 24 + Resources/Prototypes/_NF/Mail/Items/boxes.yml | 212 +++ Resources/Prototypes/_NF/Mail/Items/misc.yml | 117 ++ Resources/Prototypes/_NF/Mail/Items/paper.yml | 483 ++++++ .../Prototypes/_NF/Recipes/Lathes/misc.yml | 15 + Resources/Prototypes/_NF/tags.yml | 56 + .../Misc/mail_capsule.rsi/icon-cash.png | Bin 0 -> 6954 bytes .../Misc/mail_capsule.rsi/icon-empty.png | Bin 0 -> 6506 bytes .../Misc/mail_capsule.rsi/icon-food.png | Bin 0 -> 7202 bytes .../Misc/mail_capsule.rsi/icon-mail.png | Bin 0 -> 6821 bytes .../Objects/Misc/mail_capsule.rsi/meta.json | 26 + .../Objects/Misc/mail_capsule.rsi/spent.png | Bin 0 -> 5618 bytes .../Specific/Mail/mail_large.rsi/broken.png | Bin 0 -> 246 bytes .../Specific/Mail/mail_large.rsi/fragile.png | Bin 0 -> 135 bytes .../Specific/Mail/mail_large.rsi/icon.png | Bin 0 -> 304 bytes .../Mail/mail_large.rsi/inhand-left.png | Bin 0 -> 324 bytes .../Mail/mail_large.rsi/inhand-right.png | Bin 0 -> 324 bytes .../Specific/Mail/mail_large.rsi/locked.png | Bin 0 -> 229 bytes .../Specific/Mail/mail_large.rsi/meta.json | 40 + .../Specific/Mail/mail_large.rsi/priority.png | Bin 0 -> 117 bytes .../Mail/mail_large.rsi/priority_inactive.png | Bin 0 -> 118 bytes .../Specific/Mail/mail_large.rsi/trash.png | Bin 0 -> 343 bytes .../Guns/Launchers/mail.rsi/bolt-open.png | Bin 0 -> 6861 bytes .../Launchers/mail.rsi/equipped-BACKPACK.png | Bin 0 -> 1472 bytes .../Guns/Launchers/mail.rsi/equipped-BELT.png | Bin 0 -> 1488 bytes .../Weapons/Guns/Launchers/mail.rsi/icon.png | Bin 0 -> 6855 bytes .../Guns/Launchers/mail.rsi/inhand-left.png | Bin 0 -> 1048 bytes .../Guns/Launchers/mail.rsi/inhand-right.png | Bin 0 -> 1060 bytes .../Weapons/Guns/Launchers/mail.rsi/meta.json | 33 + 57 files changed, 3482 insertions(+), 1184 deletions(-) create mode 100644 Content.Server/_NF/Mail/DelayedItemComponent.cs create mode 100644 Content.Server/_NF/Mail/DelayedItemSystem.cs create mode 100644 Content.Server/_NF/Mail/MailConstants.cs create mode 100644 Resources/Locale/en-US/_NF/mail/mail.ftl rename Resources/Locale/en-US/{ => nyanotrasen}/Mail/mail.ftl (91%) create mode 100644 Resources/Migrations/frontierMigrations.yml rename Resources/Prototypes/{Nyanotrasen => DeltaV}/Entities/Objects/Specific/Mail/mail_civilian.yml (71%) create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml rename Resources/Prototypes/{Nyanotrasen => DeltaV}/Entities/Objects/Specific/Mail/mail_epistemology.yml (74%) rename Resources/Prototypes/{Nyanotrasen => DeltaV}/Entities/Objects/Specific/Mail/mail_medical.yml (84%) create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml create mode 100644 Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml create mode 100644 Resources/Prototypes/_NF/Entities/Objects/Misc/mail_capsule.yml create mode 100644 Resources/Prototypes/_NF/Entities/Objects/Specific/Mail/base_mail_large.yml create mode 100644 Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml create mode 100644 Resources/Prototypes/_NF/Mail/Items/boxes.yml create mode 100644 Resources/Prototypes/_NF/Mail/Items/misc.yml create mode 100644 Resources/Prototypes/_NF/Mail/Items/paper.yml create mode 100644 Resources/Prototypes/_NF/Recipes/Lathes/misc.yml create mode 100644 Resources/Prototypes/_NF/tags.yml create mode 100644 Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-cash.png create mode 100644 Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-empty.png create mode 100644 Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-food.png create mode 100644 Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-mail.png create mode 100644 Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/meta.json create mode 100644 Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/spent.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/broken.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/fragile.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/icon.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/inhand-left.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/inhand-right.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/locked.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/meta.json create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/trash.png create mode 100644 Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/bolt-open.png create mode 100644 Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BACKPACK.png create mode 100644 Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BELT.png create mode 100644 Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/icon.png create mode 100644 Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-left.png create mode 100644 Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-right.png create mode 100644 Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json diff --git a/Content.Server/Nyanotrasen/Mail/Components/MailComponent.cs b/Content.Server/Nyanotrasen/Mail/Components/MailComponent.cs index 61d94bbad31..2b1c4e26e56 100644 --- a/Content.Server/Nyanotrasen/Mail/Components/MailComponent.cs +++ b/Content.Server/Nyanotrasen/Mail/Components/MailComponent.cs @@ -8,20 +8,17 @@ namespace Content.Server.Mail.Components [RegisterComponent] public sealed partial class MailComponent : SharedMailComponent { - [ViewVariables(VVAccess.ReadWrite)] - [DataField("recipient")] + [DataField] public string Recipient = "None"; - [ViewVariables(VVAccess.ReadWrite)] - [DataField("recipientJob")] + [DataField] public string RecipientJob = "None"; // Why do we not use LockComponent? // Because this can't be locked again, // and we have special conditions for unlocking, // and we don't want to add a verb. - [ViewVariables(VVAccess.ReadWrite)] - [DataField("isLocked")] + [DataField] public bool IsLocked = true; /// @@ -32,7 +29,7 @@ public sealed partial class MailComponent : SharedMailComponent /// This is useful for broken fragile packages and packages that were /// not delivered in time. /// - [DataField("isProfitable")] + [DataField] public bool IsProfitable = true; /// @@ -42,7 +39,7 @@ public sealed partial class MailComponent : SharedMailComponent /// This can be set to true in the YAML files for a mail delivery to /// always be Fragile, despite its contents. /// - [DataField("isFragile")] + [DataField] public bool IsFragile = false; /// @@ -58,43 +55,51 @@ public sealed partial class MailComponent : SharedMailComponent /// This can be set to true in the YAML files for a mail delivery to /// always be Priority. /// - [DataField("isPriority")] + [DataField] public bool IsPriority = false; + // Frontier Mail Port: large mail + /// + /// Whether this parcel is large. + /// + [DataField] + public bool IsLarge = false; + // End Frontier: large mail + /// /// What will be packaged when the mail is spawned. /// - [DataField("contents")] + [DataField] public List Contents = new(); /// /// The amount that cargo will be awarded for delivering this mail. /// - [DataField("bounty")] + [DataField] public int Bounty = 750; /// /// Penalty if the mail is destroyed. /// - [DataField("penalty")] + [DataField] public int Penalty = -250; /// /// The sound that's played when the mail's lock is broken. /// - [DataField("penaltySound")] + [DataField] public SoundSpecifier PenaltySound = new SoundPathSpecifier("/Audio/Machines/Nuke/angry_beep.ogg"); /// /// The sound that's played when the mail's opened. /// - [DataField("openSound")] + [DataField] public SoundSpecifier OpenSound = new SoundPathSpecifier("/Audio/Effects/packetrip.ogg"); /// /// The sound that's played when the mail's lock has been emagged. /// - [DataField("emagSound")] + [DataField] public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks"); /// diff --git a/Content.Server/Nyanotrasen/Mail/Components/MailTeleporterComponent.cs b/Content.Server/Nyanotrasen/Mail/Components/MailTeleporterComponent.cs index bc05d7307d9..aa045f843db 100644 --- a/Content.Server/Nyanotrasen/Mail/Components/MailTeleporterComponent.cs +++ b/Content.Server/Nyanotrasen/Mail/Components/MailTeleporterComponent.cs @@ -27,8 +27,8 @@ public sealed partial class MailTeleporterComponent : Component /// The MailDeliveryPoolPrototype that's used to select what mail this /// teleporter can deliver. /// - [DataField("mailPool")] - public string MailPool = "RandomMailDeliveryPool"; + [DataField] + public string MailPool = "RandomDeltaVMailDeliveryPool"; // Frontier / DeltaV: Mail rework /// /// How many mail candidates do we need per actual delivery sent when @@ -102,7 +102,21 @@ public sealed partial class MailTeleporterComponent : Component /// /// What's the malus for failing to deliver a priority package? /// - [DataField("priorityMalus")] + [DataField] public int PriorityMalus = -250; + + // Frontier: Large mail + /// + /// What's the bonus for delivering a large package intact? + /// + [DataField] + public int LargeBonus = 1500; //DeltaV; 5000 to 1500 + + /// + /// What's the malus for failing to deliver a large package? + /// + [DataField] + public int LargeMalus = -500; //DeltaV; -250 to -500 + // End Frontier: Large mail } } diff --git a/Content.Server/Nyanotrasen/Mail/MailCommands.cs b/Content.Server/Nyanotrasen/Mail/MailCommands.cs index 5af873f9e80..e28343710fe 100644 --- a/Content.Server/Nyanotrasen/Mail/MailCommands.cs +++ b/Content.Server/Nyanotrasen/Mail/MailCommands.cs @@ -20,6 +20,7 @@ public sealed class MailToCommand : IConsoleCommand [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; private readonly string _blankMailPrototype = "MailAdminFun"; + private readonly string _blankLargeMailPrototype = "MailLargeAdminFun"; // Frontier: large mail private readonly string _container = "storagebase"; private readonly string _mailContainer = "contents"; @@ -56,6 +57,16 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args) return; } + // Frontier: Large Mail + bool isLarge = false; + if (args.Length > 4 && !Boolean.TryParse(args[4], out isLarge)) + { + shell.WriteError(Loc.GetString("shell-invalid-bool")); + return; + } + var mailPrototype = isLarge ? _blankLargeMailPrototype : _blankMailPrototype; + // End Frontier + var _mailSystem = _entitySystemManager.GetEntitySystem(); var _containerSystem = _entitySystemManager.GetEntitySystem(); @@ -66,9 +77,9 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args) return; } - if (!_prototypeManager.HasIndex(_blankMailPrototype)) + if (!_prototypeManager.HasIndex(mailPrototype)) // Frontier: _blankMailPrototype(containerUid).Coordinates); + var mailUid = _entityManager.SpawnEntity(mailPrototype, _entityManager.GetComponent(containerUid).Coordinates); // Frontier: _blankMailPrototype(mailUid, _mailContainer); if (!_entityManager.TryGetComponent(mailUid, out MailComponent? mailComponent)) { - shell.WriteLine(Loc.GetString("command-mailto-bogus-mail", ("blankMail", _blankMailPrototype), ("requiredMailComponent", nameof(MailComponent)))); + shell.WriteLine(Loc.GetString("command-mailto-bogus-mail", ("blankMail", mailPrototype), ("requiredMailComponent", nameof(MailComponent)))); // Frontier: _blankMailPrototype(uid); @@ -710,6 +720,8 @@ public void SpawnMail(EntityUid uid, MailTeleporterComponent? component = null) var mail = EntityManager.SpawnEntity(chosenParcel, Transform(uid).Coordinates); SetupMail(mail, component, candidate); + + _tagSystem.AddTag(mail, "Mail"); // Frontier } if (_containerSystem.TryGetContainer(uid, "queued", out var queued)) diff --git a/Content.Server/_NF/Mail/DelayedItemComponent.cs b/Content.Server/_NF/Mail/DelayedItemComponent.cs new file mode 100644 index 00000000000..dbf1ab6fcbb --- /dev/null +++ b/Content.Server/_NF/Mail/DelayedItemComponent.cs @@ -0,0 +1,16 @@ +namespace Content.Server.Mail +{ + /// + /// A placeholder for another entity, spawned when dropped or placed in someone's hands. + /// Useful for storing instant effect entities, e.g. smoke, in the mail. + /// + [RegisterComponent] + public sealed partial class DelayedItemComponent : Component + { + /// + /// The entity to replace this when opened or dropped. + /// + [DataField] + public string Item = "None"; + } +} diff --git a/Content.Server/_NF/Mail/DelayedItemSystem.cs b/Content.Server/_NF/Mail/DelayedItemSystem.cs new file mode 100644 index 00000000000..a8dd5fae73a --- /dev/null +++ b/Content.Server/_NF/Mail/DelayedItemSystem.cs @@ -0,0 +1,56 @@ +using Content.Shared.Damage; +using Content.Shared.Hands; +using Robust.Shared.Containers; + +namespace Content.Server.Mail +{ + /// + /// A placeholder for another entity, spawned when taken out of a container, with the placeholder deleted shortly after. + /// Useful for storing instant effect entities, e.g. smoke, in the mail. + /// + public sealed class DelayedItemSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnDropAttempt); + SubscribeLocalEvent(OnHandEquipped); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnRemovedFromContainer); + } + + /// + /// EntGotRemovedFromContainerMessage handler - spawn the intended entity after removed from a container. + /// + private void OnRemovedFromContainer(EntityUid uid, DelayedItemComponent component, ContainerModifiedMessage args) + { + Spawn(component.Item, Transform(uid).Coordinates); + } + + /// + /// GotEquippedHandEvent handler - destroy the placeholder. + /// + private void OnHandEquipped(EntityUid uid, DelayedItemComponent component, EquippedHandEvent args) + { + EntityManager.DeleteEntity(uid); + } + + /// + /// OnDropAttempt handler - destroy the placeholder. + /// + private void OnDropAttempt(EntityUid uid, DelayedItemComponent component, DropAttemptEvent args) + { + EntityManager.DeleteEntity(uid); + } + + /// + /// OnDamageChanged handler - item has taken damage (e.g. inside the envelope), spawn the intended entity outside of any container and delete the placeholder. + /// + private void OnDamageChanged(EntityUid uid, DelayedItemComponent component, DamageChangedEvent args) + { + Spawn(component.Item, Transform(uid).Coordinates); + EntityManager.DeleteEntity(uid); + } + } +} diff --git a/Content.Server/_NF/Mail/MailConstants.cs b/Content.Server/_NF/Mail/MailConstants.cs new file mode 100644 index 00000000000..a739a70ab89 --- /dev/null +++ b/Content.Server/_NF/Mail/MailConstants.cs @@ -0,0 +1,38 @@ +namespace Content.Server.Mail +{ + /// + /// A set of localized strings related to mail entities + /// + public struct MailEntityStrings + { + public string NameAddressed; + public string DescClose; + public string DescFar; + } + + /// + /// Constants related to mail. + /// + public sealed class MailConstants : EntitySystem + { + /// + /// Locale strings related to small parcels. + /// + public static readonly MailEntityStrings Mail = new() + { + NameAddressed = "mail-item-name-addressed", + DescClose = "mail-desc-close", + DescFar = "mail-desc-far" + }; + + /// + /// Locale strings related to large packages. + /// + public static readonly MailEntityStrings MailLarge = new() + { + NameAddressed = "mail-large-item-name-addressed", + DescClose = "mail-large-desc-close", + DescFar = "mail-large-desc-far" + }; + } +} \ No newline at end of file diff --git a/Resources/Locale/en-US/_NF/mail/mail.ftl b/Resources/Locale/en-US/_NF/mail/mail.ftl new file mode 100644 index 00000000000..394c551fad5 --- /dev/null +++ b/Resources/Locale/en-US/_NF/mail/mail.ftl @@ -0,0 +1,9 @@ +mail-large-item-name-unaddressed = package +mail-large-item-name-addressed = package ({$recipient}) +mail-large-desc-far = A large package. +mail-large-desc-close = A large package addressed to {CAPITALIZE($name)}, {$job}. Last known location: {$station}. + +### Frontier: mailtestbulk +command-mailtestbulk = Sends one of each type of parcel to a given mail teleporter. Implicitly calls mailnow. +command-mailtestbulk-help = Usage: {$command} +command-mailtestbulk-success = Success! All mail teleporters will be delivering another round of mail soon. diff --git a/Resources/Locale/en-US/Mail/mail.ftl b/Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl similarity index 91% rename from Resources/Locale/en-US/Mail/mail.ftl rename to Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl index 72cd3879b32..40c292d7ddd 100644 --- a/Resources/Locale/en-US/Mail/mail.ftl +++ b/Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl @@ -8,15 +8,16 @@ mail-desc-priority = The anti-tamper lock's [color=yellow]yellow priority tape[/ mail-desc-priority-inactive = The anti-tamper lock's [color=#886600]yellow priority tape[/color] is inactive. mail-unlocked = Anti-tamper system unlocked. mail-unlocked-by-emag = Anti-tamper system *BZZT*. -mail-unlocked-reward = Anti-tamper system unlocked. {$bounty} spesos have been added to logistics's account. -mail-penalty-lock = ANTI-TAMPER LOCK BROKEN. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} CREDITS. -mail-penalty-fragile = INTEGRITY COMPROMISED. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} CREDITS. -mail-penalty-expired = DELIVERY PAST DUE. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} CREDITS. +mail-unlocked-reward = Anti-tamper system unlocked. {$bounty} spesos have been added to logistics' account. +mail-penalty-lock = ANTI-TAMPER LOCK BROKEN. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. +mail-penalty-fragile = INTEGRITY COMPROMISED. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. +mail-penalty-expired = DELIVERY PAST DUE. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. mail-item-name-unaddressed = mail mail-item-name-addressed = mail ({$recipient}) command-mailto-description = Queue a parcel to be delivered to an entity. Example usage: `mailto 1234 5678 false false`. The target container's contents will be transferred to an actual mail parcel. -command-mailto-help = Usage: {$command} [is-fragile: true or false] [is-priority: true or false] +### Frontier: add is-large description +command-mailto-help = Usage: {$command} [is-fragile: true or false] [is-priority: true or false] [is-large: true or false, optional] command-mailto-no-mailreceiver = Target recipient entity does not have a {$requiredComponent}. command-mailto-no-blankmail = The {$blankMail} prototype doesn't exist. Something is very wrong. Contact a programmer. command-mailto-bogus-mail = {$blankMail} did not have {$requiredMailComponent}. Something is very wrong. Contact a programmer. diff --git a/Resources/Migrations/frontierMigrations.yml b/Resources/Migrations/frontierMigrations.yml new file mode 100644 index 00000000000..e8d607494ed --- /dev/null +++ b/Resources/Migrations/frontierMigrations.yml @@ -0,0 +1,2 @@ +# 2024-08-22 - Frontier Mail - Add more to these when they come up as mapped. Part of the Frontier Mail port, blame Tortuga. +MailPAI: MailNFPAI diff --git a/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml b/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml index 88f691ba9b7..fbbec89a269 100644 --- a/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml +++ b/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml @@ -12,3 +12,5 @@ ClothingHeadMailCarrier: 2 # Nyanotrasen - Mail Carrier old gear MailBag: 2 # Nyanotrasen - Mail Carrier old gear ClothingOuterWinterCoatMail: 2 # Nyanotrasen - Mail Carrier old gear + WeaponMailLake: 2 # Frontier Mail Port + BoxMailCapsulePrimed: 4 # Frontier Mail Port diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml index 7de554f5ff5..4da4fa260a3 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml @@ -1,3 +1,5 @@ +# DeltaV Mail + - type: entity noSpawn: true parent: BaseMail @@ -175,3 +177,1526 @@ - type: Mail contents: - id: FoodPiePumpkin + +- type: entity + parent: BaseMail + id: MailDVCosplayFakeWizard + suffix: cosplay-wizard, fake as fuck + components: + - type: Mail + contents: + - id: ClothingOuterWizardFake + - id: ClothingHeadHatWizardFake + - id: ClothingShoesWizardFake + - id: FoodBurgerSpell + orGroup: FakeWizard + prob: 0.3 + - id: FoodKebabSkewer + orGroup: FakeWizard + prob: 0.1 + + + +# Frontier Mail, including Extended Nyano Mail. (Pony Express?) +- type: entity + parent: BaseMail + id: MailNFAlcohol + suffix: alcohol, extended + components: + - type: Mail + isFragile: true + contents: + # 12.5 overall weight, 8% base chance + - id: DrinkAbsintheBottleFull + orGroup: Drink + - id: DrinkBlueCuracaoBottleFull + orGroup: Drink + - id: DrinkCoffeeLiqueurBottleFull + orGroup: Drink + - id: DrinkGinBottleFull + orGroup: Drink + - id: DrinkMelonLiquorBottleFull + orGroup: Drink + - id: DrinkRumBottleFull + orGroup: Drink + - id: DrinkTequilaBottleFull + orGroup: Drink + - id: DrinkVermouthBottleFull + orGroup: Drink + - id: DrinkVodkaBottleFull + orGroup: Drink + - id: DrinkWhiskeyBottleFull + orGroup: Drink + - id: DrinkWineBottleFull + orGroup: Drink + - id: DrinkChampagneBottleFull + orGroup: Drink + prob: 0.5 + - id: DrinkGildlagerBottleFull + orGroup: Drink + prob: 0.5 + - id: DrinkPatronBottleFull + orGroup: Drink + prob: 0.5 + - id: DrinkGlass + amount: 2 + +- type: entity + parent: BaseMailLarge + id: MailNFBible + suffix: bible, extended + components: + - type: Mail + contents: + - id: Bible + - id: ClothingHeadHatWitch1 #DeltaV - Compensates for items that don't exist here + - id: ClothingOuterCoatMNKBlackTopCoat #DeltaV - Compensates for items that don't exist here + +- type: entity + parent: BaseMail + id: MailNFBikeHorn + suffix: bike horn, random + components: + - type: Mail + contents: + - id: BikeHorn + orGroup: Horn + prob: 0.95 + - id: CluwneHorn + orGroup: Horn + prob: 0.05 + +- type: entity + parent: BaseMailLarge + id: MailNFBuildABuddy + suffix: Build-a-Buddy + components: + - type: Mail + isFragile: true + contents: +# - id: BoxBuildABuddyGoblin # DeltaV - Goblins Aren't Real +# orGroup: Box + - id: BoxBuildABuddyHuman + orGroup: Box + - id: BoxBuildABuddyReptilian + orGroup: Box + - id: BoxBuildABuddySlime + orGroup: Box + - id: BoxBuildABuddyVulpkanin + orGroup: Box + - id: DrinkSpaceGlue + - id: PaperMailNFBuildABuddy + +- type: entity + parent: BaseMailLarge + id: MailNFCake + suffix: cake, extended + components: + - type: Mail + isFragile: true + isPriority: true + contents: + # 14.8 total weight, ~6.8% base chance + - id: FoodCakeApple + orGroup: Cake + - id: FoodCakeBirthday + orGroup: Cake + - id: FoodCakeBlueberry + orGroup: Cake + - id: FoodCakeCarrot + orGroup: Cake + - id: FoodCakeCheese + orGroup: Cake + - id: FoodCakeChocolate + orGroup: Cake + - id: FoodCakeChristmas + orGroup: Cake + - id: FoodCakeClown + orGroup: Cake + - id: FoodCakeLemon + orGroup: Cake + - id: FoodCakeLime + orGroup: Cake + - id: FoodCakeOrange + orGroup: Cake + - id: FoodCakePumpkin + orGroup: Cake + - id: FoodCakeVanilla + orGroup: Cake + # Uncommon + - id: FoodMothMothmallow + orGroup: Cake + prob: 0.5 + - id: FoodCakeSlime + orGroup: Cake + prob: 0.5 + # Rare + - id: FoodCakeBrain + orGroup: Cake + prob: 0.25 + - id: FoodCakeLemoon + orGroup: Cake + prob: 0.25 + - id: FoodCakeSuppermatter + orGroup: Cake + prob: 0.25 + # Ultra rare + - id: FoodCakeSpaceman + orGroup: Cake + prob: 0.05 + - id: KnifePlastic + - id: ForkPlastic + amount: 2 + +- type: entity + parent: BaseMail + id: MailNFCosplayWizard + suffix: cosplay-wizard, extended + components: + - type: Mail + contents: + - id: ClothingOuterWizard + - id: ClothingHeadHatWizard + - id: ClothingShoesWizard + - id: PonderingOrb + orGroup: Staff + prob: 0.3 + - id: RGBStaff + orGroup: Staff + prob: 0.1 + +- type: entity + parent: BaseMail + id: MailNFCosplayMaid + suffix: cosplay-maid, extended + components: + - type: Mail + contents: + - id: UniformMaid + orGroup: Uniform + - id: ClothingUniformJumpskirtJanimaid + orGroup: Uniform + - id: ClothingUniformJumpskirtJanimaidmini + orGroup: Uniform + - id: MegaSprayBottle + - id: ClothingHandsGlovesColorWhite + +- type: entity + parent: BaseMail + id: MailNFCosplayNurse + suffix: cosplay-nurse, extended + components: + - type: Mail + contents: + - id: ClothingUniformJumpskirtNurse + - id: ClothingHeadNurseHat + - id: Syringe + +- type: entity + parent: BaseMail + id: MailNFCheese + suffix: cheese, extended + components: + - type: Mail + isFragile: true + isPriority: true + contents: + - id: FoodCheese + orGroup: Cheese + prob: 0.5 + - id: FoodChevre + orGroup: Cheese + prob: 0.5 + - id: KnifePlastic + +- type: entity + parent: BaseMail + id: MailNFCigarettes + suffix: cigs, random + components: + - type: Mail + contents: + - id: CigPackBlack + orGroup: Cigs + prob: 0.19 + - id: CigPackBlue + orGroup: Cigs + prob: 0.19 + - id: CigPackGreen + orGroup: Cigs + prob: 0.19 + - id: CigPackRed + orGroup: Cigs + prob: 0.19 + - id: CigPackMixed + orGroup: Cigs + prob: 0.09 # Pool shared with CigPackMixedMedical, CigPackMixedNasty + - id: CigPackMixedMedical + orGroup: Cigs + prob: 0.05 + - id: CigPackMixedNasty + orGroup: Cigs + prob: 0.05 + # Rare + - id: CigPackSyndicate + orGroup: Cigs + prob: 0.05 + - id: CheapLighter + +- type: entity + parent: BaseMail + id: MailNFEMP + suffix: emp + components: + - type: Mail + contents: + - id: DelayedEMP + - id: PaperMailNFEMPPreparedness + +- type: entity + parent: BaseMail + id: MailNFSmoke + suffix: smoke + components: + - type: Mail + contents: + - id: DelayedSmoke + +- type: entity + parent: BaseMail + id: MailNFGoldCigars + suffix: cigars, premium + components: + - type: Mail + contents: + - id: CigarGoldCase + orGroup: Cigars + - id: FlippoLighter + orGroup: Lighter + prob: 0.95 + +- type: entity + parent: BaseMail + id: MailNFCookies + suffix: cookies, random + components: + - type: Mail + isPriority: true + contents: + # Cookie 1 + - id: FoodBakedCookie + orGroup: Cookie1 + - id: FoodBakedCookieOatmeal + orGroup: Cookie1 + - id: FoodBakedCookieRaisin + orGroup: Cookie1 + - id: FoodBakedCookieSugar + orGroup: Cookie1 + # Cookie 2 + - id: FoodBakedCookie + orGroup: Cookie2 + - id: FoodBakedCookieOatmeal + orGroup: Cookie2 + - id: FoodBakedCookieRaisin + orGroup: Cookie2 + - id: FoodBakedCookieSugar + orGroup: Cookie2 + # Cookie 3 + - id: FoodBakedCookie + orGroup: Cookie3 + - id: FoodBakedCookieOatmeal + orGroup: Cookie3 + - id: FoodBakedCookieRaisin + orGroup: Cookie3 + - id: FoodBakedCookieSugar + orGroup: Cookie3 + # Cookie 4 + - id: FoodBakedCookie + orGroup: Cookie4 + - id: FoodBakedCookieOatmeal + orGroup: Cookie4 + - id: FoodBakedCookieRaisin + orGroup: Cookie4 + - id: FoodBakedCookieSugar + orGroup: Cookie4 + +- type: entity + parent: BaseMail + id: MailNFKnife + suffix: knife, extended + components: + - type: Mail + contents: + - id: KukriKnife + orGroup: Knife + - id: Machete # A little large for an envelope but "we'll live" + orGroup: Knife + - id: CombatKnife + orGroup: Knife + - id: SurvivalKnife + orGroup: Knife + +- type: entity + parent: BaseMailLarge + id: MailNFSword + suffix: sword + components: + - type: Mail + contents: + - id: KatanaDulled + orGroup: Sword + prob: 0.95 + - id: ClaymoreDulled + orGroup: Sword + prob: 0.95 + - id: FoamCutlass + orGroup: Sword + prob: 0.95 + - id: Katana + orGroup: Sword + prob: 0.5 + - id: Claymore + orGroup: Sword + prob: 0.5 + - id: CaneSheathFilled + orGroup: Sword + prob: 0.3 + - id: Cutlass + orGroup: Sword + prob: 0.1 + - id: Kanabou # ah yes, swords + orGroup: Sword + prob: 0.1 + - id: ClothingBeltSheathFilled # Little dangerous between the reflect and the damage + orGroup: Sword + prob: 0.001 + +- type: entity + parent: BaseMail + id: MailNFMuffins + suffix: muffins, random + components: + - type: Mail + isPriority: true + contents: + # Muffin 1 + - id: FoodBakedMuffinBerry + orGroup: Muffin1 + - id: FoodBakedMuffinCherry + orGroup: Muffin1 + - id: FoodBakedMuffinBluecherry + orGroup: Muffin1 + - id: FoodBakedMuffin + orGroup: Muffin1 + - id: FoodMothMoffin + orGroup: Muffin1 + prob: 0.5 + # Muffin 2 + - id: FoodBakedMuffinBerry + orGroup: Muffin2 + - id: FoodBakedMuffinCherry + orGroup: Muffin2 + - id: FoodBakedMuffinBluecherry + orGroup: Muffin2 + - id: FoodBakedMuffin + orGroup: Muffin2 + - id: FoodMothMoffin + orGroup: Muffin2 + prob: 0.5 + # Muffin 3 + - id: FoodBakedMuffinBerry + orGroup: Muffin3 + - id: FoodBakedMuffinCherry + orGroup: Muffin3 + - id: FoodBakedMuffinBluecherry + orGroup: Muffin3 + - id: FoodBakedMuffin + orGroup: Muffin3 + - id: FoodMothMoffin + orGroup: Muffin3 + prob: 0.5 + # Muffin 4 + - id: FoodBakedMuffinBerry + orGroup: Muffin4 + - id: FoodBakedMuffinCherry + orGroup: Muffin4 + - id: FoodBakedMuffinBluecherry + orGroup: Muffin4 + - id: FoodBakedMuffin + orGroup: Muffin4 + - id: FoodMothMoffin + orGroup: Muffin4 + prob: 0.5 + +- type: entity + parent: BaseMail + id: MailNFPAI + suffix: PAI, extended + components: + - type: Mail + contents: + - id: PersonalAI + orGroup: PAI + prob: 0.99 + # Ultra rare + - id: SyndicatePersonalAI + orGroup: PAI + prob: 0.01 + +- type: entity + parent: BaseMail + id: MailNFPlushie + suffix: plushie, extended + components: + - type: Mail + contents: + # These are all grouped up now to guarantee at least one item received. + # The downside is you're not going to get half a dozen plushies anymore. + - id: PlushieBee + orGroup: Plushie + - id: PlushieRGBee + prob: 0.5 + orGroup: Plushie + - id: PlushieNuke + orGroup: Plushie + - id: PlushieArachind #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushieAtmosian #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushieXeno #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushiePenguin #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushieGhost #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushieDiona #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: ToyMouse #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushieRouny + orGroup: Plushie + - id: PlushieLizard + orGroup: Plushie + - id: PlushieSpaceLizard + orGroup: Plushie + - id: PlushieRatvar + orGroup: Plushie + - id: PlushieNar + orGroup: Plushie + - id: PlushieCarp + orGroup: Plushie + - id: PlushieHolocarp #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushieRainbowCarp #DeltaV - Adds MORE PLUSHIE + orGroup: Plushie + - id: PlushieSlime + orGroup: Plushie + - id: PlushieSnake + orGroup: Plushie + - id: PlushieMothRandom + orGroup: Plushie + - id: PlushieMoth + prob: 0.5 + orGroup: Plushie + - id: PlushieMothMusician + prob: 0.5 + orGroup: Plushie + - id: PlushieMothBartender + prob: 0.5 + orGroup: Plushie + +# Random snacks, replaces MailChocolate (lousy animal organs) +- type: entity + parent: BaseMail + id: MailNFSnacks + suffix: snacks, random + components: + - type: Mail + contents: + # Snack 1 + - id: FoodSnackChocolate + orGroup: Snack1 + - id: FoodSnackPopcorn + orGroup: Snack1 + - id: FoodSnackChips + orGroup: Snack1 + - id: FoodSnackBoritos + orGroup: Snack1 + - id: FoodSnackSus + orGroup: Snack1 + - id: FoodSnackPistachios + orGroup: Snack1 + - id: FoodSnackRaisins + orGroup: Snack1 + - id: FoodSnackCheesie + orGroup: Snack1 + - id: FoodSnackEnergy + orGroup: Snack1 + - id: FoodSnackCnDs + orGroup: Snack1 + - id: FoodSnackSemki + orGroup: Snack1 + - id: FoodSnackSyndi + orGroup: Snack1 + prob: 0.5 + # Snack 2 + - id: FoodSnackChocolate + orGroup: Snack2 + - id: FoodSnackPopcorn + orGroup: Snack2 + - id: FoodSnackChips + orGroup: Snack2 + - id: FoodSnackBoritos + orGroup: Snack2 + - id: FoodSnackSus + orGroup: Snack2 + - id: FoodSnackPistachios + orGroup: Snack2 + - id: FoodSnackRaisins + orGroup: Snack2 + - id: FoodSnackCheesie + orGroup: Snack2 + - id: FoodSnackEnergy + orGroup: Snack2 + - id: FoodSnackCnDs + orGroup: Snack2 + - id: FoodSnackSemki + orGroup: Snack2 + - id: FoodSnackSyndi + orGroup: Snack2 + prob: 0.5 + # Snack 3 + - id: FoodSnackChocolate + orGroup: Snack3 + - id: FoodSnackPopcorn + orGroup: Snack3 + - id: FoodSnackChips + orGroup: Snack3 + - id: FoodSnackBoritos + orGroup: Snack3 + - id: FoodSnackSus + orGroup: Snack3 + - id: FoodSnackPistachios + orGroup: Snack3 + - id: FoodSnackRaisins + orGroup: Snack3 + - id: FoodSnackCheesie + orGroup: Snack3 + - id: FoodSnackEnergy + orGroup: Snack3 + - id: FoodSnackCnDs + orGroup: Snack3 + - id: FoodSnackSemki + orGroup: Snack3 + - id: FoodSnackSyndi + orGroup: Snack3 + prob: 0.5 + # Snack 4 + - id: FoodSnackChocolate + orGroup: Snack4 + - id: FoodSnackPopcorn + orGroup: Snack4 + - id: FoodSnackChips + orGroup: Snack4 + - id: FoodSnackBoritos + orGroup: Snack4 + - id: FoodSnackSus + orGroup: Snack4 + - id: FoodSnackPistachios + orGroup: Snack4 + - id: FoodSnackRaisins + orGroup: Snack4 + - id: FoodSnackCheesie + orGroup: Snack4 + - id: FoodSnackEnergy + orGroup: Snack4 + - id: FoodSnackCnDs + orGroup: Snack4 + - id: FoodSnackSemki + orGroup: Snack4 + - id: FoodSnackSyndi + orGroup: Snack4 + prob: 0.5 + +- type: entity + parent: BaseMail + id: MailNFVagueThreat + suffix: vague-threat + components: + - type: Mail + contents: + - id: PaperMailNFVagueThreat1 + orGroup: Paper + - id: PaperMailNFVagueThreat2 + orGroup: Paper + - id: PaperMailNFVagueThreat3 + orGroup: Paper + - id: PaperMailNFVagueThreat4 + orGroup: Paper + - id: PaperMailNFVagueThreat5 + orGroup: Paper + - id: PaperMailNFVagueThreat6 + orGroup: Paper + - id: PaperMailNFVagueThreat7 + orGroup: Paper + - id: PaperMailNFVagueThreat8 + orGroup: Paper + - id: PaperMailNFVagueThreat9 + orGroup: Paper + - id: PaperMailNFVagueThreat10 + orGroup: Paper + - id: PaperMailNFVagueThreat11 + orGroup: Paper + - id: PaperMailNFVagueThreat12 + orGroup: Paper + - id: KitchenKnife + orGroup: ThreateningObject + - id: ButchCleaver + orGroup: ThreateningObject + - id: CombatKnife + orGroup: ThreateningObject + - id: SurvivalKnife + orGroup: ThreateningObject + - id: SoapHomemade + orGroup: ThreateningObject + - id: FoodMeat + orGroup: ThreateningObject + - id: OrganHumanHeart + orGroup: ThreateningObject + +- type: entity + parent: BaseMail + id: MailNFDonkPockets + suffix: donk pockets, random + components: + - type: Mail + contents: + - id: FoodBoxDonkpocket + orGroup: Donk + prob: 0.4 # Higher probability, useful for chefs. + - id: FoodBoxDonkpocketSpicy + orGroup: Donk + prob: 0.1 + - id: FoodBoxDonkpocketTeriyaki + orGroup: Donk + prob: 0.1 + - id: FoodBoxDonkpocketPizza + orGroup: Donk + prob: 0.1 + - id: FoodBoxDonkpocketStonk + orGroup: Donk + prob: 0.05 + - id: FoodBoxDonkpocketCarp + orGroup: Donk + prob: 0.05 + - id: FoodBoxDonkpocketBerry + orGroup: Donk + prob: 0.1 + - id: FoodBoxDonkpocketHonk + orGroup: Donk + prob: 0.05 + - id: FoodBoxDonkpocketDink + orGroup: Donk + prob: 0.05 # Bad luck. + +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFSodaPwrGame + suffix: Pwrgame + components: + - type: Mail + contents: + - id: DrinkPwrGameCan + amount: 3 + - id: PaperMailNFPwrGameAd + +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFSodaRedBool + suffix: Red Bool + components: + - type: Mail + contents: + - id: DrinkEnergyDrinkCan + amount: 3 + - id: PaperMailNFRedBoolAd + +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFSodaSpaceCola + suffix: Space Cola + components: + - type: Mail + contents: + - id: DrinkColaBottleFull + - id: PaperMailNFSpaceColaAd + +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFSodaSpaceMountainWind + suffix: Space Mountain Wind + components: + - type: Mail + contents: + - id: DrinkSpaceMountainWindBottleFull + - id: PaperMailNFSpaceMountainWindAd + +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFSodaSpaceUp + suffix: Space Up + components: + - type: Mail + contents: + - id: DrinkSpaceUpBottleFull + - id: PaperMailNFSpaceUpAd + +- type: entity + parent: BaseMail + id: MailNFJoints + suffix: joints + components: + - type: Mail + contents: + # Smokeable 1 + - id: Joint + orGroup: Smokeable1 + prob: 0.35 + - id: JointRainbow + orGroup: Smokeable1 + prob: 0.15 + - id: Blunt + orGroup: Smokeable1 + prob: 0.35 + - id: BluntRainbow + orGroup: Smokeable1 + prob: 0.15 + # Smokeable 2 + - id: Joint + orGroup: Smokeable2 + prob: 0.35 + - id: JointRainbow + orGroup: Smokeable2 + prob: 0.15 + - id: Blunt + orGroup: Smokeable2 + prob: 0.35 + - id: BluntRainbow + orGroup: Smokeable2 + prob: 0.15 + # Smokeable 3 + - id: Joint + orGroup: Smokeable3 + prob: 0.35 + - id: JointRainbow + orGroup: Smokeable3 + prob: 0.15 + - id: Blunt + orGroup: Smokeable3 + prob: 0.35 + - id: BluntRainbow + orGroup: Smokeable3 + prob: 0.15 + +# Catchalls for food that only exist in random spawners +# Mmm, mail food +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFUnusualFood + suffix: unusual food + components: + - type: Mail + isPriority: true + isFragile: true + contents: + - id: FoodMealNachos + orGroup: Food + - id: FoodMealNachosCheesy + orGroup: Food + - id: FoodMealNachosCuban + orGroup: Food + - id: FoodMealEggplantParm + orGroup: Food + - id: FoodMealPotatoYaki + orGroup: Food + - id: FoodMealCornedbeef + orGroup: Food + - id: FoodMealBearsteak + orGroup: Food + - id: FoodMealPigblanket + orGroup: Food + - id: FoodMealEggsbenedict + orGroup: Food + - id: FoodMealOmelette + orGroup: Food + - id: FoodMealFriedegg + orGroup: Food + - id: FoodMealMilkape + orGroup: Food + - id: FoodMealMemoryleek + orGroup: Food + - id: DisgustingSweptSoup + orGroup: Food + - id: FoodBreadVolcanic + orGroup: Food + - id: FoodBakedWaffleSoylent + orGroup: Food + - id: FoodBakedWaffleRoffle + orGroup: Food + - id: FoodPieCherry + orGroup: Food + - id: FoodPieFrosty + orGroup: Food + prob: 0.05 + - id: FoodMeatGoliathCooked + amount: 3 + orGroup: Food + - id: FoodMeatRounyCooked + amount: 3 + orGroup: Food + - id: FoodMeatLizardCooked + amount: 3 + orGroup: Food + - id: FoodMeatSpiderlegCooked + amount: 3 + orGroup: Food + - id: FoodMeatMeatballCooked + amount: 4 + orGroup: Food + +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFBakedGoods + suffix: baked goods + components: + - type: Mail + isPriority: true + isFragile: true + contents: + - id: FoodBakedBunHoney + amount: 2 + orGroup: Food + - id: FoodBakedBunHotX + amount: 2 + orGroup: Food + - id: FoodBakedBunMeat + amount: 2 + orGroup: Food + - id: FoodBakedPretzel + amount: 2 + orGroup: Food + - id: FoodBakedCannoli + amount: 2 + orGroup: Food + - id: FoodDonutPlain + amount: 2 + orGroup: Food + - id: FoodDonutJellyPlain + amount: 2 + orGroup: Food + - id: FoodDonutHomer + amount: 2 + orGroup: Food + - id: FoodDonutChaos + amount: 2 + orGroup: Food + - id: FoodDonutMeat + amount: 2 + orGroup: Food + - id: FoodDonutPink + amount: 2 + orGroup: Food + - id: FoodDonutSpaceman + amount: 2 + orGroup: Food + - id: FoodDonutApple + amount: 2 + orGroup: Food + - id: FoodDonutCaramel + amount: 2 + orGroup: Food + - id: FoodDonutChocolate + amount: 2 + orGroup: Food + - id: FoodDonutBluePumpkin + amount: 2 + orGroup: Food + - id: FoodDonutBungo + amount: 2 + orGroup: Food + - id: FoodDonut + amount: 2 + orGroup: Food + - id: FoodDonutSweetpea + amount: 2 + orGroup: Food + - id: FoodDonutJellyHomer + amount: 2 + orGroup: Food + - id: FoodDonutJellyPink + amount: 2 + orGroup: Food + - id: FoodDonutJellySpaceman + amount: 2 + orGroup: Food + - id: FoodDonutJellyApple + amount: 2 + orGroup: Food + - id: FoodDonutJellyCaramel + amount: 2 + orGroup: Food + - id: FoodDonutJellyChocolate + amount: 2 + orGroup: Food + - id: FoodDonutJellyBluePumpkin + amount: 2 + orGroup: Food + - id: FoodDonutJellyBungo + amount: 2 + orGroup: Food + - id: FoodDonutJelly + amount: 2 + orGroup: Food + - id: FoodDonutJellySweetpea + amount: 2 + orGroup: Food + - id: FoodDonutJellySlugcat + amount: 2 + orGroup: Food + - id: FoodFrozenSandwich # ah yes, baked goods + amount: 2 + orGroup: Food + - id: FoodFrozenFreezy + amount: 2 + orGroup: Food + - id: FoodFrozenSundae + amount: 2 + orGroup: Food + - id: FoodFrozenCornuto + amount: 2 + orGroup: Food + - id: FoodFrozenPopsicleOrange + amount: 2 + orGroup: Food + - id: FoodFrozenPopsicleBerry + amount: 2 + orGroup: Food + - id: FoodFrozenPopsicleJumbo + amount: 2 + orGroup: Food + - id: FoodFrozenSnowcone + amount: 2 + orGroup: Food + - id: FoodFrozenSnowconeBerry + amount: 2 + orGroup: Food + - id: FoodFrozenSnowconeFruit + amount: 2 + orGroup: Food + - id: FoodFrozenSnowconeClown + amount: 2 + orGroup: Food + - id: FoodFrozenSnowconeMime + amount: 2 + orGroup: Food + - id: FoodFrozenSnowconeRainbow + amount: 2 + orGroup: Food + - id: FoodFrozenSnowconeMime + amount: 2 + orGroup: Food + - id: FoodMealMint # unlucky + amount: 2 + orGroup: Food + +# Needs a buff? +- type: entity + parent: BaseMail + id: MailNFUnusualProduce + suffix: unusual produce + components: + - type: Mail + isPriority: true + isFragile: true + contents: + - id: FoodLaughinPeaPod + orGroup: Produce + amount: 5 + - id: FoodMimana + orGroup: Produce + amount: 5 + - id: FoodLemoon + orGroup: Produce + amount: 5 + - id: FoodBlueTomato + orGroup: Produce + amount: 5 + - id: FoodBloodTomato + orGroup: Produce + amount: 5 + - id: FoodKoibean + orGroup: Produce + amount: 5 + - id: FoodGhostPepper #DeltaV + orGroup: Produce + amount: 5 + - id: FoodCosmicRevenant #DeltaV + orGroup: Produce + amount: 5 + - id: FoodCrystalThistle #DeltaV + orGroup: Produce + amount: 5 + - id: FoodLily + orGroup: Produce + amount: 5 + prob: 0.5 + - id: FoodAmbrosiaDeus + orGroup: Produce + amount: 5 + prob: 0.5 + - id: FoodSpacemansTrumpet + orGroup: Produce + amount: 5 + prob: 0.25 + +- type: entity + parent: BaseMail + id: MailNFSoaps + suffix: soap sampler + components: + - type: Mail + contents: + - id: BoxSoapsAssorted + - id: PaperMailNTSoapAd1 + orGroup: Ad + - id: PaperMailNTSoapAd2 + orGroup: Ad + +- type: entity + parent: BaseMail + id: MailNFSoapsOmega + suffix: soap sampler, omega + components: + - type: Mail + contents: + - id: BoxSoapsAssortedOmega + - id: PaperMailNTSoapAd1 + orGroup: Ad + - id: PaperMailNTSoapAd2 + orGroup: Ad + +# Could add spessman battle rules here +- type: entity + parent: BaseMail + id: MailNFFigurineBulk # DeltaV - No longer Bulk + suffix: figurine, bulk #DeltaV - Spams 3 boxes instead of using the bulk figurine prototype that Frontier uses + components: + - type: Mail + contents: + - id: MysteryFigureBox + - id: MysteryFigureBox + - id: MysteryFigureBox + +- type: entity + parent: BaseMail + id: MailNFPen + suffix: fancy pen + components: + - type: Mail + contents: + - id: LuxuryPen + orGroup: Pen + prob: 0.50 + # DeltaV: Commenting these two out because I dunno if crew should have nice things + # - id: PenHop + # orGroup: Pen + # prob: 0.25 + # - id: PenCap + # orGroup: Pen + # prob: 0.25 + # TODO: come up with a slightly less powerful version of these + # Ultra-rare + # - id: CyberPen + # orGroup: Pen + # prob: 0.005 + # - id: PenCentcom + # orGroup: Pen + # prob: 0.005 + - id: PaperMailNFPaperPusherAd + +- type: entity + parent: BaseMailLarge + id: MailNFThrongler + suffix: throngler + components: + - type: Mail + contents: + - id: PlushieThrongler #DeltaV: ThronglerToy -> PlushieThrongler + +- type: entity + parent: BaseMail + id: MailNFInstrumentSmall + suffix: instrument, expanded + components: + - type: Mail + contents: + - id: TrumpetInstrument + orGroup: Instrument + - id: RecorderInstrument + orGroup: Instrument + - id: ClarinetInstrument + orGroup: Instrument + - id: FluteInstrument + orGroup: Instrument + - id: HarmonicaInstrument + orGroup: Instrument + - id: OcarinaInstrument + orGroup: Instrument + - id: PanFluteInstrument + orGroup: Instrument + - id: KalimbaInstrument + orGroup: Instrument + - id: WoodblockInstrument + orGroup: Instrument + - id: BikeHornInstrument + orGroup: Instrument + - id: MusicBoxInstrument + orGroup: Instrument + - id: MicrophoneInstrument + orGroup: Instrument + - id: MusicalLungInstrument + orGroup: Instrument + # Uncommon + - id: PhoneInstrument + orGroup: Instrument + prob: 0.1 + # Rare + - id: BananaPhoneInstrument + orGroup: Instrument + prob: 0.05 + # Ultra-rare + - id: PhoneInstrumentSyndicate + orGroup: Instrument + prob: 0.01 + +- type: entity + parent: BaseMail + id: MailNFUnusualClothing + suffix: unusual clothing + components: + - type: Mail + contents: + - id: ClothingKimonoPink + orGroup: Clothes + - id: ClothingKimonoBlue + orGroup: Clothes + - id: ClothingKimonoPurple + orGroup: Clothes + - id: ClothingKimonoSky + orGroup: Clothes + - id: ClothingKimonoGreen + orGroup: Clothes + - id: ClothingUniformMartialGi + orGroup: Clothes + - id: ClothingNeckBling + orGroup: Clothes + - id: ClothingShoesBling + orGroup: Clothes + - id: ClothingNeckCloakAdmin + orGroup: Clothes + - id: ClothingHeadHatFancyCrown + orGroup: Clothes + - id: ClothingHeadHatCake + orGroup: Clothes + - id: ClothingHeadHatCone + orGroup: Clothes + - id: ClothingMaskOniRed + orGroup: Clothes + - id: ClothingMaskOniBlue + orGroup: Clothes + - id: ClothingHeadHatRichard + orGroup: Clothes + - id: ClothingHeadHatAnimalHeadslime + orGroup: Clothes + - id: ClothingHeadHatDogEars + orGroup: Clothes + - id: ClothingHeadHatCatEars + orGroup: Clothes + - id: ClothingEyesGlassesOutlawGlasses + orGroup: Clothes + - id: ClothingUniformJumpsuitGalaxyBlue + orGroup: Clothes + prob: 0.25 + - id: ClothingUniformJumpsuitGalaxyRed + orGroup: Clothes + prob: 0.25 + +- type: entity + parent: BaseMail + id: MailNFCritter + suffix: critter + components: + - type: Mail + isFragile: true + contents: + # Bugs (weight: 2) + - id: MobCockroach + orGroup: Critter + prob: 0.36 + - id: MobSlug + orGroup: Critter + prob: 0.36 + - id: MobArgocyteSlurva # honorary bug? + orGroup: Critter + prob: 0.36 + - id: MobBee + orGroup: Critter + prob: 0.36 + - id: MobButterfly + orGroup: Critter + prob: 0.36 + # Uncommon + - id: MobMothroach + orGroup: Critter + prob: 0.2 + # Small reptiles (weight: 1) + - id: MobLizard + orGroup: Critter + prob: 0.34 + - id: MobSnake + orGroup: Critter + prob: 0.33 + - id: MobFrog + orGroup: Critter + prob: 0.33 + # Small mammals (weight: 1) + - id: MobMouse + orGroup: Critter + prob: 0.33 + - id: MobMouse1 + orGroup: Critter + prob: 0.33 + - id: MobMouse2 + orGroup: Critter + prob: 0.33 + - id: MobMouseCancer + orGroup: Critter + prob: 0.01 # Rare + +- type: entity + parent: BaseMail + id: MailNFTacticalMaid + suffix: tactical maid + components: + - type: Mail + contents: + - id: ClothingUniformJumpskirtTacticalMaid + - id: ClothingHeadHatTacticalMaidHeadband + - id: MegaSprayBottle + - id: ClothingHandsTacticalMaidGloves + +- type: entity + parent: BaseMailLarge + id: MailNFKendoKit + suffix: kendo kit + components: + - type: Mail + contents: # A lot of stuff here, seems spammy. + - id: ClothingUniformKendoHakama + amount: 2 + - id: ClothingOuterArmorKendoBogu + amount: 2 + - id: ClothingHeadHelmetKendoMen + amount: 2 + - id: Shinai + amount: 2 + +# Base Nyano Mail +- type: entity + parent: BaseMail + id: MailSake + suffix: osake + components: + - type: Mail + contents: + - id: DrinkSakeCup + amount: 2 + - id: DrinkTokkuri + +- type: entity + parent: BaseMail + id: MailBlockGameDIY + suffix: blockgamediy + components: + - type: Mail + contents: + - id: BlockGameArcadeComputerCircuitboard + +- type: entity + parent: BaseMail + id: MailCigars + suffix: Cigars + components: + - type: Mail + contents: + - id: CigarCase + - id: Lighter + +- type: entity + parent: BaseMail + id: MailCrayon + suffix: Crayon + components: + - type: Mail + contents: + - id: CrayonBox + +- type: entity + parent: BaseMail + id: MailCosplayArc + suffix: cosplay-arc + components: + - type: Mail + openSound: /Audio/Nyanotrasen/Voice/Felinid/cat_wilhelm.ogg + contents: + - id: ClothingCostumeArcDress + +- type: entity + parent: BaseMail + id: MailCosplayGeisha + suffix: cosplay-geisha + components: + - type: Mail + contents: + - id: UniformGeisha + - id: DrinkTeapot + - id: DrinkTeacup + amount: 3 + +- type: entity + parent: BaseMail + id: MailCosplaySchoolgirl + suffix: cosplay-schoolgirl + components: + - type: Mail + contents: + - id: UniformSchoolgirlBlack + orGroup: Color + - id: UniformSchoolgirlBlue + orGroup: Color + - id: UniformSchoolgirlCyan + orGroup: Color + - id: UniformSchoolgirlGreen + orGroup: Color + - id: UniformSchoolgirlOrange + orGroup: Color + - id: UniformSchoolgirlPink + orGroup: Color + - id: UniformSchoolgirlPurple + orGroup: Color + - id: UniformSchoolgirlRed + orGroup: Color + +- type: entity + parent: BaseMail + id: MailFlowers + suffix: flowers + components: + - type: Mail + contents: + # TODO actual flowers + - id: ClothingHeadHatFlowerWreath + orGroup: Flowers + - id: FoodPoppy + orGroup: Flowers + - id: FoodLily + +- type: entity + parent: BaseMail + id: MailSignallerKit + suffix: signallerkit + components: + - type: Mail + contents: + - id: Multitool + - id: RemoteSignaller + +- type: entity + parent: BaseMail + id: MailNoir + suffix: noir + components: + - type: Mail + contents: + - id: ClothingUniformJumpsuitDetectiveGrey + - id: ClothingUniformJumpskirtDetectiveGrey + - id: ClothingHeadHatBowlerHat + - id: ClothingOuterCoatGentle + +- type: entity + parent: BaseMail + id: MailRestraints + suffix: restraints + components: + - type: Mail + contents: + - id: Handcuffs + - id: ClothingMaskMuzzle + - id: ClothingEyesBlindfold + +- type: entity + parent: BaseMail + id: MailFishingCap + suffix: fishingcap + components: + - type: Mail + contents: + - id: ClothingHeadFishCap + +- type: entity + parent: BaseMail + id: MailFlashlight + suffix: Flashlight + components: + - type: Mail + contents: + - id: FlashlightLantern + +- type: entity + parent: BaseMail + id: MailSpaceVillainDIY + suffix: spacevilliandiy + components: + - type: Mail + contents: + - id: SpaceVillainArcadeComputerCircuitboard + +- type: entity + parent: BaseMail + id: MailSunglasses + suffix: Sunglasses + components: + - type: Mail + contents: + - id: ClothingEyesGlassesSunglasses + +- type: entity + parent: BaseMail + id: MailWinterCoat + suffix: wintercoat + components: + - type: Mail + contents: + - id: ClothingOuterWinterCoat + orGroup: Coat + - id: ClothingOuterWinterCoatLong + orGroup: Coat + - id: ClothingOuterWinterCoatPlaid + orGroup: Coat diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_civilian.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_civilian.yml similarity index 71% rename from Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_civilian.yml rename to Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_civilian.yml index a41fac14ffa..aea3131daeb 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_civilian.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_civilian.yml @@ -1,8 +1,63 @@ +# Frontier Mail + +- type: entity + noSpawn: true + parent: BaseMailLarge + id: MailNFInstrumentLarge + suffix: instrument, large + components: + - type: Mail + contents: + - id: TromboneInstrument + orGroup: Instrument + - id: FrenchHornInstrument + orGroup: Instrument + - id: SaxophoneInstrument + orGroup: Instrument + - id: EuphoniumInstrument + orGroup: Instrument + - id: AcousticGuitarInstrument + orGroup: Instrument + - id: ElectricGuitarInstrument + orGroup: Instrument + - id: BassGuitarInstrument + orGroup: Instrument + - id: RockGuitarInstrument + orGroup: Instrument + - id: BanjoInstrument + orGroup: Instrument + - id: ViolinInstrument + orGroup: Instrument + - id: CelloInstrument + orGroup: Instrument + - id: ViolaInstrument + orGroup: Instrument + - id: BagpipeInstrument # Fury. + orGroup: Instrument + - id: SynthesizerInstrument + orGroup: Instrument + - id: AccordionInstrument + orGroup: Instrument + - id: GlockenspielInstrument + orGroup: Instrument + - id: XylophoneInstrument + orGroup: Instrument + # Uncommon + - id: Rickenbacker4003Instrument + orGroup: Instrument + prob: 0.25 + # Rare + - id: Rickenbacker4001Instrument + orGroup: Instrument + prob: 0.1 + +# Base Nyano Mail + - type: entity noSpawn: true parent: BaseMail id: MailBotanistChemicalBottles - suffix: botanistchemicals + suffix: botanist chemicals components: - type: Mail contents: @@ -102,7 +157,7 @@ noSpawn: true parent: BaseMail id: MailHoPBureaucracy - suffix: hoppaper + suffix: hop paper components: - type: Mail contents: @@ -113,7 +168,7 @@ noSpawn: true parent: BaseMail id: MailHoPSupplement - suffix: hopsupplement + suffix: hop supplement components: - type: Mail contents: @@ -125,7 +180,7 @@ noSpawn: true parent: BaseMail id: MailMimeArtsCrafts - suffix: artscrafts + suffix: arts and crafts components: - type: Mail contents: @@ -137,7 +192,7 @@ noSpawn: true parent: BaseMail id: MailMimeBlankBook - suffix: blankbook + suffix: blank book components: - type: Mail contents: @@ -147,37 +202,17 @@ noSpawn: true parent: BaseMail id: MailMimeBottleOfNothing - suffix: bottleofnothing + suffix: bottle of nothing components: - type: Mail contents: - id: DrinkBottleOfNothingFull -- type: entity - noSpawn: true - parent: BaseMail - id: MailMusicianInstrumentSmall - suffix: instrument-small - components: - - type: Mail - isFragile: true - contents: - - id: FluteInstrument - orGroup: Instrument - - id: HarmonicaInstrument - orGroup: Instrument - - id: OcarinaInstrument - orGroup: Instrument - - id: PanFluteInstrument - orGroup: Instrument - - id: RecorderInstrument - orGroup: Instrument - - type: entity noSpawn: true parent: BaseMail id: MailPassengerMoney - suffix: passengermoney + suffix: passenger money components: - type: Mail contents: diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml new file mode 100644 index 00000000000..375b024c408 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml @@ -0,0 +1,32 @@ +# Base Nyano Mail +- type: entity + parent: BaseMail + id: MailCommandPinpointerNuclear + suffix: pinpointer mail ops + components: + - type: Mail + contents: + - id: PinpointerNuclear + +- type: entity + parent: BaseMail + id: MailStationRepNFNukeDisk + suffix: nuke disk + components: + - type: Mail + isFragile: true + contents: + - id: NukeDiskFake + - id: PaperMailNFAntivirus + +- type: entity + parent: BaseMail + id: MailCommandNFPipebombIntern + suffix: pipe and bomb + components: + - type: Mail + isFragile: true + contents: + - id: SmokingPipeFilledTobacco + - id: DrinkAtomicBombGlass + - id: PaperMailNFPipebombIntern diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml new file mode 100644 index 00000000000..8fa0fa4baf7 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml @@ -0,0 +1,175 @@ +# Base Nyano Mail +- type: entity + parent: BaseMail + id: MailEngineeringCables + suffix: cables + components: + - type: Mail + contents: + - id: CableHVStack + orGroup: Cables + - id: CableMVStack + orGroup: Cables + - id: CableApcStack + orGroup: Cables + +- type: entity + parent: BaseMail + id: MailEngineeringKudzuDeterrent + suffix: antikudzu + components: + - type: Mail + contents: + - id: PlantBGoneSpray + +- type: entity + parent: BaseMail + id: MailEngineeringSheetGlass + suffix: sheetglass + components: + - type: Mail + contents: + - id: SheetGlass + +- type: entity + parent: BaseMail + id: MailEngineeringWelderReplacement + suffix: welder + components: + - type: Mail + contents: + - id: Welder + +# Frontier Mail + +- type: entity + parent: BaseMail + id: MailNFCircuitboardIndustrial + suffix: industrial circuitboard + components: + - type: Mail + contents: + - id: ThermomachineFreezerMachineCircuitBoard + orGroup: Board + prob: 0.5 + - id: ThermomachineHeaterMachineCircuitBoard + orGroup: Board + prob: 0.5 + - id: HellfireFreezerMachineCircuitBoard + orGroup: Board + prob: 0.25 + - id: HellfireHeaterMachineCircuitBoard + orGroup: Board + prob: 0.25 + - id: CryoPodMachineCircuitboard # Medical as well + orGroup: Board + prob: 0.5 + - id: ChemMasterMachineCircuitboard + orGroup: Board + prob: 0.5 + - id: ChemDispenserMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: StasisBedMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: BiomassReclaimerMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: BiofabricatorMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: TurboItemRechargerCircuitboard + orGroup: Board + prob: 0.5 + - id: AutolatheHyperConvectionMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: ProtolatheHyperConvectionMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: HotplateMachineCircuitboard + orGroup: Board + prob: 0.5 + - id: CircuitImprinterHyperConvectionMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: SheetifierMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: RadarConsoleCircuitboard + orGroup: Board + prob: 0.25 + - id: OreProcessorIndustrialMachineCircuitboard + orGroup: Board + prob: 0.5 + - id: GasRecyclerMachineCircuitboard + orGroup: Board + prob: 0.1 + +- type: entity + parent: BaseMail + id: MailNFCircuitboardService + suffix: service circuitboard + components: + - type: Mail + contents: + - id: ComputerTelevisionCircuitboard + orGroup: Board + - id: ReagentGrinderMachineCircuitboard + orGroup: Board + - id: ReagentGrinderIndustrialMachineCircuitboard + orGroup: Board + prob: 0.5 + - id: SurveillanceWirelessCameraMovableCircuitboard + orGroup: Board + prob: 0.5 + - id: MicrowaveMachineCircuitboard + orGroup: Board + - id: ElectricGrillMachineCircuitboard + orGroup: Board + prob: 0.5 + - id: FatExtractorMachineCircuitboard + orGroup: Board + prob: 0.25 + - id: SeedExtractorMachineCircuitboard + orGroup: Board + prob: 0.5 + - id: BoozeDispenserMachineCircuitboard + orGroup: Board + - id: SodaDispenserMachineCircuitboard + orGroup: Board + - id: JukeboxCircuitBoard + orGroup: Board + - id: TelecomServerCircuitboard + orGroup: Board + prob: 0.25 + - id: ComputerMassMediaCircuitboard + orGroup: Board + prob: 0.1 + +- type: entity + parent: BaseMailLarge + id: MailNFPowerTool + suffix: power tool + components: + - type: Mail + contents: + - id: PaperMailNFPowerTool + orGroup: Paper + - id: JawsOfLife + orGroup: Gift + prob: 0.33 + - id: PowerDrill + orGroup: Gift + prob: 0.33 + - id: WelderIndustrial + orGroup: Gift + prob: 0.20 + # Rare + - id: WelderIndustrialAdvanced + orGroup: Gift + prob: 0.10 + - id: WelderExperimental + orGroup: Gift + prob: 0.04 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_epistemology.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_epistemology.yml similarity index 74% rename from Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_epistemology.yml rename to Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_epistemology.yml index 38526966b80..be6f9818e22 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_epistemology.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_epistemology.yml @@ -46,13 +46,3 @@ - type: Mail contents: - id: ClothingHeadTinfoil - -- type: entity - noSpawn: true - parent: BaseMail - id: MailDetectiveForensicSupplement # Deltav - Detective is in charge of investigating crimes. - suffix: detectivesupplement # Deltav - Detective is in charge of investigating crimes. - components: - - type: Mail - contents: - - id: BoxForensicPad diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_medical.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_medical.yml similarity index 84% rename from Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_medical.yml rename to Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_medical.yml index 4e797272e5e..735f840a201 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_medical.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_medical.yml @@ -1,3 +1,4 @@ +# Base Nyano Mail - type: entity noSpawn: true parent: BaseMail @@ -91,3 +92,19 @@ maxAmount: 2 - id: SyringeTranexamicAcid maxAmount: 2 + +# Frontier Mail +- type: entity + parent: BaseMailLarge + id: MailNFMedkit + suffix: medkit + components: + - type: Mail + contents: + - id: MedkitAdvancedFilled + orGroup: Medkit + prob: 0.75 + - id: MedkitCombatFilled + orGroup: Medkit + prob: 0.25 + diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml new file mode 100644 index 00000000000..c08e92cc6b2 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml @@ -0,0 +1,88 @@ +# Base Nyano Mail +- type: entity + parent: BaseMail + id: MailSecurityDonuts + suffix: donuts + components: + - type: Mail + contents: + - id: FoodBoxDonut + +- type: entity + parent: BaseMail + id: MailSecurityFlashlight + suffix: seclite + components: + - type: Mail + contents: + - id: FlashlightSeclite + +- type: entity + parent: BaseMail + id: MailSecurityNonlethalsKit + suffix: nonlethalskit + components: + - type: Mail + contents: + - id: Flash + maxAmount: 2 + - id: GrenadeFlashBang + maxAmount: 2 + - id: Handcuffs + maxAmount: 2 + +#- type: entity +# parent: BaseMail +# id: MailSecuritySpaceLaw +# suffix: spacelaw +# components: +# - type: Mail +# contents: +# - id: HyperlinkBookSpaceLaw +# Will we ever readd hyperlinks books? Who knows! + +- type: entity + parent: BaseMail + id: MailWardenCrowdControl + suffix: crowdcontrol + components: + - type: Mail + contents: + - id: BoxBeanbag + +- type: entity + parent: BaseMail + id: MailDetectiveForensicSupplement # Deltav - Detective is in charge of investigating crimes. + suffix: detectivesupplement # Deltav - Detective is in charge of investigating crimes. + components: + - type: Mail + contents: + - id: BoxForensicPad + +# Frontier Mail + +- type: entity + parent: BaseMailLarge + id: MailSecurityNFMusket + suffix: musket + components: + - type: Mail + contents: + - id: ClothingHeadHatPwig + - id: Musket + - id: CartridgeAntiMateriel + amount: 2 + - id: PaperMailNTMusket + +# Delta Mail + +- type: entity + parent: BaseMail + id: MailSecurityDVSpaceLaw + suffix: spacelaw, extended + components: + - type: Mail + contents: + - id: BookSpaceLaw +# - id: BookSOP #This is where I'd put my Delta SOP book... IF I HAD ONE!!! + - id: PaperMailNFSpaceLaw # Uses the NF space law paper, which is edited to mention the Delta Sector diff --git a/Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml b/Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml new file mode 100644 index 00000000000..e244a14b793 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml @@ -0,0 +1,145 @@ +- type: mailDeliveryPool + id: RandomDeltaVMailDeliveryPool #This entire table is messy as fuck but the weights add up to 35. TODO: ORGANIZE THIS SHIT AAAA + everyone: + MailNFAlcohol: 1 + MailNFBakedGoods: 1 + MailNFBible: 1 + MailNFBikeHorn: 0.5 + MailBooksAll: 1 + MailBlockGameDIY: 0.5 + MailNFBuildABuddy: 0.6 + MailCrayon: 1 + MailNFCake: 1 + MailNFCheese: 1 + MailNFCookies: 1.1 + MailNFCritter: 1 + #Cigarettes - Adds up to 1 in weight + MailNFCigarettes: 0.5 + MailCigars: 0.2 + MailNFJoints: 0.2 + MailNFGoldCigars: 0.1 + #Cosplay - Adds up to 3.4 in weight + MailCosplayArc: 0.5 + MailDVCosplayFakeWizard: 0.5 + MailNFCosplayWizard: 0.5 + MailNFCosplayMaid: 0.5 + MailCosplayGeisha: 0.5 + MailCosplaySchoolgirl: 0.5 + MailNFCosplayNurse: 0.4 + MailNFDonkPockets: 0.5 + MailNFEMP: 0.3 + MailNFFigurineBulk: 1 + MailFishingCap: 0.5 + MailFlashlight: 1 + MailFlowers: 1 + MailNFKendoKit: 0.3 + MailNFKnife: 0.7 + MailNFMuffins: 1 + MailNoir: 0.5 + MailNFPAI: 1.2 + MailNFPlushie: 1 + MailPumpkinPie: 0.3 + MailNFPen: 0.7 + MailRestraints: 0.8 + MailSake: 0.4 + MailNFSnacks: 1 + #Soda - Adds up to 1 in weight + MailNFSodaPwrGame: 0.2 + MailNFSodaRedBool: 0.2 + MailNFSodaSpaceCola: 0.2 + MailNFSodaSpaceMountainWind: 0.2 + MailNFSodaSpaceUp: 0.2 + #End Soda + MailNFSmoke: 0.4 + MailSpaceVillainDIY: 0.5 + MailSignallerKit: 0.5 + MailSunglasses: 1 + MailNFSoaps: 0.5 + MailNFSoapsOmega: 0.5 + MailNFSword: 0.5 + MailNFTacticalMaid: 0.5 + MailNFThrongler: 0.1 + MailNFUnusualClothing: 0.5 + MailNFUnusualFood: 1 + MailNFUnusualProduce: 1 + MailNFVagueThreat: 0.5 + # Mainly for Glacier + MailWinterCoat: 1.5 + + # Department and job-specific mail can have slightly higher weights, + # since they'll be merged with the everyone pool. + departments: + Medical: + MailMedicalBasicSupplies: 2 + MailMedicalChemistrySupplement: 2 + MailMedicalEmergencyPens: 3 + MailMedicalMedicinePills: 2 + MailMedicalSheetPlasma: 1 + # MailMedicalSpaceacillin: 1 + MailMedicalStabilizers: 2 + MailNFMedkit: 2 + Engineering: + MailAMEGuide: 1 + MailEngineeringCables: 2 + MailEngineeringKudzuDeterrent: 2 + MailEngineeringSheetGlass: 2 + MailEngineeringWelderReplacement: 2 + MailNFCircuitboardIndustrial: 2 + MailNFCircuitboardService: 1 + MailNFPowerTool: 1 + Security: + MailSecurityDonuts: 3 + MailSecurityFlashlight: 2 + MailSecurityNonlethalsKit: 2 + MailSecurityDVSpaceLaw: 1 + MailSecurityNFMusket: 1 + Epistemics: +# MailBooks: 1 + MailEpistemologyBluespace: 1 + MailEpistemologyIngotGold: 2 + MailEpistemologyResearchDisk: 1 + MailEpistemologyTinfoilHat: 1 + MailSignallerKit: 1 + # All heads of staff are in Command and not their departments, technically. + # So any items from the departments above that should also be sent to the + # respective department heads should be duplicated below. + Command: + MailCommandPinpointerNuclear: 0.5 + MailStationRepNFNukeDisk: 0.3 + MailCommandNFPipebombIntern: 0.1 + + jobs: + Botanist: + MailBotanistChemicalBottles: 2 + MailBotanistMutagen: 1.5 + MailBotanistSeeds: 1 + ChiefEngineer: + MailEngineeringKudzuDeterrent: 2 + ChiefMedicalOfficer: + MailMedicalEmergencyPens: 2 + MailMedicalMedicinePills: 3 + MailMedicalSheetPlasma: 2 + Clown: + MailClownGildedBikeHorn: 0.5 + MailClownHonkSupplement: 3 + Detective: # Deltav - Detective is in charge of investigating crimes. + MailDetectiveForensicSupplement: 2 # Deltav - Detective is in charge of investigating crimes. + HeadOfPersonnel: + MailHoPBureaucracy: 2 + MailHoPSupplement: 3 + HeadOfSecurity: + MailSecurityNonlethalsKit: 2 + Lawyer: + MailSecurityDVSpaceLaw: 2 + Mime: + MailMimeArtsCrafts: 3 + MailMimeBlankBook: 2 + MailMimeBottleOfNothing: 1 + ResearchDirector: # DeltaV - Epistemics Department replacing Science but keeping their IDs + MailEpistemologyIngotGold: 2 + Musician: + MailMusicianInstrumentSmall: 1 + Passenger: + MailPassengerMoney: 3 + Warden: + MailWardenCrowdControl: 2 \ No newline at end of file diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Vending/Inventories/maildrobe.yml b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Vending/Inventories/maildrobe.yml index 579c57ced4e..27642558244 100644 --- a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Vending/Inventories/maildrobe.yml +++ b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Vending/Inventories/maildrobe.yml @@ -3,6 +3,8 @@ startingInventory: ClothingUniformMailCarrier: 2 ClothingUniformSkirtMailCarrier: 2 + WeaponMailLake: 1 # Frontier + BoxMailCapsulePrimed: 2 # Frontier ClothingHeadMailCarrier: 2 MailBag: 2 ClothingHeadsetCargo: 2 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml index c1ca2cd60b1..0ffa4850806 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml @@ -5,10 +5,12 @@ name: mail-item-name-unaddressed components: - type: Item - size: Normal +# size: Normal # Frontier + storedRotation: -90 - type: Mail - type: AccessReader - type: Sprite + scale: 0.7, 0.7 # Frontier sprite: Nyanotrasen/Objects/Specific/Mail/mail.rsi layers: - state: icon @@ -18,8 +20,8 @@ map: ["enum.MailVisualLayers.FragileStamp"] visible: false - map: ["enum.MailVisualLayers.JobStamp"] - scale: 0.5, 0.5 - offset: 0.275, 0.2 + scale: 0.8, 0.8 # Frontier 0.5<0.8 + offset: 0.225, 0.165 # Frontier (0.275, 0.2)<(0.225, 0.165) - state: locked map: ["enum.MailVisualLayers.Lock"] - state: priority @@ -92,6 +94,16 @@ damage: types: Blunt: 10 + - type: CargoSellBlacklist # Frontier + - type: Food # Frontier - Moth food + requiresSpecialDigestion: true + - type: SolutionContainerManager + solutions: + food: + maxVol: 1 + reagents: + - ReagentId: Nothing + Quantity: 1 # This empty parcel is allowed to exist and evade the tests for the admin # mailto command. diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml index 7f1b26d9cbf..e69de29bb2d 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml @@ -1,835 +0,0 @@ -- type: entity - noSpawn: true - parent: BaseMail - id: MailAlcohol - suffix: alcohol - components: - - type: Mail - contents: - - id: DrinkAbsintheBottleFull - orGroup: Drink - - id: DrinkBlueCuracaoBottleFull - orGroup: Drink - - id: DrinkGinBottleFull - orGroup: Drink - - id: DrinkMelonLiquorBottleFull - orGroup: Drink - - id: DrinkRumBottleFull - orGroup: Drink - - id: DrinkTequilaBottleFull - orGroup: Drink - - id: DrinkVermouthBottleFull - orGroup: Drink - - id: DrinkVodkaBottleFull - orGroup: Drink - - id: DrinkWineBottleFull - orGroup: Drink - - id: DrinkGlass - amount: 2 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSake - suffix: osake - components: - - type: Mail - contents: - - id: DrinkSakeCup - amount: 2 - - id: DrinkTokkuri - -- type: entity - noSpawn: true - parent: BaseMail - id: MailAMEGuide - suffix: ameguide - components: - - type: Mail - contents: - - id: PaperWrittenAMEScribbles - - id: Pen - -- type: entity - noSpawn: true - parent: BaseMail - id: MailBible - suffix: bible - components: - - type: Mail - contents: - - id: Bible - -- type: entity - noSpawn: true - parent: BaseMail - id: MailBikeHorn - suffix: bike horn - components: - - type: Mail - contents: - - id: BikeHorn - -- type: entity - noSpawn: true - parent: BaseMail - id: MailBlockGameDIY - suffix: blockgamediy - components: - - type: Mail - contents: - - id: BlockGameArcadeComputerCircuitboard - -#- type: entity -# noSpawn: true -# parent: BaseMail -# id: MailBooks -# suffix: books -# components: -# - type: Mail -# contents: -# # Don't use BookDemonomiconRandom. -# # It uses a RandomSpawner which just spawns the book outside of the mail. -# - id: BookDemonomicon1 -# orGroup: Demonomicon -# - id: BookDemonomicon2 -# orGroup: Demonomicon -# - id: BookDemonomicon3 -# orGroup: Demonomicon -# # There's no way to signal "spawn nothing" with an orGroup, -# # so have this blank book instead. Write your own demon summoning tome! -# - id: BookRandom -# prob: 3 -# orGroup: Demonomicon -# - id: BookChemistryInsane -# prob: 0.10 -# - id: BookBotanicalTextbook -# prob: 0.5 -# - id: BookFishing -# prob: 0.10 -# - id: BookDetective -# prob: 0.10 -# - id: BookGnominomicon -# prob: 0.2 -# - id: BookFishops # DeltaV - fishops book -# prob: 0.2 -# - id: BookSalvageEpistemics1 -# prob: 0.025 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCake - suffix: cake - components: - - type: Mail - isFragile: true - isPriority: true - contents: - - id: FoodCakeBlueberry - orGroup: Cake - - id: FoodCakeCarrot - orGroup: Cake - - id: FoodCakeCheese - orGroup: Cake - - id: FoodCakeChocolate - orGroup: Cake - - id: FoodCakeChristmas - orGroup: Cake - - id: FoodCakeClown - orGroup: Cake - - id: FoodCakeLemon - orGroup: Cake - - id: FoodCakeLime - orGroup: Cake - - id: FoodCakeOrange - orGroup: Cake - - id: FoodCakePumpkin - orGroup: Cake - - id: FoodCakeVanilla - orGroup: Cake - - id: FoodMothMothmallow - orGroup: Cake - prob: 0.5 - - id: KnifePlastic - - id: ForkPlastic - amount: 2 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCallForHelp - suffix: call-for-help - components: - - type: Mail - contents: - - id: PaperMailCallForHelp1 - orGroup: Paper - - id: PaperMailCallForHelp2 - orGroup: Paper - - id: PaperMailCallForHelp3 - orGroup: Paper - - id: PaperMailCallForHelp4 - orGroup: Paper - - id: PaperMailCallForHelp5 - orGroup: Paper - - id: FlashlightLantern - orGroup: Gift - - id: Crowbar - orGroup: Gift - prob: 0.5 - - id: CrowbarRed - orGroup: Gift - prob: 0.5 - - id: ClothingMaskGas - orGroup: Gift - - id: WeaponFlareGun - orGroup: Gift - prob: 0.25 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCheese - suffix: cheese - components: - - type: Mail - isFragile: true - isPriority: true - contents: - - id: FoodCheese - - id: KnifePlastic - -- type: entity - noSpawn: true - parent: BaseMail - id: MailChocolate - suffix: chocolate - components: - - type: Mail - contents: - # TODO make some actual chocolate candy items. - - id: FoodSnackChocolate - amount: 3 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCigarettes - suffix: cigs - components: - - type: Mail - contents: - - id: CigPackRed - - id: CheapLighter - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCigars - suffix: Cigars - components: - - type: Mail - contents: - - id: CigarCase - - id: Lighter - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCookies - suffix: cookies - components: - - type: Mail - # What, you want to eat stale cookies? - isPriority: true - contents: - - id: FoodBakedCookie - - id: FoodBakedCookieOatmeal - - id: FoodBakedCookieRaisin - - id: FoodBakedCookieSugar - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCosplayArc - suffix: cosplay-arc - components: - - type: Mail - openSound: /Audio/Nyanotrasen/Voice/Felinid/cat_wilhelm.ogg - contents: - - id: ClothingCostumeArcDress - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCosplayGeisha - suffix: cosplay-geisha - components: - - type: Mail - contents: - - id: UniformGeisha - - id: DrinkTeapot - - id: DrinkTeacup - amount: 3 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCosplayMaid - suffix: cosplay-maid - components: - - type: Mail - contents: - - id: UniformMaid - - id: SprayBottleSpaceCleaner - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCosplayNurse - suffix: cosplay-nurse - components: - - type: Mail - contents: - - id: ClothingUniformJumpskirtNurse - - id: Syringe - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCosplaySchoolgirl - suffix: cosplay-schoolgirl - components: - - type: Mail - contents: - - id: UniformSchoolgirlBlack - orGroup: Color - - id: UniformSchoolgirlBlue - orGroup: Color - - id: UniformSchoolgirlCyan - orGroup: Color - - id: UniformSchoolgirlGreen - orGroup: Color - - id: UniformSchoolgirlOrange - orGroup: Color - - id: UniformSchoolgirlPink - orGroup: Color - - id: UniformSchoolgirlPurple - orGroup: Color - - id: UniformSchoolgirlRed - orGroup: Color - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCosplayWizard - suffix: cosplay-wizard - components: - - type: Mail - contents: - - id: ClothingOuterWizardFake - - id: ClothingHeadHatWizardFake - - id: ClothingShoesWizardFake - -- type: entity - noSpawn: true - parent: BaseMail - id: MailCrayon - suffix: Crayon - components: - - type: Mail - contents: - - id: CrayonBox - -- type: entity - noSpawn: true - parent: BaseMail - id: MailFigurine - suffix: figurine - components: - - type: Mail - isFragile: true - contents: - - id: ToyAi - orGroup: Toy - - id: ToyNuke - orGroup: Toy - - id: ToyFigurinePassenger - orGroup: Toy - - id: ToyGriffin - orGroup: Toy - - id: ToyHonk - orGroup: Toy - - id: ToyIan - orGroup: Toy - - id: ToyMarauder - orGroup: Toy - - id: ToyMauler - orGroup: Toy - - id: ToyGygax - orGroup: Toy - - id: ToyOdysseus - orGroup: Toy - - id: ToyOwlman - orGroup: Toy - - id: ToyDeathRipley - orGroup: Toy - - id: ToyPhazon - orGroup: Toy - - id: ToyFireRipley - orGroup: Toy - - id: ToyReticence - orGroup: Toy - - id: ToyRipley - orGroup: Toy - - id: ToySeraph - orGroup: Toy - - id: ToyDurand - orGroup: Toy - -- type: entity - noSpawn: true - parent: BaseMail - id: MailFishingCap - suffix: fishingcap - components: - - type: Mail - contents: - - id: ClothingHeadFishCap - -- type: entity - noSpawn: true - parent: BaseMail - id: MailFlashlight - suffix: Flashlight - components: - - type: Mail - contents: - - id: FlashlightLantern - -#- type: entity -# noSpawn: true -# parent: BaseMail -# id: MailFlowers -# suffix: flowers -# components: -# - type: Mail -# contents: -# # TODO actual flowers -# - id: ClothingHeadHatFlowerCrown -# orGroup: Flower -# - id: ClothingHeadHatHairflower -# orGroup: Flower - -- type: entity - noSpawn: true - parent: BaseMail - id: MailHighlander - suffix: highlander - components: - - type: Mail - contents: - - id: ClothingUniformJumpskirtColorRed - - id: ClothingHeadHatBeret - - id: DrinkRedMeadGlass - - id: Claymore - -- type: entity - noSpawn: true - parent: BaseMail - id: MailHighlanderDulled - suffix: highlander, dulled - components: - - type: Mail - contents: - - id: ClothingUniformJumpskirtColorRed - - id: ClothingHeadHatBeret - - id: DrinkGlass - - id: ClaymoreDulled - -- type: entity - noSpawn: true - parent: BaseMail - id: MailHoneyBuns - suffix: honeybuns - components: - - type: Mail - contents: - - id: FoodBakedBunHoney - amount: 2 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailJunkFood - suffix: junk food - components: - - type: Mail - contents: - - id: FoodBoxDonkpocket - - id: FoodSnackChips - -- type: entity - noSpawn: true - parent: BaseMail - id: MailKatana - suffix: Katana - components: - - type: Mail - contents: - - id: Katana - prob: 0.1 - orGroup: Katana - - id: KatanaDulled - prob: 0.9 - orGroup: Katana - -- type: entity - noSpawn: true - parent: BaseMail - id: MailKnife - suffix: Knife - components: - - type: Mail - contents: - - id: CombatKnife - -- type: entity - noSpawn: true - parent: BaseMail - id: MailMoney - suffix: money - components: - - type: Mail - contents: - - id: SpaceCash100 - orGroup: Cash - prob: 0.3 - - id: SpaceCash500 - orGroup: Cash - prob: 0.6 - - id: SpaceCash1000 - orGroup: Cash - prob: 0.3 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailMuffins - suffix: muffins - components: - - type: Mail - isPriority: true - contents: - - id: FoodBakedMuffinBerry - - id: FoodBakedMuffinCherry - - id: FoodBakedMuffinBluecherry - -- type: entity - noSpawn: true - parent: BaseMail - id: MailMoffins - suffix: moffins - components: - - type: Mail - isPriority: true - contents: - - id: FoodMothMoffin - amount: 3 - -- type: entity - noSpawn: true - parent: BaseMail - id: MailNoir - suffix: noir - components: - - type: Mail - contents: - - id: ClothingUniformJumpsuitDetectiveGrey - - id: ClothingUniformJumpskirtDetectiveGrey - - id: ClothingHeadHatBowlerHat - - id: ClothingOuterCoatGentle - -- type: entity - noSpawn: true - parent: BaseMail - id: MailPAI - suffix: PAI - components: - - type: Mail - contents: - - id: PersonalAI - -- type: entity - noSpawn: true - parent: BaseMail - id: MailPlushie - suffix: plushie - components: - - type: Mail - contents: - - id: PlushieMothRandom - orGroup: Prize - - id: PlushieMothMusician - orGroup: Prize - - id: PlushieMothBartender - orGroup: Prize - - id: PlushieBee - orGroup: Prize - - id: PlushieHampter - orGroup: Prize - - id: PlushieRouny - orGroup: Prize - - id: PlushieLamp - orGroup: Prize - - id: PlushieArachind - orGroup: Prize - - id: PlushieLizard - orGroup: Prize - - id: PlushieLizardMirrored - orGroup: Prize - - id: PlushieSpaceLizard - orGroup: Prize - - id: PlushieDiona - orGroup: Prize - - id: PlushieSharkBlue - orGroup: Prize - - id: PlushieSharkPink - orGroup: Prize - - id: PlushieSharkGrey - orGroup: Prize - - id: PlushieCarp - orGroup: Prize - - id: PlushieMagicarp - orGroup: Prize - - id: PlushieHolocarp - orGroup: Prize - - id: PlushieSlime - orGroup: Prize - - id: PlushieSnake - orGroup: Prize - - id: PlushieVox - orGroup: Prize - - id: PlushieAtmosian - orGroup: Prize - - id: PlushiePenguin - orGroup: Prize - - id: PlushieHuman - orGroup: Prize - - id: PlushieArachne - orGroup: Prize - - id: PlushieGnome - orGroup: Prize - - id: PlushieLoveable - orGroup: Prize - - id: PlushieDeer - orGroup: Prize - - id: PlushieIpc - orGroup: Prize - - id: PlushieGrey - orGroup: Prize - - id: PlushieRedFox - orGroup: Prize - - id: PlushiePurpleFox - orGroup: Prize - - id: PlushiePinkFox - orGroup: Prize - - id: PlushieOrangeFox - orGroup: Prize - - id: PlushieMarbleFox - orGroup: Prize - - id: PlushieCrimsonFox - orGroup: Prize - - id: PlushieCoffeeFox - orGroup: Prize - - id: PlushieBlueFox - orGroup: Prize - - id: PlushieBlackFox - orGroup: Prize - - id: PlushieVulp - orGroup: Prize - - id: PlushieCorgi - orGroup: Prize - - id: PlushieGirlyCorgi - orGroup: Prize - - id: PlushieRobotCorgi - orGroup: Prize - - id: PlushieCatBlack - orGroup: Prize - - id: PlushieCatGrey - orGroup: Prize - - id: PlushieCatOrange - orGroup: Prize - - id: PlushieCatSiames - orGroup: Prize - - id: PlushieCatTabby - orGroup: Prize - - id: PlushieCatTuxedo - orGroup: Prize - - id: PlushieCatWhite - orGroup: Prize - - id: PlushieGhost - orGroup: Prize - - id: PlushieRGBee - orGroup: Prize - - id: PlushieRatvar - orGroup: Prize - - id: PlushieNar - orGroup: Prize - - id: PlushieRainbowCarp - orGroup: Prize - - id: PlushieXeno - orGroup: Prize - - id: PlushieJester - orGroup: Prize - - id: PlushieSlips - orGroup: Prize - - id: PlushieAbductor - orGroup: Prize - - id: PlushieTrystan - orGroup: Prize - - id: PlushieAbductorAgent - orGroup: Prize - - id: PlushieNuke - orGroup: Prize - -- type: entity - noSpawn: true - parent: BaseMail - id: MailRestraints - suffix: restraints - components: - - type: Mail - contents: - - id: Handcuffs - - id: ClothingMaskMuzzle - - id: ClothingEyesBlindfold - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSignallerKit - suffix: signallerkit - components: - - type: Mail - contents: - - id: Multitool - - id: RemoteSignaller - -# - type: entity -# noSpawn: true -# parent: BaseMail -# id: MailSixPack -# suffix: sixpack -# components: -# - type: Mail -# contents: -# - id: DrinkCanPack - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSkub - suffix: skub - components: - - type: Mail - contents: - - id: Skub - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSoda - suffix: soda - components: - - type: Mail - contents: - - id: DrinkColaBottleFull - orGroup: Soda - - id: DrinkSpaceMountainWindBottleFull - orGroup: Soda - - id: DrinkSpaceUpBottleFull - orGroup: Soda - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSpaceVillainDIY - suffix: spacevilliandiy - components: - - type: Mail - contents: - - id: SpaceVillainArcadeComputerCircuitboard - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSunglasses - suffix: Sunglasses - components: - - type: Mail - contents: - - id: ClothingEyesGlassesSunglasses - -- type: entity - noSpawn: true - parent: BaseMail - id: MailVagueThreat - suffix: vague-threat - components: - - type: Mail - contents: - - id: PaperMailVagueThreat1 - orGroup: Paper - - id: PaperMailVagueThreat2 - orGroup: Paper - - id: PaperMailVagueThreat3 - orGroup: Paper - - id: PaperMailVagueThreat4 - orGroup: Paper - - id: PaperMailVagueThreat5 - orGroup: Paper - - id: PaperMailVagueThreat6 - orGroup: Paper - - id: PaperMailVagueThreat7 - orGroup: Paper - - id: PaperMailVagueThreat8 - orGroup: Paper - - id: PaperMailVagueThreat9 - orGroup: Paper - - id: PaperMailVagueThreat10 - orGroup: Paper - - id: PaperMailVagueThreat11 - orGroup: Paper - - id: PaperMailVagueThreat12 - orGroup: Paper - - id: KitchenKnife - orGroup: ThreateningObject - - id: ButchCleaver - orGroup: ThreateningObject - - id: CombatKnife - orGroup: ThreateningObject - - id: SurvivalKnife - orGroup: ThreateningObject - - id: SoapHomemade - orGroup: ThreateningObject - - id: FoodMeat - orGroup: ThreateningObject - - id: OrganHumanHeart - orGroup: ThreateningObject - -- type: entity - noSpawn: true - parent: BaseMail - id: MailWinterCoat - suffix: wintercoat - components: - - type: Mail - contents: - - id: ClothingOuterWinterCoat - orGroup: Coat - - id: ClothingOuterWinterCoatLong - orGroup: Coat - - id: ClothingOuterWinterCoatPlaid - orGroup: Coat diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml index 7e2a935f908..e69de29bb2d 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml @@ -1,9 +0,0 @@ -- type: entity - noSpawn: true - parent: BaseMail - id: MailCommandPinpointerNuclear - suffix: pinpointernuclear - components: - - type: Mail - contents: - - id: PinpointerNuclear diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_engineering.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_engineering.yml index 461d9bf1365..e69de29bb2d 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_engineering.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_engineering.yml @@ -1,45 +0,0 @@ -- type: entity - noSpawn: true - parent: BaseMail - id: MailEngineeringCables - suffix: cables - components: - - type: Mail - contents: - - id: CableHVStack - orGroup: Cables - - id: CableMVStack - orGroup: Cables - - id: CableApcStack - orGroup: Cables - -- type: entity - noSpawn: true - parent: BaseMail - id: MailEngineeringKudzuDeterrent - suffix: antikudzu - components: - - type: Mail - contents: - - id: PlantBGoneSpray - -- type: entity - noSpawn: true - parent: BaseMail - id: MailEngineeringSheetGlass - suffix: sheetglass - components: - - type: Mail - contents: - - id: SheetGlass - -- type: entity - noSpawn: true - parent: BaseMail - id: MailEngineeringWelderReplacement - suffix: welder - components: - - type: Mail - contents: - - id: Welder - diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml index b47d5af56e3..e69de29bb2d 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml @@ -1,56 +0,0 @@ -- type: entity - noSpawn: true - parent: BaseMail - id: MailSecurityDonuts - suffix: donuts - components: - - type: Mail - contents: - - id: FoodBoxDonut - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSecurityFlashlight - suffix: seclite - components: - - type: Mail - contents: - - id: FlashlightSeclite - -- type: entity - noSpawn: true - parent: BaseMail - id: MailSecurityNonlethalsKit - suffix: nonlethalskit - components: - - type: Mail - contents: - - id: Flash - maxAmount: 2 - - id: GrenadeFlashBang - maxAmount: 2 - - id: Handcuffs - maxAmount: 2 - -#- type: entity -# noSpawn: true -# parent: BaseMail -# id: MailSecuritySpaceLaw -# suffix: spacelaw -# components: -# - type: Mail -# contents: -# - id: HyperlinkBookSpaceLaw -# Will we ever readd hyperlinks books? Who knows! - -- type: entity - noSpawn: true - parent: BaseMail - id: MailWardenCrowdControl - suffix: crowdcontrol - components: - - type: Mail - contents: - - id: BoxBeanbag - diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_specific_items.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_specific_items.yml index b4d2b547798..e69de29bb2d 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_specific_items.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_specific_items.yml @@ -1,169 +0,0 @@ -- type: entity - id: PaperMailCallForHelp1 - noSpawn: true - suffix: "call for help 1" - parent: Paper - components: - - type: Paper - content: | - Help! They're coming! Take this! - -- type: entity - id: PaperMailCallForHelp2 - noSpawn: true - suffix: "call for help 2" - parent: Paper - components: - - type: Paper - content: | - Check disposals! - -- type: entity - id: PaperMailCallForHelp3 - noSpawn: true - suffix: "call for help 3" - parent: Paper - components: - - type: Paper - content: | - GET ME OUT! - -- type: entity - id: PaperMailCallForHelp4 - noSpawn: true - suffix: "call for help 4" - parent: Paper - components: - - type: Paper - content: | - Check maintenance! - -- type: entity - id: PaperMailCallForHelp5 - noSpawn: true - suffix: "call for help 5" - parent: Paper - components: - - type: Paper - content: | - Save me, please! - -- type: entity - id: PaperMailVagueThreat1 - noSpawn: true - suffix: "vague mail threat 1" - parent: Paper - components: - - type: Paper - content: | - I know what you did. You don't know what I'm going to do to you. - -- type: entity - id: PaperMailVagueThreat2 - noSpawn: true - suffix: "vague mail threat 2" - parent: Paper - components: - - type: Paper - content: | - I'm coming for you. - -- type: entity - id: PaperMailVagueThreat3 - noSpawn: true - suffix: "vague mail threat 3" - parent: Paper - components: - - type: Paper - content: | - You're next. - -- type: entity - id: PaperMailVagueThreat4 - noSpawn: true - suffix: "vague mail threat 4" - parent: Paper - components: - - type: Paper - content: | - We see you. - -- type: entity - id: PaperMailVagueThreat5 - noSpawn: true - suffix: "vague mail threat 5" - parent: Paper - components: - - type: Paper - content: | - I hope your affairs are in order. - -- type: entity - id: PaperMailVagueThreat6 - noSpawn: true - suffix: "vague mail threat 6" - parent: Paper - components: - - type: Paper - content: | - It's only a matter of time. Enjoy it while it lasts. - -- type: entity - id: PaperMailVagueThreat7 - noSpawn: true - suffix: "vague mail threat 7" - parent: Paper - components: - - type: Paper - content: | - Who should we mail your pieces to? - -- type: entity - id: PaperMailVagueThreat8 - noSpawn: true - suffix: "vague mail threat 8" - parent: Paper - components: - - type: Paper - content: | - Do you prefer to die slowly or quickly? Just kidding. We don't care what you think. - -- type: entity - id: PaperMailVagueThreat9 - noSpawn: true - suffix: "vague mail threat 9" - parent: Paper - components: - - type: Paper - content: | - I think your head would look nice on my mantel. - -- type: entity - id: PaperMailVagueThreat10 - noSpawn: true - suffix: "vague mail threat 10" - parent: Paper - components: - - type: Paper - content: | - You should have paid up. It's too late now. - -- type: entity - id: PaperMailVagueThreat11 - noSpawn: true - suffix: "vague mail threat 11" - parent: Paper - components: - - type: Paper - content: | - Your family will miss you, but don't worry. We'll take care of them too. - -- type: entity - id: PaperMailVagueThreat12 - noSpawn: true - suffix: "vague mail threat 12" - parent: Paper - components: - - type: Paper - content: | - I have a bet that you're going to die today. I'm not afraid of cheating. diff --git a/Resources/Prototypes/_NF/Entities/Objects/Misc/mail_capsule.yml b/Resources/Prototypes/_NF/Entities/Objects/Misc/mail_capsule.yml new file mode 100644 index 00000000000..29e0df57869 --- /dev/null +++ b/Resources/Prototypes/_NF/Entities/Objects/Misc/mail_capsule.yml @@ -0,0 +1,139 @@ +- type: entity + name: mail capsule + suffix: Primed + id: MailCapsulePrimed + parent: BaseItem + components: + - type: ThrowingAngle + angle: 180 + - type: EmbeddableProjectile + minimumSpeed: 1 + removalTime: 0.1 + - type: Tag + tags: + - MailCapsule + - Trash + - type: Sprite + sprite: _NF/Objects/Misc/mail_capsule.rsi + layers: + - state: icon-empty + - type: ItemSlots + slots: + mail_slot: + insertVerbText: Put in Mail + ejectVerbText: Take out Mail + name: Mail + startingItem: null + whitelist: + tags: + - Book + - Document + - Mail + components: + - Mail + - Paper + - HyperlinkBook + insertOnInteract: true + priority: 3 + food_slot: + insertVerbText: Put in Food + ejectVerbText: Take out Food + name: Food + startingItem: null + whitelist: + components: + - Food + insertOnInteract: true + priority: 2 + cash_slot: + insertVerbText: Put in Cash + ejectVerbText: Take out Cash + name: Cash + startingItem: null + whitelist: + components: + - Currency + insertOnInteract: true + priority: 1 + - type: ContainerContainer + containers: + storagebase: !type:Container + showEnts: False + occludes: true + ents: [] + mail_slot: !type:ContainerSlot + showEnts: False + occludes: true + ent: null + food_slot: !type:ContainerSlot + showEnts: False + occludes: true + ent: null + cash_slot: !type:ContainerSlot + showEnts: False + occludes: true + ent: null + - type: Appearance + - type: ItemMapper + mapLayers: + icon-food: + whitelist: + components: + - Food + icon-cash: + whitelist: + components: + - Currency + icon-mail: + whitelist: + tags: + - Book + - Document + - Mail + components: + - Mail + - Paper + - HyperlinkBook + sprite: _NF/Objects/Misc/mail_capsule.rsi + - type: Dumpable + - type: Damageable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 20 #excess damage avoids cost of spawning entities. + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + - !type:EmptyAllContainersBehaviour + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: DamageOnLand + damage: + types: + Blunt: 9.5 + +- type: entity + name: mail capsule box + parent: BoxCardboard + id: BoxMailCapsulePrimed + description: A box of primed mail capsules. + components: + - type: Storage + grid: + - 0,0,4,3 + - type: StorageFill + contents: + - id: MailCapsulePrimed + amount: 10 + - type: Sprite + layers: + - state: box diff --git a/Resources/Prototypes/_NF/Entities/Objects/Specific/Mail/base_mail_large.yml b/Resources/Prototypes/_NF/Entities/Objects/Specific/Mail/base_mail_large.yml new file mode 100644 index 00000000000..3ba4cfd64e0 --- /dev/null +++ b/Resources/Prototypes/_NF/Entities/Objects/Specific/Mail/base_mail_large.yml @@ -0,0 +1,79 @@ +# Large packages. +- type: entity + parent: BaseMail + abstract: true + id: BaseMailLarge + name: mail-large-item-name-unaddressed + components: + - type: Item + size: Ginormous + - type: Sprite + scale: 0.8, 0.8 + sprite: _NF/Objects/Specific/Mail/mail_large.rsi + layers: + - state: icon + map: ["enum.MailVisualLayers.Icon"] + - state: fragile + map: ["enum.MailVisualLayers.FragileStamp"] + visible: false + - map: ["enum.MailVisualLayers.JobStamp"] + scale: 0.8, 0.8 + offset: 0.235, -0.01 + - state: locked + map: ["enum.MailVisualLayers.Lock"] + - state: priority + map: ["enum.MailVisualLayers.PriorityTape"] + visible: false + shader: unshaded + - state: broken + map: ["enum.MailVisualLayers.Breakage"] + visible: false + - type: GenericVisualizer + visuals: + enum.MailVisuals.IsTrash: + enum.MailVisualLayers.Icon: + True: + state: trash + False: + state: icon + enum.MailVisuals.IsLocked: + enum.MailVisualLayers.Lock: + True: + visible: true + False: + visible: false + enum.MailVisuals.IsFragile: + enum.MailVisualLayers.FragileStamp: + True: + visible: true + False: + visible: false + enum.MailVisuals.IsPriority: + enum.MailVisualLayers.PriorityTape: + True: + visible: true + False: + visible: false + enum.MailVisuals.IsPriorityInactive: + enum.MailVisualLayers.PriorityTape: + True: + shader: shaded + state: priority_inactive + False: + shader: unshaded + state: priority + enum.MailVisuals.IsBroken: + enum.MailVisualLayers.Breakage: + True: + visible: true + False: + visible: false + - type: MultiHandedItem + - type: Mail + isLarge: true + +- type: entity + noSpawn: true + parent: BaseMailLarge + id: MailLargeAdminFun + suffix: adminfun diff --git a/Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml new file mode 100644 index 00000000000..2804953fcfc --- /dev/null +++ b/Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -0,0 +1,24 @@ +- type: entity + name: mail RPDS + parent: WeaponLauncherChinaLake + id: WeaponMailLake + description: Rap(b?)id Parcel Delivery System + components: + - type: Sprite + sprite: _NF/Objects/Weapons/Guns/Launchers/mail.rsi + layers: + - state: icon + map: ["enum.GunVisualLayers.Base"] + - type: Clothing + sprite: _NF/Objects/Weapons/Guns/Launchers/mail.rsi + quickEquip: false + slots: + - Back + - Belt + - suitStorage + - type: BallisticAmmoProvider + proto: null + whitelist: + tags: + - MailCapsule + capacity: 4 diff --git a/Resources/Prototypes/_NF/Mail/Items/boxes.yml b/Resources/Prototypes/_NF/Mail/Items/boxes.yml new file mode 100644 index 00000000000..d61dc6c1488 --- /dev/null +++ b/Resources/Prototypes/_NF/Mail/Items/boxes.yml @@ -0,0 +1,212 @@ +# Mail-only boxes. If/when something uses these outside of the mail, move the entry into Catalog/Fills. + +- type: entity + name: scented soap sampler pack + parent: BoxCardboard + id: BoxSoapsAssorted + description: A box of various scented soaps. Ooh, lavender. + components: + - type: StorageFill + contents: + - id: SoapNT + amount: 1 + - id: Soap + amount: 1 + - id: SoapHomemade + amount: 1 + - id: SoapDeluxe + amount: 1 + - type: Storage + maxItemSize: Normal + grid: + - 0,0,3,1 + whitelist: + tags: + - Soap + - type: Sprite + layers: + - state: box + +- type: entity + name: scented soap sampler pack + parent: BoxCardboard + id: BoxSoapsAssortedOmega + description: A box of various scented soaps. Ooh, bluespace. + components: + - type: StorageFill + contents: + - id: SoapNT + amount: 1 + - id: Soap + amount: 1 + - id: SoapOmega + amount: 1 + - id: SoapDeluxe + amount: 1 + - type: Storage + maxItemSize: Normal + grid: + - 0,0,3,1 + whitelist: + tags: + - Soap + - type: Sprite + layers: + - state: box + +- type: entity + name: Build-a-Buddy kit + suffix: Human + parent: BoxHug + id: BoxBuildABuddyHuman + description: "\"Henry the Human\" Build-a-Buddy kit. Some assembly required." + components: + - type: StorageFill + contents: + - id: HeadHuman + amount: 1 + - id: TorsoHuman + amount: 1 + - id: LeftArmHuman + amount: 1 + - id: RightArmHuman + amount: 1 + - id: LeftHandHuman + amount: 1 + - id: RightHandHuman + amount: 1 + - id: LeftLegHuman + amount: 1 + - id: RightLegHuman + amount: 1 + - id: LeftFootHuman + amount: 1 + - id: RightFootHuman + amount: 1 + - type: Storage + grid: + - 0,0,4,3 + whitelist: + components: + - BodyPart + +# DeltaV - Goblins Aren't Real +#- type: entity +# name: Build-a-Buddy kit +# suffix: Goblin +# parent: BoxBuildABuddyHuman +# id: BoxBuildABuddyGoblin +# description: "\"Greta the Goblin\" Build-a-Buddy kit. Some assembly required." +# components: +# - type: StorageFill +# contents: +# - id: HeadGoblin +# amount: 1 +# - id: TorsoGoblin +# amount: 1 +# - id: LeftArmGoblin +# amount: 1 +# - id: RightArmGoblin +# amount: 1 +# - id: LeftHandGoblin +# amount: 1 +# - id: RightHandGoblin +# amount: 1 +# - id: LeftLegGoblin +# amount: 1 +# - id: RightLegGoblin +# amount: 1 +# - id: LeftFootGoblin +# amount: 1 +# - id: RightFootGoblin +# amount: 1 + +- type: entity + name: Build-a-Buddy kit + suffix: Reptilian + parent: BoxBuildABuddyHuman + id: BoxBuildABuddyReptilian + description: "\"Randy the Reptilian\" Build-a-Buddy kit. Some assembly required." + components: + - type: StorageFill + contents: + - id: HeadReptilian + amount: 1 + - id: TorsoReptilian + amount: 1 + - id: LeftArmReptilian + amount: 1 + - id: RightArmReptilian + amount: 1 + - id: LeftHandReptilian + amount: 1 + - id: RightHandReptilian + amount: 1 + - id: LeftLegReptilian + amount: 1 + - id: RightLegReptilian + amount: 1 + - id: LeftFootReptilian + amount: 1 + - id: RightFootReptilian + amount: 1 + +- type: entity + name: Build-a-Buddy kit + suffix: Slime + parent: BoxBuildABuddyHuman + id: BoxBuildABuddySlime + description: "\"Steven the Slime\" Build-a-Buddy kit. Some assembly required." + components: + - type: StorageFill + contents: + - id: HeadSlime + amount: 1 + - id: TorsoSlime + amount: 1 + - id: LeftArmSlime + amount: 1 + - id: RightArmSlime + amount: 1 + - id: LeftHandSlime + amount: 1 + - id: RightHandSlime + amount: 1 + - id: LeftLegSlime + amount: 1 + - id: RightLegSlime + amount: 1 + - id: LeftFootSlime + amount: 1 + - id: RightFootSlime + amount: 1 + +- type: entity + name: Build-a-Buddy kit + suffix: Vulpkanin + parent: BoxBuildABuddyHuman + id: BoxBuildABuddyVulpkanin + description: "\"Valerie the Vulpkanin\" Build-a-Buddy kit. Some assembly required." + components: + - type: StorageFill + contents: + - id: HeadVulpkanin + amount: 1 + - id: TorsoVulpkanin + amount: 1 + - id: LeftArmVulpkanin + amount: 1 + - id: RightArmVulpkanin + amount: 1 + - id: LeftHandVulpkanin + amount: 1 + - id: RightHandVulpkanin + amount: 1 + - id: LeftLegVulpkanin + amount: 1 + - id: RightLegVulpkanin + amount: 1 + - id: LeftFootVulpkanin + amount: 1 + - id: RightFootVulpkanin + amount: 1 diff --git a/Resources/Prototypes/_NF/Mail/Items/misc.yml b/Resources/Prototypes/_NF/Mail/Items/misc.yml new file mode 100644 index 00000000000..98af182c6c4 --- /dev/null +++ b/Resources/Prototypes/_NF/Mail/Items/misc.yml @@ -0,0 +1,117 @@ +# Mail-only items. If/when these get used for anything else, please move them to another folder. +# Pranks: admin items or effects put into an envelope, released when opened or damaged. +- type: entity + id: DelayedSmoke + parent: BaseItem + noSpawn: true + name: delayed smoke + suffix: "(10s)" + components: + - type: Sprite #DeltaV: Apparently these want sprites, probably because they're baseitems + sprite: /Textures/Objects/Fun/goldbikehorn.rsi + visible: false + state: icon + - type: DelayedItem + item: AdminInstantEffectSmoke10 + +- type: entity + id: AdminInstantEffectEMP7 + noSpawn: true + suffix: EMP, 7 meters + parent: AdminInstantEffectBase + components: + - type: EmpOnTrigger + range: 7 + energyConsumption: 50000 + +- type: entity + id: DelayedEMP + parent: BaseItem + noSpawn: true + name: delayed EMP (7 meters) + components: + - type: Sprite #DeltaV: Apparently these want sprites, probably because they're baseitems + sprite: /Textures/Objects/Fun/goldbikehorn.rsi + visible: false + state: icon + - type: DelayedItem + item: AdminInstantEffectEMP7 + +# Miscellaneous Items + +- type: entity + id: SyringeCognizine + parent: Syringe + name: cognizine syringe + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 15 + reagents: + - ReagentId: Cognizine + Quantity: 15 # Surely three friends is enough. + +- type: entity + id: SyringeOpporozidone + parent: Syringe + name: opporozidone syringe + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 15 + reagents: + - ReagentId: Opporozidone + Quantity: 15 + +- type: entity + id: NecrosolChemistryBottle + parent: BaseChemistryBottleFilled + name: necrosol bottle + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: Necrosol + Quantity: 30 + +# Premium Alcohol: wait, it's just marketing? +# TODO: different sprites would be nice. +- type: entity + id: DrinkPremiumVodkaBottleFull + parent: DrinkVodkaBottleFull + name: Moment of Clarity vodka bottle + description: When things get a bit hectic, all you need is a Moment of Clarity. + +- type: entity + id: DrinkPremiumGinBottleFull + parent: DrinkGinBottleFull + name: Harry's gin bottle + description: An interesting set of botanicals, for sure. Is that pumpkin? + +- type: entity + id: DrinkPremiumTequilaBottleFull + parent: DrinkTequilaBottleFull + name: Casa del Eorg tequila bottle + description: Save the best for last. Casa del Eorg, 100% agave. + +- type: entity + id: DrinkPremiumWhiskeyBottleFull + parent: DrinkWhiskeyBottleFull + name: Ol' Prowler 18 whiskey bottle + description: Surprisingly smooth, it has a nasty habit of sneaking up on you. + +- type: entity + id: DrinkPremiumRumBottleFull + parent: DrinkRumBottleFull + name: Redeemer's Bounty rum bottle + description: Well, you asked for it. Navy strength. + +- type: entity + id: DrinkPremiumAbsintheBottleFull + parent: DrinkAbsintheBottleFull + name: Bureaucracy's Kiss absinthe bottle + description: A refined taste that tends to linger. diff --git a/Resources/Prototypes/_NF/Mail/Items/paper.yml b/Resources/Prototypes/_NF/Mail/Items/paper.yml new file mode 100644 index 00000000000..b21ca407173 --- /dev/null +++ b/Resources/Prototypes/_NF/Mail/Items/paper.yml @@ -0,0 +1,483 @@ +# Papers (letters, ad copy) +# TODO: these should really be based on localization strings. +- type: entity + id: PaperMailNFPowerTool + name: Hazard Fraught advertisement + categories: [ HideSpawnMenu ] + suffix: "power tool ad, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]Hazard Fraught Tools[/head] + + [head=2]Discount Tools at Quality Prices![/head] + + [head=2]Fax us for a catalog at + [color=#990000]ERROR: UNEXPECTED EOF[/color][/head] + +- type: entity + id: PaperMailNFVagueThreat1 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 1, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]I know what you did.[/head] + + [head=3]You don't know what I'm going to do to you.[/head] + +- type: entity + id: PaperMailNFVagueThreat2 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 2, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]I'm coming for you.[/head] + +- type: entity + id: PaperMailNFVagueThreat3 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 3, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]You're next.[/head] + +- type: entity + id: PaperMailNFVagueThreat4 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 4, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]We see you.[/head] + +- type: entity + id: PaperMailNFVagueThreat5 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 5, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=2]I hope your affairs are in order.[/head] + +- type: entity + id: PaperMailNFVagueThreat6 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 6, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]It's only a matter of time.[/head] + + + [head=1]Enjoy it while it lasts.[/head] + +- type: entity + id: PaperMailNFVagueThreat7 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 7, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=2]Who should we mail your pieces to?[/head] + +- type: entity + id: PaperMailNFVagueThreat8 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 8, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=2]Would you prefer to die slowly or quickly? + [/head] + [head=1]Just kidding.[/head] + + [head=2]We don't care what you think.[/head] + +- type: entity + id: PaperMailNFVagueThreat9 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 9, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=3]I think your head would look nice on my mantel.[/head] + +- type: entity + id: PaperMailNFVagueThreat10 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 10, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]You should have paid up.[/head] + + + [head=1]It's too late now.[/head] + +- type: entity + id: PaperMailNFVagueThreat11 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 11, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=3]Your family will miss you, but don't worry.[/head] + + + [head=1]We'll take care of them too.[/head] + +- type: entity + id: PaperMailNFVagueThreat12 + categories: [ HideSpawnMenu ] + suffix: "vague mail threat 12, formatted" + parent: Paper + components: + - type: Paper + content: |2 + + [head=3]I have a bet that you're going to die today.[/head] + + + [head=1]I'm not afraid to cheat.[/head] + +- type: entity + id: PaperMailNFPwrGameAd + name: pwr game advertisement + categories: [ HideSpawnMenu ] + suffix: "pwr game ad" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]Drink Pwr Game![/head] + + [head=3]Proud sponsor of the NT Block Game Championship.[/head] + +- type: entity + id: PaperMailNFRedBoolAd + name: red bool advertisement + categories: [ HideSpawnMenu ] + suffix: "red bool ad" + parent: Paper + components: + - type: Paper + content: |2 + + [head=2]Try NEW Reformulated Red Bool![/head] + + [head=2]Over [color=#dd0000]1.5g[/color] of caffeine per can![/head] + + [head=2]Punch your heart into overdrive![/head] + +- type: entity + id: PaperMailNFSpaceColaAd + name: space cola advertisement + categories: [ HideSpawnMenu ] + suffix: "space cola ad" + parent: Paper + components: + - type: Paper + content: |2 + + [head=2]The classic taste you love, Space Cola.[/head] + + [head=2]Now certified lead-free.[/head] + +- type: entity + id: PaperMailNFSpaceMountainWindAd + name: space mountain wind advertisement + categories: [ HideSpawnMenu ] + suffix: "space mountain wind ad" + parent: Paper + components: + - type: Paper + content: |2 + + [head=3]When it's time to game, there's one choice:[/head] + + [head=1]Space Mountain Wind.[/head] + +- type: entity + id: PaperMailNFSpaceUpAd + name: space up advertisement + categories: [ HideSpawnMenu ] + suffix: "space up ad" + parent: Paper + components: + - type: Paper + content: |2 + + [head=3]The crisp, refreshing taste of lemon and lime.[/head] + + + [head=1]Space Up![/head] + + + [head=2]Ask your barkeep for a Sui Dream today![/head] + +- type: entity + id: PaperMailNTSoapAd1 + categories: [ HideSpawnMenu ] + suffix: "soap ad 1" + parent: Paper + components: + - type: Paper + stampedBy: + - stampedColor: '#333333FF' + stampedName: Christopher Cleanman +# stampType: Signature #DeltaV - Not compatible with our signatures code stuff apparently + content: |2 + [head=3]Hello Valued Customer,[/head] + You have been selected to receive a complimentary sampler of scented soaps that Nanotrasen has to offer. + + Why not enjoy a nice warm shower with our scented soaps? Tested and effective vs. vent crud and mold. + + We hope you enjoy. + + Sincerely, + Christopher Cleanman, Vice President, NT Habs - Toiletries Dept. + +- type: entity + id: PaperMailNTSoapAd2 + categories: [ HideSpawnMenu ] + suffix: "soap ad 2" #DeltaV - Edited to not be addressed to Frontier Citizens, localized + parent: Paper + components: + - type: Paper + content: |2 + [head=2]GREETINGS DELTA SECTOR CITIZEN[/head] + + OUR REPORTS INDICATE THAT: + 1. YOU HAVE FAILED YOUR QUARTERLY HYGIENE INSPECTION. + 2. THIS HAS REDUCED SECTOR EFFICIENCY BY [bold]0.02%[/bold]. + + ENCLOSED IS A SELECTION OF HYGIENE PRODUCTS SUITABLE FOR USE BY ORGANICS. WE HOPE THAT THIS SITUATION IS RESOLVED PROMPTLY. + + [italic]THIS IS AN AUTOMATED MESSAGE. DO NOT REPLY.[/italic] + +- type: entity + id: PaperMailNTConscript + categories: [ HideSpawnMenu ] + suffix: "conscript" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]NOT ONE STEP BACK.[/head] + + + [head=1]FOR THE FRONTIER.[/head] + +- type: entity + id: PaperMailNTMusket + categories: [ HideSpawnMenu ] + suffix: "musket" + parent: Paper + components: + - type: Paper + content: |2 + + [head=2]Use a musket for sector defense, + like the founding fathers intended.[/head] + +- type: entity + id: PaperMailNFPaperPusherAd + categories: [ HideSpawnMenu ] + suffix: "paper pusher" + parent: Paper + components: + - type: Paper + content: |2 + + [head=2]Here is a pen for any letters you write. + [/head] + [head=1]Keep it close, use it often.[/head] + + [head=2]May you write well, neatly, and with style.[/head] + + [head=3]Sincerely, + [italic]The Frontier Paper Pusher's Club[/italic][/head] + +- type: entity + id: PaperMailNFPetBedAssemblyManual + name: pet bed assembly manual + categories: [ HideSpawnMenu ] + suffix: "pet bed assembly manual" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]HÖGANÄS[/head] + + [italic](There is a black and white picture of a pet bed on the first page.)[/italic] + + [italic](On the next few pages, you see a list of materials and a happy stick figure assembling furniture.)[/italic] + + [italic](On the pages after that, you see a set of instructions to assemble a pet bed. You're sure you don't need them, how hard could it be?)[/italic] + +- type: entity + id: PaperMailNTBoxer + categories: [ HideSpawnMenu ] + suffix: "boxer" + parent: Paper + components: + - type: Paper + content: |2 + [head=2]You've gotta defend your belt, champ. + [/head] + [head=1]They're coming for you.[/head] + + [head=2]This should help. Knock 'em out.[/head] + +# Placeholder for an arm-on-use, flashbang fakeout pipebomb +- type: entity + id: PaperMailNFPipebombIntern + categories: [ HideSpawnMenu ] + suffix: "pipe bomb intern" + parent: Paper + components: + - type: Paper + stampedBy: + - stampedColor: '#333333FF' + stampedName: craig +# stampType: Signature #DeltaV - Not compatible with our signatures code stuff apparently + content: |2 + [bold]hey uh, they told me to send you a pipebomb i guess? + + this is all i could find around here, hope that works + + thanks[/bold] + +- type: entity + id: PaperMailNFAntivirus + name: Snortin Antivirus invoice + categories: [ HideSpawnMenu ] + suffix: "antivirus ad" + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]Invoice[/head][head=3] + Snortin Antivirus Software[/head] + + [head=3]Order #41003 + [bold][bullet/][/bold] 1x Snortin Total-275 Antivirus Install Disk[/head] + + [head=3]Total: 947381 Spesos[/head] + + Thank you for making purchase from Snortin Antivirus Software. + We assuring you that our product is greatest. + Please sending payment at earliest convenience. + +- type: entity + id: PaperMailNFEMPPreparedness + categories: [ HideSpawnMenu ] + name: EMP preparedness response form + suffix: "emp preparedness" #DeltaV - Replaces mention of SR with HoS + parent: Paper + components: + - type: Paper + content: |2 + + [head=1]EMP Preparedness Response[/head] + + You have been selected to receive a NT EMP Preparedness kit as a test. Note that this is only a test. In a real emergency, follow the instructions of your vessel's command staff. + + As the recipient of this, please note [bold]any improvements[/bold] that could be made towards the EMP preparedness of the vessel you were aboard when opening and submit this form to your serving Captain or Head of Security. + + [bold]Date of test:[/bold] + [bold]Number of affected items:[/bold] + [bold]Perceived severity of incident:[/bold] + [bold]Suggested improvements:[/bold] + +- type: entity + id: PaperMailNFBuildABuddy + categories: [ HideSpawnMenu ] + name: Build-a-Buddy adoption letter + suffix: "build-a-buddy" #DeltaV- Body text changed, because Goblins Aren't Real + parent: Paper + components: + - type: Paper + stampState: paper_stamp-generic + stampedBy: + - stampedColor: '#FF6699FF' + stampedName: Chief Friendship Officer + - stampedColor: '#333333FF' + stampedName: Cuts-With-Scalpel +# stampType: Signature #DeltaV - Not compatible with our signatures code stuff apparently. + content: |2 + + [head=1]Note of Adoption[/head] + + You're now the proud owner of your very own Build-a-Buddy! + + We hope that your new friend can serve as a shoulder to lean on in the depths of space, and hopefully you won't be quite as lonely out there. Personally, I find putting them together to be rather therapeutic. + + [bold]Collect the whole set![/bold] + [bold][bullet/][/bold] Henry the Human + [bold][bullet/][/bold] Randy the Reptilian + [bold][bullet/][/bold] Steven the Slime + [bold][bullet/][/bold] Valerie the Vulpkanin + +- type: entity + id: PaperMailNFSpaceLaw + categories: [ HideSpawnMenu ] + suffix: "space-law" #DeltaV- edited contents to be from the Delta Sector instead of the Frontier + parent: Paper + components: + - type: Paper + stampState: paper_stamp-centcom + stampedBy: + - stampedColor: '#006600FF' + stampedName: Central Admiralty of the Delta Sector + content: |2 + + [head=1]Space Law is your shield.[/head] + + [head=2]With it, you guard the Delta Sector.[/head][head=3] + [/head] + [head=1]Memorize it. Grasp it firmly.[/head] + + [head=2]The SOP is your sword, don't get rusty.[/head] + + [head=2]Maintain your balance, and wield it well.[/head] + + + + + + + + + [head=3][italic]Internal Bureau of Propaganda[/italic][/head] diff --git a/Resources/Prototypes/_NF/Recipes/Lathes/misc.yml b/Resources/Prototypes/_NF/Recipes/Lathes/misc.yml new file mode 100644 index 00000000000..22e1f9605f7 --- /dev/null +++ b/Resources/Prototypes/_NF/Recipes/Lathes/misc.yml @@ -0,0 +1,15 @@ +- type: latheRecipe + id: ClothingShoesBootsMagAdv + result: ClothingShoesBootsMagAdv + completetime: 12 + materials: + Silver: 1000 + Gold: 500 + +- type: latheRecipe + id: MailCapsule + result: MailCapsulePrimed + completetime: 1 + materials: + Glass: 100 + Plastic: 100 \ No newline at end of file diff --git a/Resources/Prototypes/_NF/tags.yml b/Resources/Prototypes/_NF/tags.yml new file mode 100644 index 00000000000..6264405762b --- /dev/null +++ b/Resources/Prototypes/_NF/tags.yml @@ -0,0 +1,56 @@ +- type: Tag + id: CaveFactory + +- type: Tag + id: DockTransit + +- type: Tag + id: LabGrown + +- type: Tag + id: CatWearable + +- type: Tag + id: BookSpaceLaw + +- type: Tag + id: CrossbowBolt + +- type: Tag + id: WeaponMeleeStake + +- type: Tag + id: Censer + +- type: Tag + id: ReligiousSymbol + +- type: Tag + id: Crucifix + +- type: Tag + id: ObjectOfSpiritualSignificance + +- type: Tag + id: Ash + +- type: Tag + id: LavaMercenary + +- type: Tag + id: MysteryFigureBox + +- type: Tag + id: WhoopieCushion + +- type: Tag + id: Mustard + +- type: Tag + id: PrizeTicket + +- type: Tag + id: Mail + +- type: Tag + id: MailCapsule diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-cash.png b/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-cash.png new file mode 100644 index 0000000000000000000000000000000000000000..8ba33c95b571476a108f05f30de91aa581c78353 GIT binary patch literal 6954 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-empty.png b/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-empty.png new file mode 100644 index 0000000000000000000000000000000000000000..085b787410b5a3501a456472d2bf9f23a1d99990 GIT binary patch literal 6506 zcmeHLdpy(q9$#)_4S8JBqsy$zL1y=5%W|39u*kie+J5_uWjEU}gbGaQ_k@bjjfj*=b*iIOtMl8abk1|0b9%kb`LB6x_WOL_pZDkUeSbfn@Avmxmfu1T zeZ5%lK`Sj!>!J|~J)o2DA@R(PnxOWe>+NkyGJen#0Bo-%v>Gq`c<)rq zJHw>(5wERBnUiZ?9H<}WR7Z3wt7I)9^oOtJZuF>5?ko&5MAYhHx{kA^_Z2Efz#b7Y zl)(`1sam$?J^= zhu*bay7<1_NsOoMH!1U(+>+i{4_lwi;yy&Tm}=s6JAL%Si$8?w!A6i}PnyeHJ%YnR zMzTK|mgL=4>P>szuqEU@KY8G4gD?F4JYw7G<`0LGZ-mI}HK`vHDz*&|-f?q;y2r)qKNZKO?v8Gb?D?hUp~kt`Lvi4h`S1DRdqO#wFcYD5 z)wRLMlG5$W5Di~)Ze6y2nf6Hp>zel?OvTZDqS&#m`7Z8njpmC98y@JUo0K_5t>#BO z*B#kaF?9r)1C$FmwnjFuXC$TR04 zxxdFQ;Vw7ST%#)^nr+rYF58q<)$i?neOC&g>8Qid&+^x?y3_=+x0e2-cZolH;KKZ! zS8twq@GOIuqC3Y@o4gyjEJ)YlzDFbjImI}HXBI5Fduwe8B0JM7v(TC!6uhW?-}2uU z9mpvl2{A{z4{l#L$>Uk;(c|4GrpzISQtE`}D=Cddi{OS+Xty7oopUC<<8r{hmTkPk zV~xeyyF-u2kG5}*i&?uVBz$s+xVwwuB5XTUa9q$Od?UnmNNf4Z-nR=PM=md+`kZ%4 ztjq`rDx4#|qz4aQdGH4E0@>WjX?xGpRW%)(QfqsjKGt5`pnaep75-o)5*d6oJvJ%o zP4YnZ-?pt%V!9hQ*O=T;>J9k&z0sCAz8uzzoLk;pXEiMYt*?0_J1@z+r`fB@YSlea zTgAy26?>EQm1mJTmY$bZQyVj_9uuDwrKjd}J;ixhyvc8x_HxO~0ZNR1;*uSS&l-z| zR@HK6cHY|dB(zOvS1W(@Ai6K8uFm+#^xDIcYNh#=hq1Y~UE?caP~75B3i3*)jE9btSQjlwyz4R%kUm)p%uoe0pEc(BUhsEyi~5 z&2JtKiSDUG!kao-Y35F^GU_TUa_XjfuUTxl$4~rQ-;xEFTczvPhoc79wZZCqEBj_$ z411p-d^dPHQ$y$14M(-Y;CrJ`8e#By7#4imtGKwJ1YJb&>UQFXtr2@Kzx}dY)^FR* z4UDu1I>&mMW%N9)^Zb!t2+K6lNelhO>&P?>U1zr`3A??`bK=}P9-B!L5?n0ZW|gg2 zd;bbW2|LecDFjnmENqMNQZTM{%vrg(3xg+%ld&`YnpF_I(_+hBo!kt;QeKAcPd3K0 zlZ*V^-!&0<)36M9$FJo9u~P=n@=93juAv}87vCOuBDt@10p*O~viIYo22 zJx5^~(|$PWCdGNUM~9!n2}QJrzNm1C8u-1^(|w(|ay7&MV9Q1NtPj7i^_rX)<@HL= z{$hGZ3t6zg&?m~#{`HwQEeqpmKL=J6Buq*^-b6iYsZr$d^w5XE4RU3MyiUk|6tTF# zgLa`&GR;;1#5Q>Nq|nfy@NsdX>>m7OrO&U_QeflBO7Tk*D$(dz=BuE$C0c?ey+x(^ zX6(C+IQM}pJvNe=l4IJpv=MdRqM#;7>2;b1U#oj?)wQAWn~u?wTGw^_#fj$2 z?L5&jnwAorQQgb(6yMTwF0N?xxAme7|NY5&o3&F3WiSp&d^m+UlYE@m3ePHDbUAk_ zYm4Aue6L0M%EY3wbc38K`9%*`+r&nUM#1g!6@!d-n)7!i@3efBG)?_^{GdU~@gUEKA-z?GI>2i(_ZnG9WY z_>h+C$h6zB48%!oix8%p`rx0^?se@<-_M+9ZK7ElCU_5M=|0nFt`#QFxD)eA>xH9c z$dWrNgs`f@lFmCz`gI@O(Xl&pXJ;LJ*)y1?Z!Om|x4+EV1abQPl*9moN2j#oJMMNb zd2gQxBiv|zsV|Y}ZZNY>=<4h0+Fh?q*w=o~5CEln*UzBegux7V@u9ndP?ir35DV?t zTrmf}i};HZ$Wfk;q};(+0N5gq;f#3?k2&!wY7$SfR7!T=-qp7ByJAbw#W z5FZIpxoF1)2nPiXA`pUdHcBBBh-5Sc9j)f2LElwoEE=VT$Rp|KP?jHxA(nzDk{!to zhjCNzV+iO42$X}A%cJ?bx{pynS9ElQTrQzuv9YnScCkb|u{0cur&6g{905xpU?2oW z7AKOk6&R6hrix;e!xfYPQocma7mH9TPBupzEvKW=&^T(092y1O6p(Q&fa+RJFOzez zOz46H%?AQt2{@cR21mdUsMzuT&?t-b#akpBQxVb=t6)p8csm?cDE!7lCU=YZ8t)H1 zWP#Al8P*?^iKC?e=oSNtM`@;VX`mfK7o3N&$MHxQ4uMT3QSo>p8L%Hm z;Vb1soxm21&q_tbg{as784r+n6bzn31R*K{h~aQKTnvfLnFrzsL=Mp&R8y(ef#&ST zq@xLTxUUvJ0b9-!ONCH-@kLy5tnBMhAYTXu$k{5{@bhr*Pq4?^Q}Lt8sTqSo zsSGM}6)PTRMn z$3}pv;=&O~s!b3_3dG}RWP2KsfF50Klmk|^!+xHvgK7_Av1sGxW$5 zrNDQAe^l51OfJONM{ZCA-S@>p57dbb@#WCNxDLnL!xeT~_4o5`cpzlalXxzc!C(`O zRqqL~ox98-BV5j8xxpW4Xu)Zyn}aiapkG|5OjqZ?(6d8Z>%GtVnRxh?B4UUr15;531t-x9~oI=Cb$3h*%ObV=Ulw!Sdrs^V@}<%GvW+dn2Mg~E~J zh}L4m+!GV)n|;L1t8}9JHC~f9Y)Qp0(#CXNKXp~R?KNWGAUVzH6H!~{em=4$cfnq( z!!-{k*qUXB5q0JJoovjR+Adw&%9AuCxGtxlEid}Koy{|bOF@0di8`8m+!_M7&R%LX z?bP8^|90Pn7Yaiwgn8{q$l7_!v|Bvaan7v#%olp+L-x1&2&5E9R~XZ6q3a=+m8t&# DcPr_! literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-food.png b/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-food.png new file mode 100644 index 0000000000000000000000000000000000000000..d08489cec899042a9f0875d207ef925a6a15f1c9 GIT binary patch literal 7202 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-mail.png b/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-mail.png new file mode 100644 index 0000000000000000000000000000000000000000..b35a2acc0f35c17db2ed3b9dc71defa390b8a36b GIT binary patch literal 6821 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 R)<7u$qg&Zq9$C2|_Fs*mhuZ)E literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/meta.json b/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/meta.json new file mode 100644 index 00000000000..2e9bfc36170 --- /dev/null +++ b/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-4.0", + "copyright": "Made for Frontier by erhardsteinhauer (discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon-empty" + }, + { + "name": "icon-mail" + }, + { + "name": "icon-food" + }, + { + "name": "icon-cash" + }, + { + "name": "spent" + } + ] +} diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/spent.png b/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/spent.png new file mode 100644 index 0000000000000000000000000000000000000000..acd0d0577fcf2c69dafee98bdeea2787236ac4f8 GIT binary patch literal 5618 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/broken.png b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/broken.png new file mode 100644 index 0000000000000000000000000000000000000000..1c798c4075b0ce9759cf88d64e2def45dea7342c GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJy`CJRkaFj2;(rr(q0kZ~c z^y)qT4xd>(ZRX+xk)EbNhx&vCI$c3cp(+&@*SlnQZ2Pr;kJ^|0jhkN7GpAnsU$Rx^ zW>U&&ZJ|9YUJ0x*71_lq%e`%4sCHjdpaB;f?}6|shu}HQp5$F*HPgg&ebxsLQ07`vh+W-In literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/fragile.png b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/fragile.png new file mode 100644 index 0000000000000000000000000000000000000000..0917000cbef3ef7f6341f1f764d978392db98bd9 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzKTj9Okcigg1PRu~2_ijBfd*V| z2Q?s^k^>#S8>Tw`v$ylT%EQ0$l`^}*!$}@Dw=^6Kh@A|?!sq;eoTzVy4mPwO0P11p ZV|Z!Jv#PmvZWYjE22WQ%mvv4FO#mgMEY$!2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/icon.png b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f3974ab116c90710a0a437b09a83978350e0439a GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyegQrqu0T4_R5H>|Eyi9s*+nD8 zRXx>JGtFH)!(A)eOFPF~FV9;i-$%E|-=HDdsx`sBGs(Uy#i>8td19vf%(l|mMZOEm z1DDr?ZkW|R-N-0eiPZ#XqEtzcUogXeT!203uL4k2xu=U`h(+(wix;^X6nI(_Z7;e8 zTyzuP`+xE_k;_S^TNcP4iLKFCQ9Q}KNYj3mXhJ|Xzc-TLq|*Wk||bFk8O;!1DBuXZ|q)&HC|)L3=`Y TQH{n&caX`Ru6{1-oD!Mzc-TLq|*Wk||bFk8O;!1DBuXZ|q)&HC|)L3=`Y TQH{n&caX`Ru6{1-oD!Mn3Iu0Yz-(=yUdEyi9s*+nD8 zRXx>JGtFH)!(A)eOFPF~FV9;i-$%E|-=HDdsx`sBGs(Uy#i>8td19vf%(l|mMZOEm z1DDr?ZkW|R-N?vRN2)2p#6VfpSXB&Y@;s4MWk5>4B*-tA;XhvB?m1T!s8qt!#WBR9 rH#tE11>klOa_KuA`G4kMR(2s)i8Lv`njxgN@xNA<4sdi literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/meta.json b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/meta.json new file mode 100644 index 00000000000..ac5345ba1a5 --- /dev/null +++ b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/meta.json @@ -0,0 +1,40 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation (obj/storage/closet.dmi, obj/service/bureaucracy.dmi), modified by Whatstone (Discord). broken, inhand-left, inhand-right by Whatstone.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "broken" + }, + { + "name": "fragile" + }, + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "locked" + }, + { + "name": "priority" + }, + { + "name": "priority_inactive" + }, + { + "name": "trash" + } + ] +} diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority.png b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority.png new file mode 100644 index 0000000000000000000000000000000000000000..9c5a74ad10326820f316db28068a15bd0c649474 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz8&4O$Dny@!}XRX7Ap9zKQcYZt5kn&CHlpX((tVwB4%^oFtgN$UjZ)xx}eD(d)f@&b1 Mr>mdKI;Vst0DGk+(EtDd literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..fc03165b576885291ea0dfaf8b8f2385af9cd7a2 GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzTTd6qkcigg1PRu~47^8vX#8ES z+RHbi!1Bn2j`?aP7x^se-zodP2sGewJE#FvlOWR51m%=4Fzj+QE7arl)BzgA;OXk; Jvd$@?2>=f&Ay)tZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/trash.png b/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/trash.png new file mode 100644 index 0000000000000000000000000000000000000000..2ef4ee7233883af6f8d42a12d2ca927b3ec865b6 GIT binary patch literal 343 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 ej6g(0_3;yTz>Vz2R4ZfY literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json b/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json new file mode 100644 index 00000000000..464c22d1a7a --- /dev/null +++ b/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-SA-4.0", + "copyright": "Taken/modified from cev-eris at https://github.com/discordia-space/CEV-Eris/pull/6042/commits/64916c98f4847acc4adf3a2416bf78c005fd7dd7, https://github.com/discordia-space/CEV-Eris/blob/master/icons/obj/guns/launcher/grenadelauncher.dmi, backpack sprite by Peptide, resprited for mail gun by erhardsteinhauer (discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "bolt-open" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BELT", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + } + ] +} \ No newline at end of file From 9a78144452c961a73e245a0d597b4d1f60338e61 Mon Sep 17 00:00:00 2001 From: fox Date: Sat, 5 Oct 2024 18:45:43 +0300 Subject: [PATCH 03/14] Removes obsolete empty files --- .../Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml | 0 .../Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml | 0 .../Entities/Objects/Specific/Mail/mail_engineering.yml | 0 .../Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml | 0 .../Entities/Objects/Specific/Mail/mail_specific_items.yml | 0 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml delete mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml delete mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_engineering.yml delete mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml delete mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_specific_items.yml diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_command.yml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_engineering.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_engineering.yml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_security.yml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_specific_items.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_specific_items.yml deleted file mode 100644 index e69de29bb2d..00000000000 From be3aac16e8746be8ebe25a8cd09b75baeb95772b Mon Sep 17 00:00:00 2001 From: fox Date: Sat, 5 Oct 2024 18:46:07 +0300 Subject: [PATCH 04/14] Fixes, I suppose? Idk, git didn't commit those files along with the cherry-picks --- .../Entities/Objects/Specific/Mail/mail.yml | 58 +++++++++++++++++++ .../Objects/Specific/Mail/mail_command.yml | 3 + .../Specific/Mail/mail_engineering.yml | 9 ++- .../Objects/Specific/Mail/mail_security.yml | 7 +++ .../Entities/Objects/Devices/pda.yml | 2 +- .../Entities/Objects/Devices/pda.yml | 10 +++- 6 files changed, 85 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml index 4da4fa260a3..bb08f18d087 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml @@ -179,6 +179,7 @@ - id: FoodPiePumpkin - type: entity + noSpawn: true parent: BaseMail id: MailDVCosplayFakeWizard suffix: cosplay-wizard, fake as fuck @@ -199,6 +200,7 @@ # Frontier Mail, including Extended Nyano Mail. (Pony Express?) - type: entity + noSpawn: true parent: BaseMail id: MailNFAlcohol suffix: alcohol, extended @@ -242,6 +244,7 @@ amount: 2 - type: entity + noSpawn: true parent: BaseMailLarge id: MailNFBible suffix: bible, extended @@ -253,6 +256,7 @@ - id: ClothingOuterCoatMNKBlackTopCoat #DeltaV - Compensates for items that don't exist here - type: entity + noSpawn: true parent: BaseMail id: MailNFBikeHorn suffix: bike horn, random @@ -267,6 +271,7 @@ prob: 0.05 - type: entity + noSpawn: true parent: BaseMailLarge id: MailNFBuildABuddy suffix: Build-a-Buddy @@ -288,6 +293,7 @@ - id: PaperMailNFBuildABuddy - type: entity + noSpawn: true parent: BaseMailLarge id: MailNFCake suffix: cake, extended @@ -349,6 +355,7 @@ amount: 2 - type: entity + noSpawn: true parent: BaseMail id: MailNFCosplayWizard suffix: cosplay-wizard, extended @@ -366,6 +373,7 @@ prob: 0.1 - type: entity + noSpawn: true parent: BaseMail id: MailNFCosplayMaid suffix: cosplay-maid, extended @@ -382,6 +390,7 @@ - id: ClothingHandsGlovesColorWhite - type: entity + noSpawn: true parent: BaseMail id: MailNFCosplayNurse suffix: cosplay-nurse, extended @@ -393,6 +402,7 @@ - id: Syringe - type: entity + noSpawn: true parent: BaseMail id: MailNFCheese suffix: cheese, extended @@ -410,6 +420,7 @@ - id: KnifePlastic - type: entity + noSpawn: true parent: BaseMail id: MailNFCigarettes suffix: cigs, random @@ -444,6 +455,7 @@ - id: CheapLighter - type: entity + noSpawn: true parent: BaseMail id: MailNFEMP suffix: emp @@ -454,6 +466,7 @@ - id: PaperMailNFEMPPreparedness - type: entity + noSpawn: true parent: BaseMail id: MailNFSmoke suffix: smoke @@ -463,6 +476,7 @@ - id: DelayedSmoke - type: entity + noSpawn: true parent: BaseMail id: MailNFGoldCigars suffix: cigars, premium @@ -476,6 +490,7 @@ prob: 0.95 - type: entity + noSpawn: true parent: BaseMail id: MailNFCookies suffix: cookies, random @@ -521,6 +536,7 @@ orGroup: Cookie4 - type: entity + noSpawn: true parent: BaseMail id: MailNFKnife suffix: knife, extended @@ -537,6 +553,7 @@ orGroup: Knife - type: entity + noSpawn: true parent: BaseMailLarge id: MailNFSword suffix: sword @@ -572,6 +589,7 @@ prob: 0.001 - type: entity + noSpawn: true parent: BaseMail id: MailNFMuffins suffix: muffins, random @@ -629,6 +647,7 @@ prob: 0.5 - type: entity + noSpawn: true parent: BaseMail id: MailNFPAI suffix: PAI, extended @@ -644,6 +663,7 @@ prob: 0.01 - type: entity + noSpawn: true parent: BaseMail id: MailNFPlushie suffix: plushie, extended @@ -707,6 +727,7 @@ # Random snacks, replaces MailChocolate (lousy animal organs) - type: entity + noSpawn: true parent: BaseMail id: MailNFSnacks suffix: snacks, random @@ -819,6 +840,7 @@ prob: 0.5 - type: entity + noSpawn: true parent: BaseMail id: MailNFVagueThreat suffix: vague-threat @@ -865,6 +887,7 @@ orGroup: ThreateningObject - type: entity + noSpawn: true parent: BaseMail id: MailNFDonkPockets suffix: donk pockets, random @@ -901,6 +924,7 @@ # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFSodaPwrGame suffix: Pwrgame @@ -913,6 +937,7 @@ # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFSodaRedBool suffix: Red Bool @@ -925,6 +950,7 @@ # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFSodaSpaceCola suffix: Space Cola @@ -936,6 +962,7 @@ # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFSodaSpaceMountainWind suffix: Space Mountain Wind @@ -947,6 +974,7 @@ # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFSodaSpaceUp suffix: Space Up @@ -957,6 +985,7 @@ - id: PaperMailNFSpaceUpAd - type: entity + noSpawn: true parent: BaseMail id: MailNFJoints suffix: joints @@ -1007,6 +1036,7 @@ # Mmm, mail food # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFUnusualFood suffix: unusual food @@ -1072,6 +1102,7 @@ # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFBakedGoods suffix: baked goods @@ -1218,6 +1249,7 @@ # Needs a buff? - type: entity + noSpawn: true parent: BaseMail id: MailNFUnusualProduce suffix: unusual produce @@ -1267,6 +1299,7 @@ prob: 0.25 - type: entity + noSpawn: true parent: BaseMail id: MailNFSoaps suffix: soap sampler @@ -1280,6 +1313,7 @@ orGroup: Ad - type: entity + noSpawn: true parent: BaseMail id: MailNFSoapsOmega suffix: soap sampler, omega @@ -1294,6 +1328,7 @@ # Could add spessman battle rules here - type: entity + noSpawn: true parent: BaseMail id: MailNFFigurineBulk # DeltaV - No longer Bulk suffix: figurine, bulk #DeltaV - Spams 3 boxes instead of using the bulk figurine prototype that Frontier uses @@ -1305,6 +1340,7 @@ - id: MysteryFigureBox - type: entity + noSpawn: true parent: BaseMail id: MailNFPen suffix: fancy pen @@ -1332,6 +1368,7 @@ - id: PaperMailNFPaperPusherAd - type: entity + noSpawn: true parent: BaseMailLarge id: MailNFThrongler suffix: throngler @@ -1341,6 +1378,7 @@ - id: PlushieThrongler #DeltaV: ThronglerToy -> PlushieThrongler - type: entity + noSpawn: true parent: BaseMail id: MailNFInstrumentSmall suffix: instrument, expanded @@ -1387,6 +1425,7 @@ prob: 0.01 - type: entity + noSpawn: true parent: BaseMail id: MailNFUnusualClothing suffix: unusual clothing @@ -1439,6 +1478,7 @@ prob: 0.25 - type: entity + noSpawn: true parent: BaseMail id: MailNFCritter suffix: critter @@ -1491,6 +1531,7 @@ prob: 0.01 # Rare - type: entity + noSpawn: true parent: BaseMail id: MailNFTacticalMaid suffix: tactical maid @@ -1503,6 +1544,7 @@ - id: ClothingHandsTacticalMaidGloves - type: entity + noSpawn: true parent: BaseMailLarge id: MailNFKendoKit suffix: kendo kit @@ -1520,6 +1562,7 @@ # Base Nyano Mail - type: entity + noSpawn: true parent: BaseMail id: MailSake suffix: osake @@ -1531,6 +1574,7 @@ - id: DrinkTokkuri - type: entity + noSpawn: true parent: BaseMail id: MailBlockGameDIY suffix: blockgamediy @@ -1540,6 +1584,7 @@ - id: BlockGameArcadeComputerCircuitboard - type: entity + noSpawn: true parent: BaseMail id: MailCigars suffix: Cigars @@ -1550,6 +1595,7 @@ - id: Lighter - type: entity + noSpawn: true parent: BaseMail id: MailCrayon suffix: Crayon @@ -1559,6 +1605,7 @@ - id: CrayonBox - type: entity + noSpawn: true parent: BaseMail id: MailCosplayArc suffix: cosplay-arc @@ -1569,6 +1616,7 @@ - id: ClothingCostumeArcDress - type: entity + noSpawn: true parent: BaseMail id: MailCosplayGeisha suffix: cosplay-geisha @@ -1581,6 +1629,7 @@ amount: 3 - type: entity + noSpawn: true parent: BaseMail id: MailCosplaySchoolgirl suffix: cosplay-schoolgirl @@ -1605,6 +1654,7 @@ orGroup: Color - type: entity + noSpawn: true parent: BaseMail id: MailFlowers suffix: flowers @@ -1619,6 +1669,7 @@ - id: FoodLily - type: entity + noSpawn: true parent: BaseMail id: MailSignallerKit suffix: signallerkit @@ -1629,6 +1680,7 @@ - id: RemoteSignaller - type: entity + noSpawn: true parent: BaseMail id: MailNoir suffix: noir @@ -1641,6 +1693,7 @@ - id: ClothingOuterCoatGentle - type: entity + noSpawn: true parent: BaseMail id: MailRestraints suffix: restraints @@ -1652,6 +1705,7 @@ - id: ClothingEyesBlindfold - type: entity + noSpawn: true parent: BaseMail id: MailFishingCap suffix: fishingcap @@ -1661,6 +1715,7 @@ - id: ClothingHeadFishCap - type: entity + noSpawn: true parent: BaseMail id: MailFlashlight suffix: Flashlight @@ -1670,6 +1725,7 @@ - id: FlashlightLantern - type: entity + noSpawn: true parent: BaseMail id: MailSpaceVillainDIY suffix: spacevilliandiy @@ -1679,6 +1735,7 @@ - id: SpaceVillainArcadeComputerCircuitboard - type: entity + noSpawn: true parent: BaseMail id: MailSunglasses suffix: Sunglasses @@ -1688,6 +1745,7 @@ - id: ClothingEyesGlassesSunglasses - type: entity + noSpawn: true parent: BaseMail id: MailWinterCoat suffix: wintercoat diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml index 375b024c408..86dec46a654 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_command.yml @@ -1,5 +1,6 @@ # Base Nyano Mail - type: entity + noSpawn: true parent: BaseMail id: MailCommandPinpointerNuclear suffix: pinpointer mail ops @@ -9,6 +10,7 @@ - id: PinpointerNuclear - type: entity + noSpawn: true parent: BaseMail id: MailStationRepNFNukeDisk suffix: nuke disk @@ -20,6 +22,7 @@ - id: PaperMailNFAntivirus - type: entity + noSpawn: true parent: BaseMail id: MailCommandNFPipebombIntern suffix: pipe and bomb diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml index 8fa0fa4baf7..741e01d633f 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml @@ -1,5 +1,6 @@ # Base Nyano Mail - type: entity + noSpawn: true parent: BaseMail id: MailEngineeringCables suffix: cables @@ -14,6 +15,7 @@ orGroup: Cables - type: entity + noSpawn: true parent: BaseMail id: MailEngineeringKudzuDeterrent suffix: antikudzu @@ -23,6 +25,7 @@ - id: PlantBGoneSpray - type: entity + noSpawn: true parent: BaseMail id: MailEngineeringSheetGlass suffix: sheetglass @@ -32,6 +35,7 @@ - id: SheetGlass - type: entity + noSpawn: true parent: BaseMail id: MailEngineeringWelderReplacement suffix: welder @@ -43,6 +47,7 @@ # Frontier Mail - type: entity + noSpawn: true parent: BaseMail id: MailNFCircuitboardIndustrial suffix: industrial circuitboard @@ -108,6 +113,7 @@ prob: 0.1 - type: entity + noSpawn: true parent: BaseMail id: MailNFCircuitboardService suffix: service circuitboard @@ -149,8 +155,9 @@ prob: 0.1 - type: entity + noSpawn: true parent: BaseMailLarge - id: MailNFPowerTool + id: MailNFPowerTool suffix: power tool components: - type: Mail diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml index c08e92cc6b2..ac29aa20d2b 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml @@ -1,5 +1,6 @@ # Base Nyano Mail - type: entity + noSpawn: true parent: BaseMail id: MailSecurityDonuts suffix: donuts @@ -9,6 +10,7 @@ - id: FoodBoxDonut - type: entity + noSpawn: true parent: BaseMail id: MailSecurityFlashlight suffix: seclite @@ -18,6 +20,7 @@ - id: FlashlightSeclite - type: entity + noSpawn: true parent: BaseMail id: MailSecurityNonlethalsKit suffix: nonlethalskit @@ -42,6 +45,7 @@ # Will we ever readd hyperlinks books? Who knows! - type: entity + noSpawn: true parent: BaseMail id: MailWardenCrowdControl suffix: crowdcontrol @@ -51,6 +55,7 @@ - id: BoxBeanbag - type: entity + noSpawn: true parent: BaseMail id: MailDetectiveForensicSupplement # Deltav - Detective is in charge of investigating crimes. suffix: detectivesupplement # Deltav - Detective is in charge of investigating crimes. @@ -62,6 +67,7 @@ # Frontier Mail - type: entity + noSpawn: true parent: BaseMailLarge id: MailSecurityNFMusket suffix: musket @@ -77,6 +83,7 @@ # Delta Mail - type: entity + noSpawn: true parent: BaseMail id: MailSecurityDVSpaceLaw suffix: spacelaw, extended diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index d9538f57649..ebefd05cbb6 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -358,7 +358,7 @@ accentVColor: "#a23e3e" - type: Icon state: pda-qm - - type: CartridgeLoader # DeltaV - MailMetrics courier tracker + - type: CartridgeLoader # Adds the MailMetrics courier tracker preinstalled: - CrewManifestCartridge - NotekeeperCartridge diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml index d898124b771..c85255f814e 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml @@ -32,7 +32,7 @@ accentVColor: "#DFDFDF" - type: Icon state: pda-security - - type: CartridgeLoader # DeltaV - Crime Assist + SecWatch + - type: CartridgeLoader # Adds Crime Assist and SecWatch preinstalled: - CrewManifestCartridge - NotekeeperCartridge @@ -43,7 +43,7 @@ - type: entity parent: BasePDA id: MailCarrierPDA - name: courier PDA # DeltaV - Mail Carrier to Courier replacement + name: courier PDA description: Smells like unopened letters. components: - type: Sprite @@ -67,6 +67,12 @@ - type: Icon sprite: DeltaV/Objects/Devices/pda.rsi state: pda-mailcarrier + - type: CartridgeLoader # Adds a courier performance tracker + preinstalled: + - CrewManifestCartridge + - NotekeeperCartridge + - NewsReaderCartridge + - MailMetricsCartridge - type: entity parent: BasePDA From 232ba1416d220323b8070deff3eeb1d9de4d18b1 Mon Sep 17 00:00:00 2001 From: fox Date: Sat, 5 Oct 2024 18:47:53 +0300 Subject: [PATCH 05/14] Manual cherry-pick of https://github.com/DeltaV-Station/Delta-v/pull/1788/ --- .../Entities/Objects/Specific/Mail/mail.yml | 57 +++++++++++++++++++ .../Prototypes/DeltaV/Mail/mailDeliveries.yml | 10 ++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml index bb08f18d087..b2b14b742ee 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml @@ -196,6 +196,63 @@ orGroup: FakeWizard prob: 0.1 +- type: entity + parent: BaseMail + id: MailDVScarves + suffix: scarves + components: + - type: Mail + contents: + - id: ClothingNeckScarfStripedRed + orGroup: Scarf + - id: ClothingNeckScarfStripedBlue + orGroup: Scarf + - id: ClothingNeckScarfStripedGreen + orGroup: Scarf + - id: ClothingNeckScarfStripedBlack + orGroup: Scarf + - id: ClothingNeckScarfStripedBrown + orGroup: Scarf + - id: ClothingNeckScarfStripedLightBlue + orGroup: Scarf + - id: ClothingNeckScarfStripedOrange + orGroup: Scarf + - id: ClothingNeckScarfStripedPurple + orGroup: Scarf + - id: ClothingNeckScarfStripedZebra + orGroup: Scarf + - id: ClothingNeckScarfStripedSyndieGreen + orGroup: Scarf + prob: 0.25 + - id: ClothingNeckScarfStripedSyndieRed + orGroup: Scarf + prob: 0.25 + - id: ClothingNeckScarfStripedCentcom + orGroup: Scarf + prob: 0.001 + +- type: entity + parent: BaseMailLarge + id: MailDVBoxes + suffix: boxes + components: + - type: Mail + contents: + - id: BoxEnvelope + orGroup: Box + - id: BoxCardboard + orGroup: Box + - id: BoxMRE + orGroup: Box + - id: BoxPerformer + orGroup: Box + - id: BoxFlare + orGroup: Box + - id: BoxDarts + orGroup: Box + - id: BoxMousetrap + orGroup: Box + # Frontier Mail, including Extended Nyano Mail. (Pony Express?) diff --git a/Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml b/Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml index e244a14b793..c0d6df9ec21 100644 --- a/Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml +++ b/Resources/Prototypes/DeltaV/Mail/mailDeliveries.yml @@ -7,7 +7,8 @@ MailNFBikeHorn: 0.5 MailBooksAll: 1 MailBlockGameDIY: 0.5 - MailNFBuildABuddy: 0.6 + MailNFBuildABuddy: 0.3 + MailDVBoxes: 0.3 MailCrayon: 1 MailNFCake: 1 MailNFCheese: 1 @@ -42,6 +43,7 @@ MailNFPen: 0.7 MailRestraints: 0.8 MailSake: 0.4 + MailDVScarves: 0.15 MailNFSnacks: 1 #Soda - Adds up to 1 in weight MailNFSodaPwrGame: 0.2 @@ -51,14 +53,14 @@ MailNFSodaSpaceUp: 0.2 #End Soda MailNFSmoke: 0.4 - MailSpaceVillainDIY: 0.5 + MailSpaceVillainDIY: 0.5 MailSignallerKit: 0.5 MailSunglasses: 1 MailNFSoaps: 0.5 MailNFSoapsOmega: 0.5 MailNFSword: 0.5 MailNFTacticalMaid: 0.5 - MailNFThrongler: 0.1 + MailNFThrongler: 0.05 MailNFUnusualClothing: 0.5 MailNFUnusualFood: 1 MailNFUnusualProduce: 1 @@ -142,4 +144,4 @@ Passenger: MailPassengerMoney: 3 Warden: - MailWardenCrowdControl: 2 \ No newline at end of file + MailWardenCrowdControl: 2 From e7811f5e8307f8390f634ebe5ba285869663c51c Mon Sep 17 00:00:00 2001 From: Milon Date: Sat, 28 Sep 2024 01:42:29 +0200 Subject: [PATCH 06/14] fix large mail description (#1925) fix --- Resources/Locale/en-US/_NF/mail/mail.ftl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Resources/Locale/en-US/_NF/mail/mail.ftl b/Resources/Locale/en-US/_NF/mail/mail.ftl index 394c551fad5..7ab4f6b6f55 100644 --- a/Resources/Locale/en-US/_NF/mail/mail.ftl +++ b/Resources/Locale/en-US/_NF/mail/mail.ftl @@ -1,7 +1,8 @@ mail-large-item-name-unaddressed = package mail-large-item-name-addressed = package ({$recipient}) mail-large-desc-far = A large package. -mail-large-desc-close = A large package addressed to {CAPITALIZE($name)}, {$job}. Last known location: {$station}. +# DelaV - Removed "Last known location" +mail-large-desc-close = A large package addressed to {CAPITALIZE($name)}, {$job}. ### Frontier: mailtestbulk command-mailtestbulk = Sends one of each type of parcel to a given mail teleporter. Implicitly calls mailnow. From 9527b24c0e58ab8f5b3f5f94a23cbf618f574e02 Mon Sep 17 00:00:00 2001 From: fox Date: Sat, 5 Oct 2024 19:34:23 +0300 Subject: [PATCH 07/14] Fix stuff --- .../Entities/Objects/Specific/Mail/mail.yml | 98 ++++++++++--------- .../Specific/Mail/mail_engineering.yml | 6 +- .../Objects/Specific/Mail/mail_security.yml | 2 +- Resources/Prototypes/_NF/Mail/Items/misc.yml | 6 +- Resources/Prototypes/_NF/tags.yml | 3 - 5 files changed, 57 insertions(+), 58 deletions(-) diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml index b2b14b742ee..25b7ec40803 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml @@ -238,8 +238,8 @@ components: - type: Mail contents: - - id: BoxEnvelope - orGroup: Box +# - id: BoxEnvelope # TODO: we do not have this on EE? +# orGroup: Box - id: BoxCardboard orGroup: Box - id: BoxMRE @@ -632,9 +632,9 @@ - id: Claymore orGroup: Sword prob: 0.5 - - id: CaneSheathFilled - orGroup: Sword - prob: 0.3 +# - id: CaneSheathFilled # TODO: don't have this yet +# orGroup: Sword +# prob: 0.3 - id: Cutlass orGroup: Sword prob: 0.1 @@ -1041,6 +1041,7 @@ - id: DrinkSpaceUpBottleFull - id: PaperMailNFSpaceUpAd +#TODO: we don't have rainbow joints or blunts (yet?). Uncomment when (if?) they are added. - type: entity noSpawn: true parent: BaseMail @@ -1053,41 +1054,41 @@ - id: Joint orGroup: Smokeable1 prob: 0.35 - - id: JointRainbow - orGroup: Smokeable1 - prob: 0.15 - - id: Blunt - orGroup: Smokeable1 - prob: 0.35 - - id: BluntRainbow - orGroup: Smokeable1 - prob: 0.15 +# - id: JointRainbow +# orGroup: Smokeable1 +# prob: 0.15 +# - id: Blunt +# orGroup: Smokeable1 +# prob: 0.35 +# - id: BluntRainbow +# orGroup: Smokeable1 +# prob: 0.15 # Smokeable 2 - id: Joint orGroup: Smokeable2 prob: 0.35 - - id: JointRainbow - orGroup: Smokeable2 - prob: 0.15 - - id: Blunt - orGroup: Smokeable2 - prob: 0.35 - - id: BluntRainbow - orGroup: Smokeable2 - prob: 0.15 +# - id: JointRainbow +# orGroup: Smokeable2 +# prob: 0.15 +# - id: Blunt +# orGroup: Smokeable2 +# prob: 0.35 +# - id: BluntRainbow +# orGroup: Smokeable2 +# prob: 0.15 # Smokeable 3 - id: Joint orGroup: Smokeable3 prob: 0.35 - - id: JointRainbow - orGroup: Smokeable3 - prob: 0.15 - - id: Blunt - orGroup: Smokeable3 - prob: 0.35 - - id: BluntRainbow - orGroup: Smokeable3 - prob: 0.15 +# - id: JointRainbow +# orGroup: Smokeable3 +# prob: 0.15 +# - id: Blunt +# orGroup: Smokeable3 +# prob: 0.35 +# - id: BluntRainbow +# orGroup: Smokeable3 +# prob: 0.15 # Catchalls for food that only exist in random spawners # Mmm, mail food @@ -1213,9 +1214,9 @@ - id: FoodDonutChocolate amount: 2 orGroup: Food - - id: FoodDonutBluePumpkin - amount: 2 - orGroup: Food +# - id: FoodDonutBluePumpkin # Don't have that yet +# amount: 2 +# orGroup: Food - id: FoodDonutBungo amount: 2 orGroup: Food @@ -1243,9 +1244,9 @@ - id: FoodDonutJellyChocolate amount: 2 orGroup: Food - - id: FoodDonutJellyBluePumpkin - amount: 2 - orGroup: Food +# - id: FoodDonutJellyBluePumpkin # Don't have that yet +# amount: 2 +# orGroup: Food - id: FoodDonutJellyBungo amount: 2 orGroup: Food @@ -1333,15 +1334,16 @@ - id: FoodKoibean orGroup: Produce amount: 5 - - id: FoodGhostPepper #DeltaV - orGroup: Produce - amount: 5 - - id: FoodCosmicRevenant #DeltaV - orGroup: Produce - amount: 5 - - id: FoodCrystalThistle #DeltaV - orGroup: Produce - amount: 5 +# EE does not have those yet. Uncomment if any of those get ported. +# - id: FoodGhostPepper #DeltaV +# orGroup: Produce +# amount: 5 +# - id: FoodCosmicRevenant #DeltaV +# orGroup: Produce +# amount: 5 +# - id: FoodCrystalThistle #DeltaV +# orGroup: Produce +# amount: 5 - id: FoodLily orGroup: Produce amount: 5 @@ -1432,7 +1434,7 @@ components: - type: Mail contents: - - id: PlushieThrongler #DeltaV: ThronglerToy -> PlushieThrongler + - id: ThronglerToy - type: entity noSpawn: true diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml index 741e01d633f..af70fc621cb 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_engineering.yml @@ -96,9 +96,9 @@ - id: HotplateMachineCircuitboard orGroup: Board prob: 0.5 - - id: CircuitImprinterHyperConvectionMachineCircuitboard - orGroup: Board - prob: 0.25 +# - id: CircuitImprinterHyperConvectionMachineCircuitboard +# orGroup: Board +# prob: 0.25 - id: SheetifierMachineCircuitboard orGroup: Board prob: 0.25 diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml index ac29aa20d2b..eed846a0909 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_security.yml @@ -90,6 +90,6 @@ components: - type: Mail contents: - - id: BookSpaceLaw + - id: BookSecurity # - id: BookSOP #This is where I'd put my Delta SOP book... IF I HAD ONE!!! - id: PaperMailNFSpaceLaw # Uses the NF space law paper, which is edited to mention the Delta Sector diff --git a/Resources/Prototypes/_NF/Mail/Items/misc.yml b/Resources/Prototypes/_NF/Mail/Items/misc.yml index 98af182c6c4..6f1c86e00ba 100644 --- a/Resources/Prototypes/_NF/Mail/Items/misc.yml +++ b/Resources/Prototypes/_NF/Mail/Items/misc.yml @@ -61,9 +61,9 @@ solutions: drink: maxVol: 15 - reagents: - - ReagentId: Opporozidone - Quantity: 15 +# reagents: # TODO: we don't have that yet. Guess the people will receive an empty syringe instead. +# - ReagentId: Opporozidone +# Quantity: 15 - type: entity id: NecrosolChemistryBottle diff --git a/Resources/Prototypes/_NF/tags.yml b/Resources/Prototypes/_NF/tags.yml index 6264405762b..dbb5c68a25d 100644 --- a/Resources/Prototypes/_NF/tags.yml +++ b/Resources/Prototypes/_NF/tags.yml @@ -46,9 +46,6 @@ - type: Tag id: Mustard -- type: Tag - id: PrizeTicket - - type: Tag id: Mail From 592a22575b515a7d0db190b33c3070651a24a4c6 Mon Sep 17 00:00:00 2001 From: fox Date: Sat, 12 Oct 2024 22:49:56 +0300 Subject: [PATCH 08/14] Namespacen't (likely broken) --- Content.Server/Mail/DelayedItemComponent.cs | 15 ++ Content.Server/Mail/DelayedItemSystem.cs | 55 +++++ Content.Server/Mail/MailConstants.cs | 37 ++++ .../_NF/Mail/DelayedItemComponent.cs | 16 -- Content.Server/_NF/Mail/DelayedItemSystem.cs | 56 ----- Content.Server/_NF/Mail/MailConstants.cs | 38 ---- Resources/Locale/en-US/_NF/mail/mail.ftl | 10 - .../Mail/mail.ftl => mail/commands.ftl} | 25 +-- Resources/Locale/en-US/mail/mail.ftl | 23 ++ .../Entities/Objects/Devices/cartridges.yml | 2 +- .../Entities/Objects/Misc/mail_capsule.yml | 4 +- .../Objects/Specific}/Mail/Items/boxes.yml | 206 +++++++++--------- .../Objects/Specific}/Mail/Items/misc.yml | 0 .../Objects/Specific}/Mail/Items/paper.yml | 0 .../Objects/Specific/Mail/base_mail_large.yml | 2 +- .../Weapons/Guns/Launchers/launchers.yml | 26 +++ .../Objects/Specific/Mail/base_mail.yml | 2 +- Resources/Prototypes/Recipes/Lathes/misc.yml | 16 ++ .../Weapons/Guns/Launchers/launchers.yml | 24 -- .../Prototypes/_NF/Recipes/Lathes/misc.yml | 15 -- Resources/Prototypes/_NF/tags.yml | 53 ----- Resources/Prototypes/tags.yml | 21 ++ .../Misc/mail_capsule.rsi/icon-cash.png | Bin .../Misc/mail_capsule.rsi/icon-empty.png | Bin .../Misc/mail_capsule.rsi/icon-food.png | Bin .../Misc/mail_capsule.rsi/icon-mail.png | Bin .../Objects/Misc/mail_capsule.rsi/meta.json | 0 .../Objects/Misc/mail_capsule.rsi/spent.png | Bin .../Objects/Specific/Mail/mail.rsi/broken.png | Bin .../Specific/Mail/mail.rsi/fragile.png | Bin .../Objects/Specific/Mail/mail.rsi/icon.png | Bin .../Objects/Specific/Mail/mail.rsi/locked.png | Bin .../Objects/Specific/Mail/mail.rsi/meta.json | 0 .../Specific/Mail/mail.rsi/postmark.png | Bin .../Specific/Mail/mail.rsi/priority.png | Bin .../Mail/mail.rsi/priority_inactive.png | Bin .../Objects/Specific/Mail/mail.rsi/trash.png | Bin .../Specific/Mail/mail_large.rsi/broken.png | Bin .../Specific/Mail/mail_large.rsi/fragile.png | Bin .../Specific/Mail/mail_large.rsi/icon.png | Bin .../Mail/mail_large.rsi/inhand-left.png | Bin .../Mail/mail_large.rsi/inhand-right.png | Bin .../Specific/Mail/mail_large.rsi/locked.png | Bin .../Specific/Mail/mail_large.rsi/meta.json | 0 .../Specific/Mail/mail_large.rsi/priority.png | Bin .../Mail/mail_large.rsi/priority_inactive.png | Bin .../Specific/Mail/mail_large.rsi/trash.png | Bin .../Guns/Launchers/mail.rsi/bolt-open.png | Bin .../Launchers/mail.rsi/equipped-BACKPACK.png | Bin .../Guns/Launchers/mail.rsi/equipped-BELT.png | Bin .../Weapons/Guns/Launchers/mail.rsi/icon.png | Bin .../Guns/Launchers/mail.rsi/inhand-left.png | Bin .../Guns/Launchers/mail.rsi/inhand-right.png | Bin .../Weapons/Guns/Launchers/mail.rsi/meta.json | 0 54 files changed, 308 insertions(+), 338 deletions(-) create mode 100644 Content.Server/Mail/DelayedItemComponent.cs create mode 100644 Content.Server/Mail/DelayedItemSystem.cs create mode 100644 Content.Server/Mail/MailConstants.cs delete mode 100644 Content.Server/_NF/Mail/DelayedItemComponent.cs delete mode 100644 Content.Server/_NF/Mail/DelayedItemSystem.cs delete mode 100644 Content.Server/_NF/Mail/MailConstants.cs delete mode 100644 Resources/Locale/en-US/_NF/mail/mail.ftl rename Resources/Locale/en-US/{nyanotrasen/Mail/mail.ftl => mail/commands.ftl} (53%) create mode 100644 Resources/Locale/en-US/mail/mail.ftl rename Resources/Prototypes/{_NF => }/Entities/Objects/Misc/mail_capsule.yml (97%) rename Resources/Prototypes/{_NF => Entities/Objects/Specific}/Mail/Items/boxes.yml (53%) rename Resources/Prototypes/{_NF => Entities/Objects/Specific}/Mail/Items/misc.yml (100%) rename Resources/Prototypes/{_NF => Entities/Objects/Specific}/Mail/Items/paper.yml (100%) rename Resources/Prototypes/{_NF => }/Entities/Objects/Specific/Mail/base_mail_large.yml (97%) delete mode 100644 Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml delete mode 100644 Resources/Prototypes/_NF/Recipes/Lathes/misc.yml delete mode 100644 Resources/Prototypes/_NF/tags.yml rename Resources/Textures/{_NF => }/Objects/Misc/mail_capsule.rsi/icon-cash.png (100%) rename Resources/Textures/{_NF => }/Objects/Misc/mail_capsule.rsi/icon-empty.png (100%) rename Resources/Textures/{_NF => }/Objects/Misc/mail_capsule.rsi/icon-food.png (100%) rename Resources/Textures/{_NF => }/Objects/Misc/mail_capsule.rsi/icon-mail.png (100%) rename Resources/Textures/{_NF => }/Objects/Misc/mail_capsule.rsi/meta.json (100%) rename Resources/Textures/{_NF => }/Objects/Misc/mail_capsule.rsi/spent.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/broken.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/fragile.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/icon.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/locked.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/meta.json (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/postmark.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/priority.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/priority_inactive.png (100%) rename Resources/Textures/{Nyanotrasen => }/Objects/Specific/Mail/mail.rsi/trash.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/broken.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/fragile.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/icon.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/inhand-left.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/inhand-right.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/locked.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/meta.json (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/priority.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png (100%) rename Resources/Textures/{_NF => }/Objects/Specific/Mail/mail_large.rsi/trash.png (100%) rename Resources/Textures/{_NF => }/Objects/Weapons/Guns/Launchers/mail.rsi/bolt-open.png (100%) rename Resources/Textures/{_NF => }/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BACKPACK.png (100%) rename Resources/Textures/{_NF => }/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BELT.png (100%) rename Resources/Textures/{_NF => }/Objects/Weapons/Guns/Launchers/mail.rsi/icon.png (100%) rename Resources/Textures/{_NF => }/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-left.png (100%) rename Resources/Textures/{_NF => }/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-right.png (100%) rename Resources/Textures/{_NF => }/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json (100%) diff --git a/Content.Server/Mail/DelayedItemComponent.cs b/Content.Server/Mail/DelayedItemComponent.cs new file mode 100644 index 00000000000..8b9c281990b --- /dev/null +++ b/Content.Server/Mail/DelayedItemComponent.cs @@ -0,0 +1,15 @@ +namespace Content.Server.Mail; + +/// +/// A placeholder for another entity, spawned when dropped or placed in someone's hands. +/// Useful for storing instant effect entities, e.g. smoke, in the mail. +/// +[RegisterComponent] +public sealed partial class DelayedItemComponent : Component +{ + /// + /// The entity to replace this when opened or dropped. + /// + [DataField] + public string Item = "None"; +} diff --git a/Content.Server/Mail/DelayedItemSystem.cs b/Content.Server/Mail/DelayedItemSystem.cs new file mode 100644 index 00000000000..0bd3d1928b8 --- /dev/null +++ b/Content.Server/Mail/DelayedItemSystem.cs @@ -0,0 +1,55 @@ +using Content.Shared.Damage; +using Content.Shared.Hands; +using Robust.Shared.Containers; + +namespace Content.Server.Mail; + +/// +/// A placeholder for another entity, spawned when taken out of a container, with the placeholder deleted shortly after. +/// Useful for storing instant effect entities, e.g. smoke, in the mail. +/// +public sealed class DelayedItemSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnDropAttempt); + SubscribeLocalEvent(OnHandEquipped); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnRemovedFromContainer); + } + + /// + /// EntGotRemovedFromContainerMessage handler - spawn the intended entity after removed from a container. + /// + private void OnRemovedFromContainer(EntityUid uid, DelayedItemComponent component, ContainerModifiedMessage args) + { + Spawn(component.Item, Transform(uid).Coordinates); + } + + /// + /// GotEquippedHandEvent handler - destroy the placeholder. + /// + private void OnHandEquipped(EntityUid uid, DelayedItemComponent component, EquippedHandEvent args) + { + EntityManager.DeleteEntity(uid); + } + + /// + /// OnDropAttempt handler - destroy the placeholder. + /// + private void OnDropAttempt(EntityUid uid, DelayedItemComponent component, DropAttemptEvent args) + { + EntityManager.DeleteEntity(uid); + } + + /// + /// OnDamageChanged handler - item has taken damage (e.g. inside the envelope), spawn the intended entity outside of any container and delete the placeholder. + /// + private void OnDamageChanged(EntityUid uid, DelayedItemComponent component, DamageChangedEvent args) + { + Spawn(component.Item, Transform(uid).Coordinates); + EntityManager.DeleteEntity(uid); + } +} diff --git a/Content.Server/Mail/MailConstants.cs b/Content.Server/Mail/MailConstants.cs new file mode 100644 index 00000000000..681699b08fe --- /dev/null +++ b/Content.Server/Mail/MailConstants.cs @@ -0,0 +1,37 @@ +namespace Content.Server.Mail; + +/// +/// A set of localized strings related to mail entities +/// +public struct MailEntityStrings +{ + public string NameAddressed; + public string DescClose; + public string DescFar; +} + +/// +/// Constants related to mail. +/// +public sealed class MailConstants : EntitySystem +{ + /// + /// Locale strings related to small parcels. + /// + public static readonly MailEntityStrings Mail = new() + { + NameAddressed = "mail-item-name-addressed", + DescClose = "mail-desc-close", + DescFar = "mail-desc-far" + }; + + /// + /// Locale strings related to large packages. + /// + public static readonly MailEntityStrings MailLarge = new() + { + NameAddressed = "mail-large-item-name-addressed", + DescClose = "mail-large-desc-close", + DescFar = "mail-large-desc-far" + }; +} diff --git a/Content.Server/_NF/Mail/DelayedItemComponent.cs b/Content.Server/_NF/Mail/DelayedItemComponent.cs deleted file mode 100644 index dbf1ab6fcbb..00000000000 --- a/Content.Server/_NF/Mail/DelayedItemComponent.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Content.Server.Mail -{ - /// - /// A placeholder for another entity, spawned when dropped or placed in someone's hands. - /// Useful for storing instant effect entities, e.g. smoke, in the mail. - /// - [RegisterComponent] - public sealed partial class DelayedItemComponent : Component - { - /// - /// The entity to replace this when opened or dropped. - /// - [DataField] - public string Item = "None"; - } -} diff --git a/Content.Server/_NF/Mail/DelayedItemSystem.cs b/Content.Server/_NF/Mail/DelayedItemSystem.cs deleted file mode 100644 index a8dd5fae73a..00000000000 --- a/Content.Server/_NF/Mail/DelayedItemSystem.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Content.Shared.Damage; -using Content.Shared.Hands; -using Robust.Shared.Containers; - -namespace Content.Server.Mail -{ - /// - /// A placeholder for another entity, spawned when taken out of a container, with the placeholder deleted shortly after. - /// Useful for storing instant effect entities, e.g. smoke, in the mail. - /// - public sealed class DelayedItemSystem : EntitySystem - { - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnDropAttempt); - SubscribeLocalEvent(OnHandEquipped); - SubscribeLocalEvent(OnDamageChanged); - SubscribeLocalEvent(OnRemovedFromContainer); - } - - /// - /// EntGotRemovedFromContainerMessage handler - spawn the intended entity after removed from a container. - /// - private void OnRemovedFromContainer(EntityUid uid, DelayedItemComponent component, ContainerModifiedMessage args) - { - Spawn(component.Item, Transform(uid).Coordinates); - } - - /// - /// GotEquippedHandEvent handler - destroy the placeholder. - /// - private void OnHandEquipped(EntityUid uid, DelayedItemComponent component, EquippedHandEvent args) - { - EntityManager.DeleteEntity(uid); - } - - /// - /// OnDropAttempt handler - destroy the placeholder. - /// - private void OnDropAttempt(EntityUid uid, DelayedItemComponent component, DropAttemptEvent args) - { - EntityManager.DeleteEntity(uid); - } - - /// - /// OnDamageChanged handler - item has taken damage (e.g. inside the envelope), spawn the intended entity outside of any container and delete the placeholder. - /// - private void OnDamageChanged(EntityUid uid, DelayedItemComponent component, DamageChangedEvent args) - { - Spawn(component.Item, Transform(uid).Coordinates); - EntityManager.DeleteEntity(uid); - } - } -} diff --git a/Content.Server/_NF/Mail/MailConstants.cs b/Content.Server/_NF/Mail/MailConstants.cs deleted file mode 100644 index a739a70ab89..00000000000 --- a/Content.Server/_NF/Mail/MailConstants.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Content.Server.Mail -{ - /// - /// A set of localized strings related to mail entities - /// - public struct MailEntityStrings - { - public string NameAddressed; - public string DescClose; - public string DescFar; - } - - /// - /// Constants related to mail. - /// - public sealed class MailConstants : EntitySystem - { - /// - /// Locale strings related to small parcels. - /// - public static readonly MailEntityStrings Mail = new() - { - NameAddressed = "mail-item-name-addressed", - DescClose = "mail-desc-close", - DescFar = "mail-desc-far" - }; - - /// - /// Locale strings related to large packages. - /// - public static readonly MailEntityStrings MailLarge = new() - { - NameAddressed = "mail-large-item-name-addressed", - DescClose = "mail-large-desc-close", - DescFar = "mail-large-desc-far" - }; - } -} \ No newline at end of file diff --git a/Resources/Locale/en-US/_NF/mail/mail.ftl b/Resources/Locale/en-US/_NF/mail/mail.ftl deleted file mode 100644 index 7ab4f6b6f55..00000000000 --- a/Resources/Locale/en-US/_NF/mail/mail.ftl +++ /dev/null @@ -1,10 +0,0 @@ -mail-large-item-name-unaddressed = package -mail-large-item-name-addressed = package ({$recipient}) -mail-large-desc-far = A large package. -# DelaV - Removed "Last known location" -mail-large-desc-close = A large package addressed to {CAPITALIZE($name)}, {$job}. - -### Frontier: mailtestbulk -command-mailtestbulk = Sends one of each type of parcel to a given mail teleporter. Implicitly calls mailnow. -command-mailtestbulk-help = Usage: {$command} -command-mailtestbulk-success = Success! All mail teleporters will be delivering another round of mail soon. diff --git a/Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl b/Resources/Locale/en-US/mail/commands.ftl similarity index 53% rename from Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl rename to Resources/Locale/en-US/mail/commands.ftl index 40c292d7ddd..1f471bb7a59 100644 --- a/Resources/Locale/en-US/nyanotrasen/Mail/mail.ftl +++ b/Resources/Locale/en-US/mail/commands.ftl @@ -1,22 +1,5 @@ -mail-recipient-mismatch = Recipient name or job does not match. -mail-invalid-access = Recipient name and job match, but access isn't as expected. -mail-locked = The anti-tamper lock hasn't been removed. Tap the recipient's ID. -mail-desc-far = A parcel of mail. You can't make out who it's addressed to from this distance. -mail-desc-close = A parcel of mail addressed to {CAPITALIZE($name)}, {$job}. -mail-desc-fragile = It has a [color=red]red fragile label[/color]. -mail-desc-priority = The anti-tamper lock's [color=yellow]yellow priority tape[/color] is active. Better deliver it on time! -mail-desc-priority-inactive = The anti-tamper lock's [color=#886600]yellow priority tape[/color] is inactive. -mail-unlocked = Anti-tamper system unlocked. -mail-unlocked-by-emag = Anti-tamper system *BZZT*. -mail-unlocked-reward = Anti-tamper system unlocked. {$bounty} spesos have been added to logistics' account. -mail-penalty-lock = ANTI-TAMPER LOCK BROKEN. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. -mail-penalty-fragile = INTEGRITY COMPROMISED. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. -mail-penalty-expired = DELIVERY PAST DUE. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. -mail-item-name-unaddressed = mail -mail-item-name-addressed = mail ({$recipient}) - +# Mailto command-mailto-description = Queue a parcel to be delivered to an entity. Example usage: `mailto 1234 5678 false false`. The target container's contents will be transferred to an actual mail parcel. -### Frontier: add is-large description command-mailto-help = Usage: {$command} [is-fragile: true or false] [is-priority: true or false] [is-large: true or false, optional] command-mailto-no-mailreceiver = Target recipient entity does not have a {$requiredComponent}. command-mailto-no-blankmail = The {$blankMail} prototype doesn't exist. Something is very wrong. Contact a programmer. @@ -26,6 +9,12 @@ command-mailto-unable-to-receive = Target recipient entity was unable to be setu command-mailto-no-teleporter-found = Target recipient entity was unable to be matched to any station's mail teleporter. Recipient may be off-station. command-mailto-success = Success! Mail parcel has been queued for next teleport in {$timeToTeleport} seconds. +# Mailnow command-mailnow = Force all mail teleporters to deliver another round of mail as soon as possible. This will not bypass the undelivered mail limit. command-mailnow-help = Usage: {$command} command-mailnow-success = Success! All mail teleporters will be delivering another round of mail soon. + +# Mailtestbulk +command-mailtestbulk = Sends one of each type of parcel to a given mail teleporter. Implicitly calls mailnow. +command-mailtestbulk-help = Usage: {$command} +command-mailtestbulk-success = Success! All mail teleporters will be delivering another round of mail soon. diff --git a/Resources/Locale/en-US/mail/mail.ftl b/Resources/Locale/en-US/mail/mail.ftl new file mode 100644 index 00000000000..5a277377324 --- /dev/null +++ b/Resources/Locale/en-US/mail/mail.ftl @@ -0,0 +1,23 @@ +mail-recipient-mismatch = Recipient name or job does not match. +mail-invalid-access = Recipient name and job match, but access isn't as expected. +mail-locked = The anti-tamper lock hasn't been removed. Tap the recipient's ID. +mail-desc-far = A parcel of mail. You can't make out who it's addressed to from this distance. +mail-desc-close = A parcel of mail addressed to {CAPITALIZE($name)}, {$job}. +mail-desc-fragile = It has a [color=red]red fragile label[/color]. +mail-desc-priority = The anti-tamper lock's [color=yellow]yellow priority tape[/color] is active. Better deliver it on time! +mail-desc-priority-inactive = The anti-tamper lock's [color=#886600]yellow priority tape[/color] is inactive. +mail-unlocked = Anti-tamper system unlocked. +mail-unlocked-by-emag = Anti-tamper system *BZZT*. +mail-unlocked-reward = Anti-tamper system unlocked. {$bounty} spesos have been added to logistics' account. +mail-penalty-lock = ANTI-TAMPER LOCK BROKEN. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. +mail-penalty-fragile = INTEGRITY COMPROMISED. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. +mail-penalty-expired = DELIVERY PAST DUE. LOGISTICS BANK ACCOUNT PENALIZED BY {$credits} SPESOS. +mail-item-name-unaddressed = mail +mail-item-name-addressed = mail ({$recipient}) + +mail-large-item-name-unaddressed = package +mail-large-item-name-addressed = package ({$recipient}) +mail-large-desc-far = A large package. +mail-large-desc-close = A large package addressed to {CAPITALIZE($name)}, {$job}. + + diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml index 3cf293ff3c2..81e11d9d084 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Devices/cartridges.yml @@ -57,5 +57,5 @@ - type: Cartridge programName: mail-metrics-program-name icon: - sprite: Nyanotrasen/Objects/Specific/Mail/mail.rsi + sprite: Objects/Specific/Mail/mail.rsi state: icon diff --git a/Resources/Prototypes/_NF/Entities/Objects/Misc/mail_capsule.yml b/Resources/Prototypes/Entities/Objects/Misc/mail_capsule.yml similarity index 97% rename from Resources/Prototypes/_NF/Entities/Objects/Misc/mail_capsule.yml rename to Resources/Prototypes/Entities/Objects/Misc/mail_capsule.yml index 29e0df57869..bd6c9057cd0 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Misc/mail_capsule.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/mail_capsule.yml @@ -14,7 +14,7 @@ - MailCapsule - Trash - type: Sprite - sprite: _NF/Objects/Misc/mail_capsule.rsi + sprite: Objects/Misc/mail_capsule.rsi layers: - state: icon-empty - type: ItemSlots @@ -94,7 +94,7 @@ - Mail - Paper - HyperlinkBook - sprite: _NF/Objects/Misc/mail_capsule.rsi + sprite: Objects/Misc/mail_capsule.rsi - type: Dumpable - type: Damageable damageContainer: Inorganic diff --git a/Resources/Prototypes/_NF/Mail/Items/boxes.yml b/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/boxes.yml similarity index 53% rename from Resources/Prototypes/_NF/Mail/Items/boxes.yml rename to Resources/Prototypes/Entities/Objects/Specific/Mail/Items/boxes.yml index d61dc6c1488..536736fc904 100644 --- a/Resources/Prototypes/_NF/Mail/Items/boxes.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/boxes.yml @@ -8,24 +8,24 @@ components: - type: StorageFill contents: - - id: SoapNT - amount: 1 - - id: Soap - amount: 1 - - id: SoapHomemade - amount: 1 - - id: SoapDeluxe - amount: 1 + - id: SoapNT + amount: 1 + - id: Soap + amount: 1 + - id: SoapHomemade + amount: 1 + - id: SoapDeluxe + amount: 1 - type: Storage maxItemSize: Normal grid: - - 0,0,3,1 + - 0,0,3,1 whitelist: tags: - - Soap + - Soap - type: Sprite layers: - - state: box + - state: box - type: entity name: scented soap sampler pack @@ -35,24 +35,24 @@ components: - type: StorageFill contents: - - id: SoapNT - amount: 1 - - id: Soap - amount: 1 - - id: SoapOmega - amount: 1 - - id: SoapDeluxe - amount: 1 + - id: SoapNT + amount: 1 + - id: Soap + amount: 1 + - id: SoapOmega + amount: 1 + - id: SoapDeluxe + amount: 1 - type: Storage maxItemSize: Normal grid: - - 0,0,3,1 + - 0,0,3,1 whitelist: tags: - - Soap + - Soap - type: Sprite layers: - - state: box + - state: box - type: entity name: Build-a-Buddy kit @@ -63,32 +63,32 @@ components: - type: StorageFill contents: - - id: HeadHuman - amount: 1 - - id: TorsoHuman - amount: 1 - - id: LeftArmHuman - amount: 1 - - id: RightArmHuman - amount: 1 - - id: LeftHandHuman - amount: 1 - - id: RightHandHuman - amount: 1 - - id: LeftLegHuman - amount: 1 - - id: RightLegHuman - amount: 1 - - id: LeftFootHuman - amount: 1 - - id: RightFootHuman - amount: 1 + - id: HeadHuman + amount: 1 + - id: TorsoHuman + amount: 1 + - id: LeftArmHuman + amount: 1 + - id: RightArmHuman + amount: 1 + - id: LeftHandHuman + amount: 1 + - id: RightHandHuman + amount: 1 + - id: LeftLegHuman + amount: 1 + - id: RightLegHuman + amount: 1 + - id: LeftFootHuman + amount: 1 + - id: RightFootHuman + amount: 1 - type: Storage grid: - 0,0,4,3 whitelist: components: - - BodyPart + - BodyPart # DeltaV - Goblins Aren't Real #- type: entity @@ -130,26 +130,26 @@ components: - type: StorageFill contents: - - id: HeadReptilian - amount: 1 - - id: TorsoReptilian - amount: 1 - - id: LeftArmReptilian - amount: 1 - - id: RightArmReptilian - amount: 1 - - id: LeftHandReptilian - amount: 1 - - id: RightHandReptilian - amount: 1 - - id: LeftLegReptilian - amount: 1 - - id: RightLegReptilian - amount: 1 - - id: LeftFootReptilian - amount: 1 - - id: RightFootReptilian - amount: 1 + - id: HeadReptilian + amount: 1 + - id: TorsoReptilian + amount: 1 + - id: LeftArmReptilian + amount: 1 + - id: RightArmReptilian + amount: 1 + - id: LeftHandReptilian + amount: 1 + - id: RightHandReptilian + amount: 1 + - id: LeftLegReptilian + amount: 1 + - id: RightLegReptilian + amount: 1 + - id: LeftFootReptilian + amount: 1 + - id: RightFootReptilian + amount: 1 - type: entity name: Build-a-Buddy kit @@ -160,26 +160,26 @@ components: - type: StorageFill contents: - - id: HeadSlime - amount: 1 - - id: TorsoSlime - amount: 1 - - id: LeftArmSlime - amount: 1 - - id: RightArmSlime - amount: 1 - - id: LeftHandSlime - amount: 1 - - id: RightHandSlime - amount: 1 - - id: LeftLegSlime - amount: 1 - - id: RightLegSlime - amount: 1 - - id: LeftFootSlime - amount: 1 - - id: RightFootSlime - amount: 1 + - id: HeadSlime + amount: 1 + - id: TorsoSlime + amount: 1 + - id: LeftArmSlime + amount: 1 + - id: RightArmSlime + amount: 1 + - id: LeftHandSlime + amount: 1 + - id: RightHandSlime + amount: 1 + - id: LeftLegSlime + amount: 1 + - id: RightLegSlime + amount: 1 + - id: LeftFootSlime + amount: 1 + - id: RightFootSlime + amount: 1 - type: entity name: Build-a-Buddy kit @@ -190,23 +190,23 @@ components: - type: StorageFill contents: - - id: HeadVulpkanin - amount: 1 - - id: TorsoVulpkanin - amount: 1 - - id: LeftArmVulpkanin - amount: 1 - - id: RightArmVulpkanin - amount: 1 - - id: LeftHandVulpkanin - amount: 1 - - id: RightHandVulpkanin - amount: 1 - - id: LeftLegVulpkanin - amount: 1 - - id: RightLegVulpkanin - amount: 1 - - id: LeftFootVulpkanin - amount: 1 - - id: RightFootVulpkanin - amount: 1 + - id: HeadVulpkanin + amount: 1 + - id: TorsoVulpkanin + amount: 1 + - id: LeftArmVulpkanin + amount: 1 + - id: RightArmVulpkanin + amount: 1 + - id: LeftHandVulpkanin + amount: 1 + - id: RightHandVulpkanin + amount: 1 + - id: LeftLegVulpkanin + amount: 1 + - id: RightLegVulpkanin + amount: 1 + - id: LeftFootVulpkanin + amount: 1 + - id: RightFootVulpkanin + amount: 1 diff --git a/Resources/Prototypes/_NF/Mail/Items/misc.yml b/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/misc.yml similarity index 100% rename from Resources/Prototypes/_NF/Mail/Items/misc.yml rename to Resources/Prototypes/Entities/Objects/Specific/Mail/Items/misc.yml diff --git a/Resources/Prototypes/_NF/Mail/Items/paper.yml b/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/paper.yml similarity index 100% rename from Resources/Prototypes/_NF/Mail/Items/paper.yml rename to Resources/Prototypes/Entities/Objects/Specific/Mail/Items/paper.yml diff --git a/Resources/Prototypes/_NF/Entities/Objects/Specific/Mail/base_mail_large.yml b/Resources/Prototypes/Entities/Objects/Specific/Mail/base_mail_large.yml similarity index 97% rename from Resources/Prototypes/_NF/Entities/Objects/Specific/Mail/base_mail_large.yml rename to Resources/Prototypes/Entities/Objects/Specific/Mail/base_mail_large.yml index 3ba4cfd64e0..a5dcefacba5 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Specific/Mail/base_mail_large.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mail/base_mail_large.yml @@ -9,7 +9,7 @@ size: Ginormous - type: Sprite scale: 0.8, 0.8 - sprite: _NF/Objects/Specific/Mail/mail_large.rsi + sprite: Objects/Specific/Mail/mail_large.rsi layers: - state: icon map: ["enum.MailVisualLayers.Icon"] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 594ffb4d4d9..62ed28e1148 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -375,3 +375,29 @@ tags: - CartridgeRocket proto: ImmovableRodSlow + +# Frontier mail RPDS +- type: entity + name: mail RPDS + parent: WeaponLauncherChinaLake + id: WeaponMailLake + description: Rap(b?)id Parcel Delivery System + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Launchers/mail.rsi + layers: + - state: icon + map: ["enum.GunVisualLayers.Base"] + - type: Clothing + sprite: Objects/Weapons/Guns/Launchers/mail.rsi + quickEquip: false + slots: + - Back + - Belt + - suitStorage + - type: BallisticAmmoProvider + proto: null + whitelist: + tags: + - MailCapsule + capacity: 4 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml index 0ffa4850806..fd77f19dccb 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/base_mail.yml @@ -11,7 +11,7 @@ - type: AccessReader - type: Sprite scale: 0.7, 0.7 # Frontier - sprite: Nyanotrasen/Objects/Specific/Mail/mail.rsi + sprite: Objects/Specific/Mail/mail.rsi layers: - state: icon map: ["enum.MailVisualLayers.Icon"] diff --git a/Resources/Prototypes/Recipes/Lathes/misc.yml b/Resources/Prototypes/Recipes/Lathes/misc.yml index ab13dc4573f..2c0e1eeec38 100644 --- a/Resources/Prototypes/Recipes/Lathes/misc.yml +++ b/Resources/Prototypes/Recipes/Lathes/misc.yml @@ -207,3 +207,19 @@ materials: Steel: 400 Glass: 200 + +- type: latheRecipe + id: ClothingShoesBootsMagAdv + result: ClothingShoesBootsMagAdv + completetime: 12 + materials: + Silver: 1000 + Gold: 500 + +- type: latheRecipe + id: MailCapsule + result: MailCapsulePrimed + completetime: 1 + materials: + Glass: 100 + Plastic: 100 diff --git a/Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml deleted file mode 100644 index 2804953fcfc..00000000000 --- a/Resources/Prototypes/_NF/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ /dev/null @@ -1,24 +0,0 @@ -- type: entity - name: mail RPDS - parent: WeaponLauncherChinaLake - id: WeaponMailLake - description: Rap(b?)id Parcel Delivery System - components: - - type: Sprite - sprite: _NF/Objects/Weapons/Guns/Launchers/mail.rsi - layers: - - state: icon - map: ["enum.GunVisualLayers.Base"] - - type: Clothing - sprite: _NF/Objects/Weapons/Guns/Launchers/mail.rsi - quickEquip: false - slots: - - Back - - Belt - - suitStorage - - type: BallisticAmmoProvider - proto: null - whitelist: - tags: - - MailCapsule - capacity: 4 diff --git a/Resources/Prototypes/_NF/Recipes/Lathes/misc.yml b/Resources/Prototypes/_NF/Recipes/Lathes/misc.yml deleted file mode 100644 index 22e1f9605f7..00000000000 --- a/Resources/Prototypes/_NF/Recipes/Lathes/misc.yml +++ /dev/null @@ -1,15 +0,0 @@ -- type: latheRecipe - id: ClothingShoesBootsMagAdv - result: ClothingShoesBootsMagAdv - completetime: 12 - materials: - Silver: 1000 - Gold: 500 - -- type: latheRecipe - id: MailCapsule - result: MailCapsulePrimed - completetime: 1 - materials: - Glass: 100 - Plastic: 100 \ No newline at end of file diff --git a/Resources/Prototypes/_NF/tags.yml b/Resources/Prototypes/_NF/tags.yml deleted file mode 100644 index dbb5c68a25d..00000000000 --- a/Resources/Prototypes/_NF/tags.yml +++ /dev/null @@ -1,53 +0,0 @@ -- type: Tag - id: CaveFactory - -- type: Tag - id: DockTransit - -- type: Tag - id: LabGrown - -- type: Tag - id: CatWearable - -- type: Tag - id: BookSpaceLaw - -- type: Tag - id: CrossbowBolt - -- type: Tag - id: WeaponMeleeStake - -- type: Tag - id: Censer - -- type: Tag - id: ReligiousSymbol - -- type: Tag - id: Crucifix - -- type: Tag - id: ObjectOfSpiritualSignificance - -- type: Tag - id: Ash - -- type: Tag - id: LavaMercenary - -- type: Tag - id: MysteryFigureBox - -- type: Tag - id: WhoopieCushion - -- type: Tag - id: Mustard - -- type: Tag - id: Mail - -- type: Tag - id: MailCapsule diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index cc81a2ed64b..77cc4f372f2 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -25,6 +25,9 @@ - type: Tag id: Arrow +- type: Tag + id: Ash + - type: Tag id: ATVKeys @@ -352,6 +355,9 @@ - type: Tag id: CartridgeRocket +- type: Tag + id: CaveFactory + # Allows you to walk over tile entities such as lava without steptrigger - type: Tag id: Catwalk @@ -803,6 +809,12 @@ - type: Tag id: MacroBomb +- type: Tag + id: Mail + +- type: Tag + id: MailCapsule + - type: Tag id: MimeBelt @@ -916,6 +928,12 @@ - type: Tag id: Multitool +- type: Tag + id: Mustard + +- type: Tag + id: MysteryFigureBox + - type: Tag id: NoBlockAnchoring @@ -1295,6 +1313,9 @@ - type: Tag id: WhitelistChameleon +- type: Tag + id: WhoopieCushion + - type: Tag id: Window diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-cash.png b/Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-cash.png similarity index 100% rename from Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-cash.png rename to Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-cash.png diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-empty.png b/Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-empty.png similarity index 100% rename from Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-empty.png rename to Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-empty.png diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-food.png b/Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-food.png similarity index 100% rename from Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-food.png rename to Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-food.png diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-mail.png b/Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-mail.png similarity index 100% rename from Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/icon-mail.png rename to Resources/Textures/Objects/Misc/mail_capsule.rsi/icon-mail.png diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/meta.json b/Resources/Textures/Objects/Misc/mail_capsule.rsi/meta.json similarity index 100% rename from Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/meta.json rename to Resources/Textures/Objects/Misc/mail_capsule.rsi/meta.json diff --git a/Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/spent.png b/Resources/Textures/Objects/Misc/mail_capsule.rsi/spent.png similarity index 100% rename from Resources/Textures/_NF/Objects/Misc/mail_capsule.rsi/spent.png rename to Resources/Textures/Objects/Misc/mail_capsule.rsi/spent.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/broken.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/broken.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/broken.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/broken.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/fragile.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/fragile.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/fragile.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/fragile.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/icon.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/icon.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/icon.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/icon.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/locked.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/locked.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/locked.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/locked.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/meta.json b/Resources/Textures/Objects/Specific/Mail/mail.rsi/meta.json similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/meta.json rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/meta.json diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/postmark.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/postmark.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/postmark.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/postmark.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/priority.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/priority.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/priority.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/priority.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/priority_inactive.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/priority_inactive.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/priority_inactive.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/priority_inactive.png diff --git a/Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/trash.png b/Resources/Textures/Objects/Specific/Mail/mail.rsi/trash.png similarity index 100% rename from Resources/Textures/Nyanotrasen/Objects/Specific/Mail/mail.rsi/trash.png rename to Resources/Textures/Objects/Specific/Mail/mail.rsi/trash.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/broken.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/broken.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/broken.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/broken.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/fragile.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/fragile.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/fragile.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/fragile.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/icon.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/icon.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/icon.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/icon.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/inhand-left.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/inhand-left.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/inhand-left.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/inhand-left.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/inhand-right.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/inhand-right.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/inhand-right.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/inhand-right.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/locked.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/locked.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/locked.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/locked.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/meta.json b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/meta.json similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/meta.json rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/meta.json diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/priority.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/priority.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/priority_inactive.png diff --git a/Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/trash.png b/Resources/Textures/Objects/Specific/Mail/mail_large.rsi/trash.png similarity index 100% rename from Resources/Textures/_NF/Objects/Specific/Mail/mail_large.rsi/trash.png rename to Resources/Textures/Objects/Specific/Mail/mail_large.rsi/trash.png diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/bolt-open.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/bolt-open.png similarity index 100% rename from Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/bolt-open.png rename to Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/bolt-open.png diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BACKPACK.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BACKPACK.png similarity index 100% rename from Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BACKPACK.png rename to Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BACKPACK.png diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BELT.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BELT.png similarity index 100% rename from Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BELT.png rename to Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/equipped-BELT.png diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/icon.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/icon.png similarity index 100% rename from Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/icon.png rename to Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/icon.png diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-left.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-left.png similarity index 100% rename from Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-left.png rename to Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-left.png diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-right.png similarity index 100% rename from Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-right.png rename to Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/inhand-right.png diff --git a/Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json similarity index 100% rename from Resources/Textures/_NF/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json rename to Resources/Textures/Objects/Weapons/Guns/Launchers/mail.rsi/meta.json From 2d80e25a9a28ec873c0a4f1658c4d8726ee36992 Mon Sep 17 00:00:00 2001 From: fox Date: Sun, 13 Oct 2024 21:51:12 +0300 Subject: [PATCH 09/14] Namespacen't 2 --- .../Cartridges/MailMetricUi.cs | 4 +-- .../Cartridges/MailMetricUiFragment.xaml | 2 +- .../Cartridges/MailMetricUiFragment.xaml.cs | 3 +-- .../StationLogisticStatsDatabaseComponent.cs | 4 +-- .../Cargo/Systems/LogisticStatsSystem.cs | 9 ++----- .../MailMetricsCartridgeComponent.cs | 2 +- .../Cartridges/MailMetricsCartridgeSystem.cs | 9 +++---- .../{ => Components}/DelayedItemComponent.cs | 2 +- .../Mail/Components/MailComponent.cs | 0 .../Mail/Components/MailReceiverComponent.cs | 0 .../Components/MailTeleporterComponent.cs | 0 .../Components/StationMailRouterComponent.cs | 2 +- .../{Nyanotrasen => }/Mail/MailCommands.cs | 1 + .../Mail/{ => Systems}/DelayedItemSystem.cs | 18 ++++++------- .../Mail => Mail/Systems}/MailSystem.cs | 26 ++++++------------- 15 files changed, 33 insertions(+), 49 deletions(-) rename Content.Client/{DeltaV => }/CartridgeLoader/Cartridges/MailMetricUi.cs (91%) rename Content.Client/{DeltaV => }/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml (98%) rename Content.Client/{DeltaV => }/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs (97%) rename Content.Server/{DeltaV => }/Cargo/Components/StationLogisticStatsDatabaseComponent.cs (88%) rename Content.Server/{DeltaV => }/Cargo/Systems/LogisticStatsSystem.cs (91%) rename Content.Server/{DeltaV => }/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs (82%) rename Content.Server/{DeltaV => }/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs (93%) rename Content.Server/Mail/{ => Components}/DelayedItemComponent.cs (90%) rename Content.Server/{Nyanotrasen => }/Mail/Components/MailComponent.cs (100%) rename Content.Server/{Nyanotrasen => }/Mail/Components/MailReceiverComponent.cs (100%) rename Content.Server/{Nyanotrasen => }/Mail/Components/MailTeleporterComponent.cs (100%) rename Content.Server/{Nyanotrasen => }/Mail/Components/StationMailRouterComponent.cs (81%) rename Content.Server/{Nyanotrasen => }/Mail/MailCommands.cs (99%) rename Content.Server/Mail/{ => Systems}/DelayedItemSystem.cs (58%) rename Content.Server/{Nyanotrasen/Mail => Mail/Systems}/MailSystem.cs (98%) diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs b/Content.Client/CartridgeLoader/Cartridges/MailMetricUi.cs similarity index 91% rename from Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs rename to Content.Client/CartridgeLoader/Cartridges/MailMetricUi.cs index f1688c8dab4..504dda7c56e 100644 --- a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs +++ b/Content.Client/CartridgeLoader/Cartridges/MailMetricUi.cs @@ -1,8 +1,8 @@ -using Robust.Client.UserInterface; using Content.Client.UserInterface.Fragments; using Content.Shared.CartridgeLoader.Cartridges; +using Robust.Client.UserInterface; -namespace Content.Client.DeltaV.CartridgeLoader.Cartridges; +namespace Content.Client.CartridgeLoader.Cartridges; public sealed partial class MailMetricUi : UIFragment { diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml b/Content.Client/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml similarity index 98% rename from Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml rename to Content.Client/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml index c31a1c6063d..39639fe8c97 100644 --- a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml +++ b/Content.Client/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml @@ -1,5 +1,5 @@ /// Added to the abstract representation of a station to track stats related to mail delivery and income @@ -11,4 +11,4 @@ public sealed partial class StationLogisticStatsComponent : Component { [DataField] public MailStats Metrics { get; set; } -} \ No newline at end of file +} diff --git a/Content.Server/DeltaV/Cargo/Systems/LogisticStatsSystem.cs b/Content.Server/Cargo/Systems/LogisticStatsSystem.cs similarity index 91% rename from Content.Server/DeltaV/Cargo/Systems/LogisticStatsSystem.cs rename to Content.Server/Cargo/Systems/LogisticStatsSystem.cs index e18bd4c7cf2..6abf4eb5a47 100644 --- a/Content.Server/DeltaV/Cargo/Systems/LogisticStatsSystem.cs +++ b/Content.Server/Cargo/Systems/LogisticStatsSystem.cs @@ -1,16 +1,11 @@ -using Content.Server.DeltaV.Cargo.Components; using Content.Shared.Cargo; +using Content.Server.Cargo.Components; using JetBrains.Annotations; -namespace Content.Server.DeltaV.Cargo.Systems; +namespace Content.Server.Cargo.Systems; public sealed partial class LogisticStatsSystem : SharedCargoSystem { - public override void Initialize() - { - base.Initialize(); - } - [PublicAPI] public void AddOpenedMailEarnings(EntityUid uid, StationLogisticStatsComponent component, int earnedMoney) { diff --git a/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs b/Content.Server/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs similarity index 82% rename from Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs rename to Content.Server/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs index 11a6c5c5bb1..380a4d90c04 100644 --- a/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs +++ b/Content.Server/CartridgeLoader/Cartridges/MailMetricsCartridgeComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.DeltaV.CartridgeLoader.Cartridges; +namespace Content.Server.CartridgeLoader.Cartridges; [RegisterComponent, Access(typeof(MailMetricsCartridgeSystem))] public sealed partial class MailMetricsCartridgeComponent : Component diff --git a/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs b/Content.Server/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs similarity index 93% rename from Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs rename to Content.Server/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs index 905e3854ee8..00b6d0a16e8 100644 --- a/Content.Server/DeltaV/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs +++ b/Content.Server/CartridgeLoader/Cartridges/MailMetricsCartridgeSystem.cs @@ -1,12 +1,11 @@ -using Content.Server.DeltaV.Cargo.Components; -using Content.Server.DeltaV.Cargo.Systems; +using Content.Server.Cargo.Components; +using Content.Server.Cargo.Systems; +using Content.Server.Mail.Components; using Content.Server.Station.Systems; -using Content.Server.CartridgeLoader; using Content.Shared.CartridgeLoader; using Content.Shared.CartridgeLoader.Cartridges; -using Content.Server.Mail.Components; -namespace Content.Server.DeltaV.CartridgeLoader.Cartridges; +namespace Content.Server.CartridgeLoader.Cartridges; public sealed class MailMetricsCartridgeSystem : EntitySystem { diff --git a/Content.Server/Mail/DelayedItemComponent.cs b/Content.Server/Mail/Components/DelayedItemComponent.cs similarity index 90% rename from Content.Server/Mail/DelayedItemComponent.cs rename to Content.Server/Mail/Components/DelayedItemComponent.cs index 8b9c281990b..256da125d18 100644 --- a/Content.Server/Mail/DelayedItemComponent.cs +++ b/Content.Server/Mail/Components/DelayedItemComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Mail; +namespace Content.Server.Mail.Components; /// /// A placeholder for another entity, spawned when dropped or placed in someone's hands. diff --git a/Content.Server/Nyanotrasen/Mail/Components/MailComponent.cs b/Content.Server/Mail/Components/MailComponent.cs similarity index 100% rename from Content.Server/Nyanotrasen/Mail/Components/MailComponent.cs rename to Content.Server/Mail/Components/MailComponent.cs diff --git a/Content.Server/Nyanotrasen/Mail/Components/MailReceiverComponent.cs b/Content.Server/Mail/Components/MailReceiverComponent.cs similarity index 100% rename from Content.Server/Nyanotrasen/Mail/Components/MailReceiverComponent.cs rename to Content.Server/Mail/Components/MailReceiverComponent.cs diff --git a/Content.Server/Nyanotrasen/Mail/Components/MailTeleporterComponent.cs b/Content.Server/Mail/Components/MailTeleporterComponent.cs similarity index 100% rename from Content.Server/Nyanotrasen/Mail/Components/MailTeleporterComponent.cs rename to Content.Server/Mail/Components/MailTeleporterComponent.cs diff --git a/Content.Server/Nyanotrasen/Mail/Components/StationMailRouterComponent.cs b/Content.Server/Mail/Components/StationMailRouterComponent.cs similarity index 81% rename from Content.Server/Nyanotrasen/Mail/Components/StationMailRouterComponent.cs rename to Content.Server/Mail/Components/StationMailRouterComponent.cs index ce87eb131fc..b90036ecec2 100644 --- a/Content.Server/Nyanotrasen/Mail/Components/StationMailRouterComponent.cs +++ b/Content.Server/Mail/Components/StationMailRouterComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Mail; +namespace Content.Server.Mail.Components; /// /// Designates a station as a place for sending and receiving mail. diff --git a/Content.Server/Nyanotrasen/Mail/MailCommands.cs b/Content.Server/Mail/MailCommands.cs similarity index 99% rename from Content.Server/Nyanotrasen/Mail/MailCommands.cs rename to Content.Server/Mail/MailCommands.cs index e28343710fe..e216650324c 100644 --- a/Content.Server/Nyanotrasen/Mail/MailCommands.cs +++ b/Content.Server/Mail/MailCommands.cs @@ -5,6 +5,7 @@ using Content.Shared.Administration; using Content.Server.Administration; using Content.Server.Mail.Components; +using Content.Server.Mail.Systems; namespace Content.Server.Mail; diff --git a/Content.Server/Mail/DelayedItemSystem.cs b/Content.Server/Mail/Systems/DelayedItemSystem.cs similarity index 58% rename from Content.Server/Mail/DelayedItemSystem.cs rename to Content.Server/Mail/Systems/DelayedItemSystem.cs index 0bd3d1928b8..cb7cb17bea2 100644 --- a/Content.Server/Mail/DelayedItemSystem.cs +++ b/Content.Server/Mail/Systems/DelayedItemSystem.cs @@ -2,7 +2,7 @@ using Content.Shared.Hands; using Robust.Shared.Containers; -namespace Content.Server.Mail; +namespace Content.Server.Mail.Systems; /// /// A placeholder for another entity, spawned when taken out of a container, with the placeholder deleted shortly after. @@ -14,16 +14,16 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnDropAttempt); - SubscribeLocalEvent(OnHandEquipped); - SubscribeLocalEvent(OnDamageChanged); - SubscribeLocalEvent(OnRemovedFromContainer); + SubscribeLocalEvent(OnDropAttempt); + SubscribeLocalEvent(OnHandEquipped); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnRemovedFromContainer); } /// /// EntGotRemovedFromContainerMessage handler - spawn the intended entity after removed from a container. /// - private void OnRemovedFromContainer(EntityUid uid, DelayedItemComponent component, ContainerModifiedMessage args) + private void OnRemovedFromContainer(EntityUid uid, Components.DelayedItemComponent component, ContainerModifiedMessage args) { Spawn(component.Item, Transform(uid).Coordinates); } @@ -31,7 +31,7 @@ private void OnRemovedFromContainer(EntityUid uid, DelayedItemComponent componen /// /// GotEquippedHandEvent handler - destroy the placeholder. /// - private void OnHandEquipped(EntityUid uid, DelayedItemComponent component, EquippedHandEvent args) + private void OnHandEquipped(EntityUid uid, Components.DelayedItemComponent component, EquippedHandEvent args) { EntityManager.DeleteEntity(uid); } @@ -39,7 +39,7 @@ private void OnHandEquipped(EntityUid uid, DelayedItemComponent component, Equip /// /// OnDropAttempt handler - destroy the placeholder. /// - private void OnDropAttempt(EntityUid uid, DelayedItemComponent component, DropAttemptEvent args) + private void OnDropAttempt(EntityUid uid, Components.DelayedItemComponent component, DropAttemptEvent args) { EntityManager.DeleteEntity(uid); } @@ -47,7 +47,7 @@ private void OnDropAttempt(EntityUid uid, DelayedItemComponent component, DropAt /// /// OnDamageChanged handler - item has taken damage (e.g. inside the envelope), spawn the intended entity outside of any container and delete the placeholder. /// - private void OnDamageChanged(EntityUid uid, DelayedItemComponent component, DamageChangedEvent args) + private void OnDamageChanged(EntityUid uid, Components.DelayedItemComponent component, DamageChangedEvent args) { Spawn(component.Item, Transform(uid).Coordinates); EntityManager.DeleteEntity(uid); diff --git a/Content.Server/Nyanotrasen/Mail/MailSystem.cs b/Content.Server/Mail/Systems/MailSystem.cs similarity index 98% rename from Content.Server/Nyanotrasen/Mail/MailSystem.cs rename to Content.Server/Mail/Systems/MailSystem.cs index f50519eae0a..a98757ac9da 100644 --- a/Content.Server/Nyanotrasen/Mail/MailSystem.cs +++ b/Content.Server/Mail/Systems/MailSystem.cs @@ -1,62 +1,52 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; -using Robust.Shared.Audio; -using Robust.Shared.Containers; -using Robust.Shared.Prototypes; -using Robust.Shared.Random; using Content.Server.Access.Systems; using Content.Server.Cargo.Components; using Content.Server.Cargo.Systems; using Content.Server.Chat.Systems; using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.Chemistry.EntitySystems; using Content.Server.Damage.Components; -using Content.Server.DeltaV.Cargo.Components; using Content.Server.Destructible; using Content.Server.Destructible.Thresholds; using Content.Server.Destructible.Thresholds.Behaviors; using Content.Server.Destructible.Thresholds.Triggers; -using Content.Server.Fluids.Components; using Content.Server.Item; using Content.Server.Mail.Components; using Content.Server.Mind; -using Content.Server.Nutrition.Components; -using Content.Server.Nutrition.EntitySystems; using Content.Server.Popups; using Content.Server.Power.Components; -using Content.Server.Station.Systems; using Content.Server.Spawners.EntitySystems; +using Content.Server.Station.Systems; using Content.Shared.Access; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Chat; -using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Damage; -using Content.Shared.Emag.Components; using Content.Shared.Destructible; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Examine; using Content.Shared.Fluids.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; -using Content.Shared.Item; using Content.Shared.Mail; using Content.Shared.Maps; using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.EntitySystems; using Content.Shared.PDA; -using Content.Shared.Random.Helpers; using Content.Shared.Roles; -using Content.Shared.StatusIcon; using Content.Shared.Storage; using Content.Shared.Tag; +using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; using Timer = Robust.Shared.Timing.Timer; -using Content.Server.DeltaV.Cargo.Systems; -namespace Content.Server.Mail +namespace Content.Server.Mail.Systems { public sealed class MailSystem : EntitySystem { @@ -134,7 +124,7 @@ private void OnSpawnPlayer(PlayerSpawningEvent args) return; } - if (!HasComp(station)) + if (!HasComp(station)) return; AddComp(args.SpawnResult.Value); From 3c348210a69bc7c471424e1b6706828c4f948e54 Mon Sep 17 00:00:00 2001 From: fox Date: Sun, 13 Oct 2024 21:52:28 +0300 Subject: [PATCH 10/14] That is NOT an entity system --- Content.Server/Mail/MailConstants.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Mail/MailConstants.cs b/Content.Server/Mail/MailConstants.cs index 681699b08fe..38d37a13269 100644 --- a/Content.Server/Mail/MailConstants.cs +++ b/Content.Server/Mail/MailConstants.cs @@ -13,7 +13,7 @@ public struct MailEntityStrings /// /// Constants related to mail. /// -public sealed class MailConstants : EntitySystem +public static class MailConstants { /// /// Locale strings related to small parcels. From 51d051138d0c43aa02902049fe6941d1288cd635 Mon Sep 17 00:00:00 2001 From: fox Date: Sun, 13 Oct 2024 22:13:43 +0300 Subject: [PATCH 11/14] Shitcode --- .../Mail/Components/DelayedItemComponent.cs | 6 +- .../Mail/Components/MailComponent.cs | 210 ++- .../Mail/Components/MailReceiverComponent.cs | 10 +- .../Components/MailTeleporterComponent.cs | 228 ++-- .../Components/StationMailRouterComponent.cs | 2 +- Content.Server/Mail/MailCommands.cs | 44 +- .../Mail/Systems/DelayedItemSystem.cs | 16 +- Content.Server/Mail/Systems/MailSystem.cs | 1131 ++++++++--------- 8 files changed, 793 insertions(+), 854 deletions(-) diff --git a/Content.Server/Mail/Components/DelayedItemComponent.cs b/Content.Server/Mail/Components/DelayedItemComponent.cs index 256da125d18..f73aef85b06 100644 --- a/Content.Server/Mail/Components/DelayedItemComponent.cs +++ b/Content.Server/Mail/Components/DelayedItemComponent.cs @@ -1,14 +1,14 @@ namespace Content.Server.Mail.Components; /// -/// A placeholder for another entity, spawned when dropped or placed in someone's hands. -/// Useful for storing instant effect entities, e.g. smoke, in the mail. +/// A placeholder for another entity, spawned when dropped or placed in someone's hands. +/// Useful for storing instant effect entities, e.g. smoke, in the mail. /// [RegisterComponent] public sealed partial class DelayedItemComponent : Component { /// - /// The entity to replace this when opened or dropped. + /// The entity to replace this when opened or dropped. /// [DataField] public string Item = "None"; diff --git a/Content.Server/Mail/Components/MailComponent.cs b/Content.Server/Mail/Components/MailComponent.cs index 2b1c4e26e56..af0bdaa87ff 100644 --- a/Content.Server/Mail/Components/MailComponent.cs +++ b/Content.Server/Mail/Components/MailComponent.cs @@ -3,111 +3,109 @@ using Content.Shared.Storage; using Content.Shared.Mail; -namespace Content.Server.Mail.Components +namespace Content.Server.Mail.Components; + +[RegisterComponent] +public sealed partial class MailComponent : SharedMailComponent { - [RegisterComponent] - public sealed partial class MailComponent : SharedMailComponent - { - [DataField] - public string Recipient = "None"; - - [DataField] - public string RecipientJob = "None"; - - // Why do we not use LockComponent? - // Because this can't be locked again, - // and we have special conditions for unlocking, - // and we don't want to add a verb. - [DataField] - public bool IsLocked = true; - - /// - /// Is this parcel profitable to deliver for the station? - /// - /// - /// The station won't receive any award on delivery if this is false. - /// This is useful for broken fragile packages and packages that were - /// not delivered in time. - /// - [DataField] - public bool IsProfitable = true; - - /// - /// Is this package considered fragile? - /// - /// - /// This can be set to true in the YAML files for a mail delivery to - /// always be Fragile, despite its contents. - /// - [DataField] - public bool IsFragile = false; - - /// - /// Is this package considered priority mail? - /// - /// - /// There will be a timer set for its successful delivery. The - /// station's bank account will be penalized if it is not delivered on - /// time. - /// - /// This is set to false on successful delivery. - /// - /// This can be set to true in the YAML files for a mail delivery to - /// always be Priority. - /// - [DataField] - public bool IsPriority = false; - - // Frontier Mail Port: large mail - /// - /// Whether this parcel is large. - /// - [DataField] - public bool IsLarge = false; - // End Frontier: large mail - - /// - /// What will be packaged when the mail is spawned. - /// - [DataField] - public List Contents = new(); - - /// - /// The amount that cargo will be awarded for delivering this mail. - /// - [DataField] - public int Bounty = 750; - - /// - /// Penalty if the mail is destroyed. - /// - [DataField] - public int Penalty = -250; - - /// - /// The sound that's played when the mail's lock is broken. - /// - [DataField] - public SoundSpecifier PenaltySound = new SoundPathSpecifier("/Audio/Machines/Nuke/angry_beep.ogg"); - - /// - /// The sound that's played when the mail's opened. - /// - [DataField] - public SoundSpecifier OpenSound = new SoundPathSpecifier("/Audio/Effects/packetrip.ogg"); - - /// - /// The sound that's played when the mail's lock has been emagged. - /// - [DataField] - public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks"); - - /// - /// Whether this component is enabled. - /// Removed when it becomes trash. - /// - public bool IsEnabled = true; - - public CancellationTokenSource? priorityCancelToken; - } + [DataField] + public string Recipient = "None"; + + [DataField] + public string RecipientJob = "None"; + + /// + /// Why do we not use LockComponent? + /// Because this can't be locked again, + /// and we have special conditions for unlocking, + /// and we don't want to add a verb. + /// + [DataField] + public bool IsLocked = true; + + /// + /// Is this parcel profitable to deliver for the station? + /// + /// + /// The station won't receive any award on delivery if this is false. + /// This is useful for broken fragile packages and packages that were + /// not delivered in time. + /// + [DataField] + public bool IsProfitable = true; + + /// + /// Is this package considered fragile? + /// + /// + /// This can be set to true in the YAML files for a mail delivery to + /// always be Fragile, despite its contents. + /// + [DataField] + public bool IsFragile = false; + + /// + /// Is this package considered priority mail? + /// + /// + /// There will be a timer set for its successful delivery. The + /// station's bank account will be penalized if it is not delivered on + /// time.
+ ///
+ /// This is set to false on successful delivery.
+ ///
+ /// This can be set to true in the YAML files for a mail delivery to always be Priority. + ///
+ [DataField] + public bool IsPriority = false; + + /// + /// Whether this parcel is large. + /// + [DataField] + public bool IsLarge = false; + + /// + /// What will be packaged when the mail is spawned. + /// + [DataField] + public List Contents = new(); + + /// + /// The amount that cargo will be awarded for delivering this mail. + /// + [DataField] + public int Bounty = 750; + + /// + /// Penalty if the mail is destroyed. + /// + [DataField] + public int Penalty = -250; + + /// + /// The sound that's played when the mail's lock is broken. + /// + [DataField] + public SoundSpecifier PenaltySound = new SoundPathSpecifier("/Audio/Machines/Nuke/angry_beep.ogg"); + + /// + /// The sound that's played when the mail's opened. + /// + [DataField] + public SoundSpecifier OpenSound = new SoundPathSpecifier("/Audio/Effects/packetrip.ogg"); + + /// + /// The sound that's played when the mail's lock has been emagged. + /// + [DataField] + public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks"); + + /// + /// Whether this component is enabled. + /// Removed when it becomes trash. + /// + public bool IsEnabled = true; + + public CancellationTokenSource? PriorityCancelToken; } diff --git a/Content.Server/Mail/Components/MailReceiverComponent.cs b/Content.Server/Mail/Components/MailReceiverComponent.cs index 4224de5de45..281a27ea79e 100644 --- a/Content.Server/Mail/Components/MailReceiverComponent.cs +++ b/Content.Server/Mail/Components/MailReceiverComponent.cs @@ -1,6 +1,4 @@ -namespace Content.Server.Mail.Components -{ - [RegisterComponent] - public sealed partial class MailReceiverComponent : Component - {} -} +namespace Content.Server.Mail.Components; + +[RegisterComponent] +public sealed partial class MailReceiverComponent : Component {} diff --git a/Content.Server/Mail/Components/MailTeleporterComponent.cs b/Content.Server/Mail/Components/MailTeleporterComponent.cs index aa045f843db..81f58bc7a59 100644 --- a/Content.Server/Mail/Components/MailTeleporterComponent.cs +++ b/Content.Server/Mail/Components/MailTeleporterComponent.cs @@ -1,122 +1,118 @@ using Robust.Shared.Audio; -namespace Content.Server.Mail.Components +namespace Content.Server.Mail.Components; + +/// +/// This is for the mail teleporter. +/// Random mail will be teleported to this every few minutes. +/// +[RegisterComponent] +public sealed partial class MailTeleporterComponent : Component { + // Not starting accumulator at 0 so mail carriers have some deliveries to make shortly after roundstart. + [DataField] + public float Accumulator = 285f; + + [DataField] + public TimeSpan TeleportInterval = TimeSpan.FromMinutes(5); + + /// + /// The sound that's played when new mail arrives. + /// + [DataField] + public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg"); + + /// + /// The MailDeliveryPoolPrototype that's used to select what mail this + /// teleporter can deliver. + /// + [DataField] + public string MailPool = "RandomDeltaVMailDeliveryPool"; + + /// + /// How many mail candidates do we need per actual delivery sent when + /// the mail goes out? The number of candidates is divided by this number + /// to determine how many deliveries will be teleported in. + /// It does not determine unique recipients. That is random. + /// + [DataField] + public int CandidatesPerDelivery = 8; + + [DataField] + public int MinimumDeliveriesPerTeleport = 1; + + /// + /// Do not teleport any more mail in, if there are at least this many + /// undelivered parcels. + /// + /// + /// Currently this works by checking how many MailComponent entities + /// are sitting on the teleporter's tile.

+ /// + /// It should be noted that if the number of actual deliveries to be + /// made based on the number of candidates divided by candidates per + /// delivery exceeds this number, the teleporter will spawn more mail + /// than this number.

+ /// + /// This is just a simple check to see if anyone's been picking up the + /// mail lately to prevent entity bloat for the sake of performance. + ///
+ [DataField] + public int MaximumUndeliveredParcels = 5; + + /// + /// Any item that breaks or is destroyed in less than this amount of + /// damage is one of the types of items considered fragile. + /// + [DataField] + public int FragileDamageThreshold = 10; + + /// + /// What's the bonus for delivering a fragile package intact? + /// + [DataField] + public int FragileBonus = 100; + + /// + /// What's the malus for failing to deliver a fragile package? + /// + [DataField] + public int FragileMalus = -100; + + /// + /// What's the chance for any one delivery to be marked as priority mail? + /// + [DataField] + public float PriorityChance = 0.1f; + + /// + /// How long until a priority delivery is considered as having failed + /// if not delivered? + /// + [DataField] + public TimeSpan PriorityDuration = TimeSpan.FromMinutes(5); + + /// + /// What's the bonus for delivering a priority package on time? + /// + [DataField] + public int PriorityBonus = 250; + + /// + /// What's the malus for failing to deliver a priority package? + /// + [DataField] + public int PriorityMalus = -250; + + /// + /// What's the bonus for delivering a large package intact? + /// + [DataField] + public int LargeBonus = 1500; + /// - /// This is for the mail teleporter. - /// Random mail will be teleported to this every few minutes. + /// What's the malus for failing to deliver a large package? /// - [RegisterComponent] - public sealed partial class MailTeleporterComponent : Component - { - - // Not starting accumulator at 0 so mail carriers have some deliveries to make shortly after roundstart. - [DataField("accumulator")] - public float Accumulator = 285f; - - [DataField("teleportInterval")] - public TimeSpan TeleportInterval = TimeSpan.FromMinutes(5); - - /// - /// The sound that's played when new mail arrives. - /// - [DataField("teleportSound")] - public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg"); - - /// - /// The MailDeliveryPoolPrototype that's used to select what mail this - /// teleporter can deliver. - /// - [DataField] - public string MailPool = "RandomDeltaVMailDeliveryPool"; // Frontier / DeltaV: Mail rework - - /// - /// How many mail candidates do we need per actual delivery sent when - /// the mail goes out? The number of candidates is divided by this number - /// to determine how many deliveries will be teleported in. - /// It does not determine unique recipients. That is random. - /// - [DataField("candidatesPerDelivery")] - public int CandidatesPerDelivery = 8; - - [DataField("minimumDeliveriesPerTeleport")] - public int MinimumDeliveriesPerTeleport = 1; - - /// - /// Do not teleport any more mail in, if there are at least this many - /// undelivered parcels. - /// - /// - /// Currently this works by checking how many MailComponent entities - /// are sitting on the teleporter's tile. - /// - /// It should be noted that if the number of actual deliveries to be - /// made based on the number of candidates divided by candidates per - /// delivery exceeds this number, the teleporter will spawn more mail - /// than this number. - /// - /// This is just a simple check to see if anyone's been picking up the - /// mail lately to prevent entity bloat for the sake of performance. - /// - [DataField("maximumUndeliveredParcels")] - public int MaximumUndeliveredParcels = 5; - - /// - /// Any item that breaks or is destroyed in less than this amount of - /// damage is one of the types of items considered fragile. - /// - [DataField("fragileDamageThreshold")] - public int FragileDamageThreshold = 10; - - /// - /// What's the bonus for delivering a fragile package intact? - /// - [DataField("fragileBonus")] - public int FragileBonus = 100; - - /// - /// What's the malus for failing to deliver a fragile package? - /// - [DataField("fragileMalus")] - public int FragileMalus = -100; - - /// - /// What's the chance for any one delivery to be marked as priority mail? - /// - [DataField("priorityChance")] - public float PriorityChance = 0.1f; - - /// - /// How long until a priority delivery is considered as having failed - /// if not delivered? - /// - [DataField("priorityDuration")] - public TimeSpan priorityDuration = TimeSpan.FromMinutes(5); - - /// - /// What's the bonus for delivering a priority package on time? - /// - [DataField("priorityBonus")] - public int PriorityBonus = 250; - - /// - /// What's the malus for failing to deliver a priority package? - /// - [DataField] - public int PriorityMalus = -250; - - // Frontier: Large mail - /// - /// What's the bonus for delivering a large package intact? - /// - [DataField] - public int LargeBonus = 1500; //DeltaV; 5000 to 1500 - - /// - /// What's the malus for failing to deliver a large package? - /// - [DataField] - public int LargeMalus = -500; //DeltaV; -250 to -500 - // End Frontier: Large mail - } + [DataField] + public int LargeMalus = -500; } diff --git a/Content.Server/Mail/Components/StationMailRouterComponent.cs b/Content.Server/Mail/Components/StationMailRouterComponent.cs index b90036ecec2..6f6df1e10bb 100644 --- a/Content.Server/Mail/Components/StationMailRouterComponent.cs +++ b/Content.Server/Mail/Components/StationMailRouterComponent.cs @@ -1,7 +1,7 @@ namespace Content.Server.Mail.Components; /// -/// Designates a station as a place for sending and receiving mail. +/// Designates a station as a place for sending and receiving mail. /// [RegisterComponent] public sealed partial class StationMailRouterComponent : Component diff --git a/Content.Server/Mail/MailCommands.cs b/Content.Server/Mail/MailCommands.cs index e216650324c..124db2f325c 100644 --- a/Content.Server/Mail/MailCommands.cs +++ b/Content.Server/Mail/MailCommands.cs @@ -46,31 +46,23 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args) return; } - if (!Boolean.TryParse(args[2], out var isFragile)) + if (!bool.TryParse(args[2], out var isFragile) || !bool.TryParse(args[3], out var isPriority)) { shell.WriteError(Loc.GetString("shell-invalid-bool")); return; } - if (!Boolean.TryParse(args[3], out var isPriority)) - { - shell.WriteError(Loc.GetString("shell-invalid-bool")); - return; - } - - // Frontier: Large Mail - bool isLarge = false; - if (args.Length > 4 && !Boolean.TryParse(args[4], out isLarge)) + var isLarge = false; + if (args.Length > 4 && !bool.TryParse(args[4], out isLarge)) { shell.WriteError(Loc.GetString("shell-invalid-bool")); return; } var mailPrototype = isLarge ? _blankLargeMailPrototype : _blankMailPrototype; - // End Frontier - var _mailSystem = _entitySystemManager.GetEntitySystem(); - var _containerSystem = _entitySystemManager.GetEntitySystem(); + var mailSystem = _entitySystemManager.GetEntitySystem(); + var containerSystem = _entitySystemManager.GetEntitySystem(); if (!_entityManager.TryGetComponent(recipientUid, out MailReceiverComponent? mailReceiver)) { @@ -78,50 +70,50 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args) return; } - if (!_prototypeManager.HasIndex(mailPrototype)) // Frontier: _blankMailPrototype(mailPrototype)) { - shell.WriteLine(Loc.GetString("command-mailto-no-blankmail", ("blankMail", mailPrototype))); // Frontier: _blankMailPrototype(containerUid).Coordinates); // Frontier: _blankMailPrototype(mailUid, _mailContainer); + var mailUid = _entityManager.SpawnEntity(mailPrototype, _entityManager.GetComponent(containerUid).Coordinates);x + var mailContents = containerSystem.EnsureContainer(mailUid, _mailContainer); if (!_entityManager.TryGetComponent(mailUid, out MailComponent? mailComponent)) { - shell.WriteLine(Loc.GetString("command-mailto-bogus-mail", ("blankMail", mailPrototype), ("requiredMailComponent", nameof(MailComponent)))); // Frontier: _blankMailPrototype(teleporterComponent.Owner, "queued"); - _containerSystem.Insert(mailUid, teleporterQueue); + var teleporterQueue = containerSystem.EnsureContainer(teleporterComponent.Owner, "queued"); + containerSystem.Insert(mailUid, teleporterQueue); shell.WriteLine(Loc.GetString("command-mailto-success", ("timeToTeleport", teleporterComponent.TeleportInterval.TotalSeconds - teleporterComponent.Accumulator))); } } @@ -138,7 +130,7 @@ public sealed class MailNowCommand : IConsoleCommand public async void Execute(IConsoleShell shell, string argStr, string[] args) { - var _mailSystem = _entitySystemManager.GetEntitySystem(); + var entitySystem = _entitySystemManager.GetEntitySystem(); foreach (var mailTeleporter in _entityManager.EntityQuery()) { diff --git a/Content.Server/Mail/Systems/DelayedItemSystem.cs b/Content.Server/Mail/Systems/DelayedItemSystem.cs index cb7cb17bea2..59aaa3aff6f 100644 --- a/Content.Server/Mail/Systems/DelayedItemSystem.cs +++ b/Content.Server/Mail/Systems/DelayedItemSystem.cs @@ -5,8 +5,8 @@ namespace Content.Server.Mail.Systems; /// -/// A placeholder for another entity, spawned when taken out of a container, with the placeholder deleted shortly after. -/// Useful for storing instant effect entities, e.g. smoke, in the mail. +/// A placeholder for another entity, spawned when taken out of a container, with the placeholder deleted shortly after. +/// Useful for storing instant effect entities, e.g. smoke, in the mail. /// public sealed class DelayedItemSystem : EntitySystem { @@ -20,33 +20,21 @@ public override void Initialize() SubscribeLocalEvent(OnRemovedFromContainer); } - /// - /// EntGotRemovedFromContainerMessage handler - spawn the intended entity after removed from a container. - /// private void OnRemovedFromContainer(EntityUid uid, Components.DelayedItemComponent component, ContainerModifiedMessage args) { Spawn(component.Item, Transform(uid).Coordinates); } - /// - /// GotEquippedHandEvent handler - destroy the placeholder. - /// private void OnHandEquipped(EntityUid uid, Components.DelayedItemComponent component, EquippedHandEvent args) { EntityManager.DeleteEntity(uid); } - /// - /// OnDropAttempt handler - destroy the placeholder. - /// private void OnDropAttempt(EntityUid uid, Components.DelayedItemComponent component, DropAttemptEvent args) { EntityManager.DeleteEntity(uid); } - /// - /// OnDamageChanged handler - item has taken damage (e.g. inside the envelope), spawn the intended entity outside of any container and delete the placeholder. - /// private void OnDamageChanged(EntityUid uid, Components.DelayedItemComponent component, DamageChangedEvent args) { Spawn(component.Item, Transform(uid).Coordinates); diff --git a/Content.Server/Mail/Systems/MailSystem.cs b/Content.Server/Mail/Systems/MailSystem.cs index a98757ac9da..1db45e4fa3b 100644 --- a/Content.Server/Mail/Systems/MailSystem.cs +++ b/Content.Server/Mail/Systems/MailSystem.cs @@ -46,745 +46,712 @@ using Robust.Shared.Random; using Timer = Robust.Shared.Timing.Timer; -namespace Content.Server.Mail.Systems +namespace Content.Server.Mail.Systems; + +public sealed class MailSystem : EntitySystem { - public sealed class MailSystem : EntitySystem + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly AccessReaderSystem _accessSystem = default!; + [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly IdCardSystem _idCardSystem = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly TagSystem _tagSystem = default!; + [Dependency] private readonly CargoSystem _cargoSystem = default!; + [Dependency] private readonly StationSystem _stationSystem = default!; + [Dependency] private readonly ChatSystem _chatSystem = default!; + [Dependency] private readonly OpenableSystem _openable = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly MetaDataSystem _metaDataSystem = default!; + + // DeltaV - system that keeps track of mail and cargo stats + [Dependency] private readonly LogisticStatsSystem _logisticsStatsSystem = default!; + + private ISawmill _sawmill = default!; + + public override void Initialize() { - [Dependency] private readonly PopupSystem _popupSystem = default!; - [Dependency] private readonly AccessReaderSystem _accessSystem = default!; - [Dependency] private readonly SharedHandsSystem _handsSystem = default!; - [Dependency] private readonly IdCardSystem _idCardSystem = default!; - [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly TagSystem _tagSystem = default!; - [Dependency] private readonly CargoSystem _cargoSystem = default!; - [Dependency] private readonly StationSystem _stationSystem = default!; - [Dependency] private readonly ChatSystem _chatSystem = default!; - [Dependency] private readonly OpenableSystem _openable = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly SharedContainerSystem _containerSystem = default!; - [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; - [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly DamageableSystem _damageableSystem = default!; - [Dependency] private readonly ItemSystem _itemSystem = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; - [Dependency] private readonly MetaDataSystem _metaDataSystem = default!; - - // DeltaV - system that keeps track of mail and cargo stats - [Dependency] private readonly LogisticStatsSystem _logisticsStatsSystem = default!; - - private ISawmill _sawmill = default!; - - public override void Initialize() - { - base.Initialize(); + base.Initialize(); - _sawmill = Logger.GetSawmill("mail"); + _sawmill = Logger.GetSawmill("mail"); - SubscribeLocalEvent(OnSpawnPlayer, after: new[] { typeof(SpawnPointSystem) }); + SubscribeLocalEvent(OnSpawnPlayer, after: new[] { typeof(SpawnPointSystem) }); - SubscribeLocalEvent(OnRemove); - SubscribeLocalEvent(OnUseInHand); - SubscribeLocalEvent(OnAfterInteractUsing); - SubscribeLocalEvent(OnExamined); - SubscribeLocalEvent(OnDestruction); - SubscribeLocalEvent(OnDamage); - SubscribeLocalEvent(OnBreak); - SubscribeLocalEvent(OnMailEmagged); - } + SubscribeLocalEvent(OnRemove); + SubscribeLocalEvent(OnUseInHand); + SubscribeLocalEvent(OnAfterInteractUsing); + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnDestruction); + SubscribeLocalEvent(OnDamage); + SubscribeLocalEvent(OnBreak); + SubscribeLocalEvent(OnMailEmagged); + } - public override void Update(float frameTime) + public override void Update(float frameTime) + { + base.Update(frameTime); + foreach (var mailTeleporter in EntityQuery()) { - base.Update(frameTime); - foreach (var mailTeleporter in EntityQuery()) - { - if (TryComp(mailTeleporter.Owner, out var power) && !power.Powered) - return; + if (TryComp(mailTeleporter.Owner, out var power) && !power.Powered) + return; - mailTeleporter.Accumulator += frameTime; + mailTeleporter.Accumulator += frameTime; - if (mailTeleporter.Accumulator < mailTeleporter.TeleportInterval.TotalSeconds) - continue; + if (mailTeleporter.Accumulator < mailTeleporter.TeleportInterval.TotalSeconds) + continue; - mailTeleporter.Accumulator -= (float) mailTeleporter.TeleportInterval.TotalSeconds; + mailTeleporter.Accumulator -= (float) mailTeleporter.TeleportInterval.TotalSeconds; - SpawnMail(mailTeleporter.Owner, mailTeleporter); - } + SpawnMail(mailTeleporter.Owner, mailTeleporter); + } + } + + /// + /// Dynamically add the MailReceiver component to appropriate entities. + /// + private void OnSpawnPlayer(PlayerSpawningEvent args) + { + if (args.SpawnResult == null + || args.Job == null + || args.Station is not {} station + || !HasComp(station)) + return; + + AddComp(args.SpawnResult.Value); + } + + private void OnRemove(EntityUid uid, MailComponent component, ComponentRemove args) + { + // Make sure the priority timer doesn't run. + if (component.PriorityCancelToken != null) + component.PriorityCancelToken.Cancel(); + } + + /// + /// Try to open the mail. + /// + private void OnUseInHand(EntityUid uid, MailComponent component, UseInHandEvent args) + { + if (!component.IsEnabled) + return; + if (component.IsLocked) + { + _popupSystem.PopupEntity(Loc.GetString("mail-locked"), uid, args.User); + return; } + OpenMail(uid, component, args.User); + } - /// - /// Dynamically add the MailReceiver component to appropriate entities. - /// - private void OnSpawnPlayer(PlayerSpawningEvent args) + /// + /// Handle logic similar between a normal mail unlock and an emag + /// frying out the lock. + /// + private void UnlockMail(EntityUid uid, MailComponent component) + { + component.IsLocked = false; + UpdateAntiTamperVisuals(uid, false); + + if (component.IsPriority) { - if (args.SpawnResult == null || - args.Job == null || - args.Station is not {} station) - { - return; - } + // This is a successful delivery. Keep the failure timer from triggering. + if (component.PriorityCancelToken != null) + component.PriorityCancelToken.Cancel(); - if (!HasComp(station)) - return; + // The priority tape is visually considered to be a part of the + // anti-tamper lock, so remove that too. + _appearanceSystem.SetData(uid, MailVisuals.IsPriority, false); - AddComp(args.SpawnResult.Value); + // The examination code depends on this being false to not show + // the priority tape description anymore. + component.IsPriority = false; } + } + + /// + /// Check the ID against the mail's lock + /// + private void OnAfterInteractUsing(EntityUid uid, MailComponent component, AfterInteractUsingEvent args) + { + if (!args.CanReach || !component.IsLocked || !TryComp(uid, out var access)) + return; - private void OnRemove(EntityUid uid, MailComponent component, ComponentRemove args) + IdCardComponent? idCard = null; // We need an ID card. + if (HasComp(args.Used)) // Can we find it in a PDA if the user is using that? { - // Make sure the priority timer doesn't run. - if (component.priorityCancelToken != null) - component.priorityCancelToken.Cancel(); + _idCardSystem.TryGetIdCard(args.Used, out var pdaID); + idCard = pdaID; } - /// - /// Try to open the mail. - /// - private void OnUseInHand(EntityUid uid, MailComponent component, UseInHandEvent args) + if (HasComp(args.Used)) // Or are they using an id card directly? + idCard = Comp(args.Used); + + if (idCard == null) // Return if we still haven't found an id card. + return; + + if (!HasComp(uid)) { - if (!component.IsEnabled) + if (idCard.FullName != component.Recipient || idCard.JobTitle != component.RecipientJob) + { + _popupSystem.PopupEntity(Loc.GetString("mail-recipient-mismatch"), uid, args.User); return; - if (component.IsLocked) + } + + if (!_accessSystem.IsAllowed(uid, args.User)) { - _popupSystem.PopupEntity(Loc.GetString("mail-locked"), uid, args.User); + _popupSystem.PopupEntity(Loc.GetString("mail-invalid-access"), uid, args.User); return; } - OpenMail(uid, component, args.User); } - /// - /// Handle logic similar between a normal mail unlock and an emag - /// frying out the lock. - /// - private void UnlockMail(EntityUid uid, MailComponent component) + ExecuteForEachLogisticsStats(uid, (station, logisticStats) => { - component.IsLocked = false; - UpdateAntiTamperVisuals(uid, false); + _logisticsStatsSystem.AddOpenedMailEarnings(station, + logisticStats, + component.IsProfitable ? component.Bounty : 0); + }); + UnlockMail(uid, component); - if (component.IsPriority) - { - // This is a successful delivery. Keep the failure timer from triggering. - if (component.priorityCancelToken != null) - component.priorityCancelToken.Cancel(); + if (!component.IsProfitable) + { + _popupSystem.PopupEntity(Loc.GetString("mail-unlocked"), uid, args.User); + return; + } - // The priority tape is visually considered to be a part of the - // anti-tamper lock, so remove that too. - _appearanceSystem.SetData(uid, MailVisuals.IsPriority, false); + _popupSystem.PopupEntity(Loc.GetString("mail-unlocked-reward", ("bounty", component.Bounty)), uid, args.User); - // The examination code depends on this being false to not show - // the priority tape description anymore. - component.IsPriority = false; - } + component.IsProfitable = false; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var station, out var account)) + { + if (_stationSystem.GetOwningStation(uid) != station) + continue; + + _cargoSystem.UpdateBankAccount(station, account, component.Bounty); } + } - /// - /// Check the ID against the mail's lock - /// - private void OnAfterInteractUsing(EntityUid uid, MailComponent component, AfterInteractUsingEvent args) + private void OnExamined(EntityUid uid, MailComponent component, ExaminedEvent args) + { + MailEntityStrings mailEntityStrings = component.IsLarge ? MailConstants.MailLarge : MailConstants.Mail; //Frontier: mail types stored per type (large mail) + if (!args.IsInDetailsRange) { - if (!args.CanReach || !component.IsLocked) - return; + args.PushMarkup(Loc.GetString(mailEntityStrings.DescFar)); // Frontier: mail constants struct + return; + } - if (!TryComp(uid, out var access)) - return; + args.PushMarkup(Loc.GetString(mailEntityStrings.DescClose, ("name", component.Recipient), ("job", component.RecipientJob))); // Frontier: mail constants struct - IdCardComponent? idCard = null; // We need an ID card. + if (component.IsFragile) + args.PushMarkup(Loc.GetString("mail-desc-fragile")); - if (HasComp(args.Used)) /// Can we find it in a PDA if the user is using that? - { - _idCardSystem.TryGetIdCard(args.Used, out var pdaID); - idCard = pdaID; - } + if (component.IsPriority) + { + if (component.IsProfitable) + args.PushMarkup(Loc.GetString("mail-desc-priority")); + else + args.PushMarkup(Loc.GetString("mail-desc-priority-inactive")); + } + } - if (HasComp(args.Used)) /// Or are they using an id card directly? - idCard = Comp(args.Used); + /// + /// Penalize a station for a failed delivery. + /// + /// + /// This will mark a parcel as no longer being profitable, which will + /// prevent multiple failures on different conditions for the same + /// delivery.

+ /// + /// The standard penalization is breaking the anti-tamper lock, + /// but this allows a delivery to fail for other reasons too + /// while having a generic function to handle different messages. + ///
+ public void PenalizeStationFailedDelivery(EntityUid uid, MailComponent component, string localizationString) + { + if (!component.IsProfitable) + return; - if (idCard == null) /// Return if we still haven't found an id card. - return; + _chatSystem.TrySendInGameICMessage(uid, Loc.GetString(localizationString, ("credits", component.Penalty)), InGameICChatType.Speak, false); + _audioSystem.PlayPvs(component.PenaltySound, uid); - if (!HasComp(uid)) - { - if (idCard.FullName != component.Recipient || idCard.JobTitle != component.RecipientJob) - { - _popupSystem.PopupEntity(Loc.GetString("mail-recipient-mismatch"), uid, args.User); - return; - } + component.IsProfitable = false; - if (!_accessSystem.IsAllowed(uid, args.User)) - { - _popupSystem.PopupEntity(Loc.GetString("mail-invalid-access"), uid, args.User); - return; - } - } + if (component.IsPriority) + _appearanceSystem.SetData(uid, MailVisuals.IsPriorityInactive, true); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var station, out var account)) + { + if (_stationSystem.GetOwningStation(uid) != station) + continue; - // DeltaV - Add earnings to logistic stats + _cargoSystem.UpdateBankAccount(station, account, component.Penalty); + return; + } + } + + private void OnDestruction(EntityUid uid, MailComponent component, DestructionEventArgs args) + { + if (component.IsLocked) + { + // DeltaV - Tampered mail recorded to logistic stats ExecuteForEachLogisticsStats(uid, (station, logisticStats) => { - _logisticsStatsSystem.AddOpenedMailEarnings(station, + _logisticsStatsSystem.AddTamperedMailLosses(station, logisticStats, - component.IsProfitable ? component.Bounty : 0); + component.IsProfitable ? component.Penalty : 0); }); - UnlockMail(uid, component); - if (!component.IsProfitable) - { - _popupSystem.PopupEntity(Loc.GetString("mail-unlocked"), uid, args.User); - return; - } + PenalizeStationFailedDelivery(uid, component, "mail-penalty-lock"); + } - _popupSystem.PopupEntity(Loc.GetString("mail-unlocked-reward", ("bounty", component.Bounty)), uid, args.User); + if (component.IsEnabled) + OpenMail(uid, component); - component.IsProfitable = false; + UpdateAntiTamperVisuals(uid, false); + } - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var station, out var account)) - { - if (_stationSystem.GetOwningStation(uid) != station) - continue; + private void OnDamage(EntityUid uid, MailComponent component, DamageChangedEvent args) + { + if (args.DamageDelta == null || !_containerSystem.TryGetContainer(uid, "contents", out var contents)) + return; - _cargoSystem.UpdateBankAccount(station, account, component.Bounty); - } - } + // Transfer damage to the contents. + // This should be a general-purpose feature for all containers in the future. + foreach (var entity in contents.ContainedEntities.ToArray()) + _damageableSystem.TryChangeDamage(entity, args.DamageDelta); + } + + private void OnBreak(EntityUid uid, MailComponent component, BreakageEventArgs args) + { + _appearanceSystem.SetData(uid, MailVisuals.IsBroken, true); - private void OnExamined(EntityUid uid, MailComponent component, ExaminedEvent args) + if (component.IsFragile) { - MailEntityStrings mailEntityStrings = component.IsLarge ? MailConstants.MailLarge : MailConstants.Mail; //Frontier: mail types stored per type (large mail) - if (!args.IsInDetailsRange) + // DeltaV - Broken mail recorded to logistic stats + ExecuteForEachLogisticsStats(uid, (station, logisticStats) => { - args.PushMarkup(Loc.GetString(mailEntityStrings.DescFar)); // Frontier: mail constants struct - return; - } + _logisticsStatsSystem.AddDamagedMailLosses(station, + logisticStats, + component.IsProfitable ? component.Penalty : 0); + }); - args.PushMarkup(Loc.GetString(mailEntityStrings.DescClose, ("name", component.Recipient), ("job", component.RecipientJob))); // Frontier: mail constants struct + PenalizeStationFailedDelivery(uid, component, "mail-penalty-fragile"); + } + } - if (component.IsFragile) - args.PushMarkup(Loc.GetString("mail-desc-fragile")); + private void OnMailEmagged(EntityUid uid, MailComponent component, ref GotEmaggedEvent args) + { + if (!component.IsLocked) + return; - if (component.IsPriority) - { - if (component.IsProfitable) - args.PushMarkup(Loc.GetString("mail-desc-priority")); - else - args.PushMarkup(Loc.GetString("mail-desc-priority-inactive")); - } - } + UnlockMail(uid, component); - /// - /// Penalize a station for a failed delivery. - /// - /// - /// This will mark a parcel as no longer being profitable, which will - /// prevent multiple failures on different conditions for the same - /// delivery. - /// - /// The standard penalization is breaking the anti-tamper lock, - /// but this allows a delivery to fail for other reasons too - /// while having a generic function to handle different messages. - /// - public void PenalizeStationFailedDelivery(EntityUid uid, MailComponent component, string localizationString) - { - if (!component.IsProfitable) - return; + _popupSystem.PopupEntity(Loc.GetString("mail-unlocked-by-emag"), uid, args.UserUid); - _chatSystem.TrySendInGameICMessage(uid, Loc.GetString(localizationString, ("credits", component.Penalty)), InGameICChatType.Speak, false); - _audioSystem.PlayPvs(component.PenaltySound, uid); + _audioSystem.PlayPvs(component.EmagSound, uid, AudioParams.Default.WithVolume(4)); + component.IsProfitable = false; + args.Handled = true; + } - component.IsProfitable = false; + /// + /// Returns true if the given entity is considered fragile for delivery. + /// + public bool IsEntityFragile(EntityUid uid, int fragileDamageThreshold) + { + // It takes damage on falling. + if (HasComp(uid)) + return true; + + // It can be spilled easily and has something to spill. + if (HasComp(uid) + && TryComp(uid, out var openable) + && !_openable.IsClosed(uid, null, openable) + && _solutionContainerSystem.PercentFull(uid) > 0) + return true; + + // It might be made of non-reinforced glass. + if (TryComp(uid, out DamageableComponent? damageableComponent) + && damageableComponent.DamageModifierSetId == "Glass") + return true; + + if (!TryComp(uid, out DestructibleComponent? destructibleComp)) + return false; - if (component.IsPriority) - _appearanceSystem.SetData(uid, MailVisuals.IsPriorityInactive, true); + // Fallback: It breaks or is destroyed in less than a damage + // threshold dictated by the teleporter. + foreach (var threshold in destructibleComp.Thresholds) + { + if (threshold.Trigger is not DamageTrigger trigger || trigger.Damage >= fragileDamageThreshold) + continue; - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var station, out var account)) + foreach (var behavior in threshold.Behaviors) { - if (_stationSystem.GetOwningStation(uid) != station) + if (behavior is not DoActsBehavior doActs) continue; - _cargoSystem.UpdateBankAccount(station, account, component.Penalty); - return; + if (doActs.Acts.HasFlag(ThresholdActs.Breakage) || doActs.Acts.HasFlag(ThresholdActs.Destruction)) + return true; } } - private void OnDestruction(EntityUid uid, MailComponent component, DestructionEventArgs args) + return false; + } + + public bool TryMatchJobTitleToDepartment(string jobTitle, [NotNullWhen(true)] out string? jobDepartment) + { + foreach (var department in _prototypeManager.EnumeratePrototypes()) { - if (component.IsLocked) + foreach (var role in department.Roles) { - // DeltaV - Tampered mail recorded to logistic stats - ExecuteForEachLogisticsStats(uid, (station, logisticStats) => - { - _logisticsStatsSystem.AddTamperedMailLosses(station, - logisticStats, - component.IsProfitable ? component.Penalty : 0); - }); + if (!_prototypeManager.TryIndex(role, out JobPrototype? jobPrototype) || jobPrototype.LocalizedName != jobTitle) + continue; - PenalizeStationFailedDelivery(uid, component, "mail-penalty-lock"); + jobDepartment = department.ID; + return true; } - - if (component.IsEnabled) - OpenMail(uid, component); - - UpdateAntiTamperVisuals(uid, false); } - private void OnDamage(EntityUid uid, MailComponent component, DamageChangedEvent args) - { - if (args.DamageDelta == null) - return; - - if (!_containerSystem.TryGetContainer(uid, "contents", out var contents)) - return; - - // Transfer damage to the contents. - // This should be a general-purpose feature for all containers in the future. - foreach (var entity in contents.ContainedEntities.ToArray()) - { - _damageableSystem.TryChangeDamage(entity, args.DamageDelta); - } - } + jobDepartment = null; + return false; + } - private void OnBreak(EntityUid uid, MailComponent component, BreakageEventArgs args) + public bool TryMatchJobTitleToPrototype(string jobTitle, [NotNullWhen(true)] out JobPrototype? jobPrototype) + { + foreach (var job in _prototypeManager.EnumeratePrototypes()) { - _appearanceSystem.SetData(uid, MailVisuals.IsBroken, true); - - if (component.IsFragile) + if (job.LocalizedName == jobTitle) { - // DeltaV - Broken mail recorded to logistic stats - ExecuteForEachLogisticsStats(uid, (station, logisticStats) => - { - _logisticsStatsSystem.AddDamagedMailLosses(station, - logisticStats, - component.IsProfitable ? component.Penalty : 0); - }); - - PenalizeStationFailedDelivery(uid, component, "mail-penalty-fragile"); + jobPrototype = job; + return true; } } - private void OnMailEmagged(EntityUid uid, MailComponent component, ref GotEmaggedEvent args) - { - if (!component.IsLocked) - return; - - UnlockMail(uid, component); - - _popupSystem.PopupEntity(Loc.GetString("mail-unlocked-by-emag"), uid, args.UserUid); + jobPrototype = null; + return false; + } - _audioSystem.PlayPvs(component.EmagSound, uid, AudioParams.Default.WithVolume(4)); - component.IsProfitable = false; - args.Handled = true; - } + /// + /// Handle all the gritty details particular to a new mail entity. + /// + /// + /// This is separate mostly so the unit tests can get to it. + /// + public void SetupMail(EntityUid uid, MailTeleporterComponent component, MailRecipient recipient) + { + var mailComp = EnsureComp(uid); - /// - /// Returns true if the given entity is considered fragile for delivery. - /// - public bool IsEntityFragile(EntityUid uid, int fragileDamageThreshold) + var container = _containerSystem.EnsureContainer(uid, "contents"); + foreach (var item in EntitySpawnCollection.GetSpawns(mailComp.Contents, _random)) { - // It takes damage on falling. - if (HasComp(uid)) - return true; - - // It can be spilled easily and has something to spill. - if (HasComp(uid) - && TryComp(uid, out var openable) - && !_openable.IsClosed(uid, null, openable) - && _solutionContainerSystem.PercentFull(uid) > 0) - return true; - - // It might be made of non-reinforced glass. - if (TryComp(uid, out DamageableComponent? damageableComponent) - && damageableComponent.DamageModifierSetId == "Glass") - return true; - - // Fallback: It breaks or is destroyed in less than a damage - // threshold dictated by the teleporter. - if (TryComp(uid, out DestructibleComponent? destructibleComp)) + var entity = EntityManager.SpawnEntity(item, Transform(uid).Coordinates); + if (!_containerSystem.Insert(entity, container)) { - foreach (var threshold in destructibleComp.Thresholds) - { - if (threshold.Trigger is DamageTrigger trigger - && trigger.Damage < fragileDamageThreshold) - { - foreach (var behavior in threshold.Behaviors) - { - if (behavior is DoActsBehavior doActs) - { - if (doActs.Acts.HasFlag(ThresholdActs.Breakage) - || doActs.Acts.HasFlag(ThresholdActs.Destruction)) - { - return true; - } - } - } - } - } + _sawmill.Error($"Can't insert {ToPrettyString(entity)} into new mail delivery {ToPrettyString(uid)}! Deleting it."); + QueueDel(entity); } - - return false; - } - - public bool TryMatchJobTitleToDepartment(string jobTitle, [NotNullWhen(true)] out string? jobDepartment) - { - foreach (var department in _prototypeManager.EnumeratePrototypes()) + else if (!mailComp.IsFragile && IsEntityFragile(entity, component.FragileDamageThreshold)) { - foreach (var role in department.Roles) - { - if (_prototypeManager.TryIndex(role, out JobPrototype? _jobPrototype) - && _jobPrototype.LocalizedName == jobTitle) - { - jobDepartment = department.ID; - return true; - } - } + mailComp.IsFragile = true; } - - jobDepartment = null; - return false; } - public bool TryMatchJobTitleToPrototype(string jobTitle, [NotNullWhen(true)] out JobPrototype? jobPrototype) + mailComp.IsPriority = recipient.MayReceivePriorityMail && _random.Prob(component.PriorityChance); + mailComp.RecipientJob = recipient.Job; + mailComp.Recipient = recipient.Name; + + var mailEntityStrings = mailComp.IsLarge ? MailConstants.MailLarge : MailConstants.Mail; + if (mailComp.IsLarge) { - foreach (var job in _prototypeManager.EnumeratePrototypes()) - { - if (job.LocalizedName == jobTitle) - { - jobPrototype = job; - return true; - } - } + mailComp.Bounty += component.LargeBonus; + mailComp.Penalty += component.LargeMalus; + } - jobPrototype = null; - return false; + if (mailComp.IsFragile) + { + mailComp.Bounty += component.FragileBonus; + mailComp.Penalty += component.FragileMalus; + _appearanceSystem.SetData(uid, MailVisuals.IsFragile, true); } - /// - /// Handle all the gritty details particular to a new mail entity. - /// - /// - /// This is separate mostly so the unit tests can get to it. - /// - public void SetupMail(EntityUid uid, MailTeleporterComponent component, MailRecipient recipient) + if (mailComp.IsPriority) { - var mailComp = EnsureComp(uid); + mailComp.Bounty += component.PriorityBonus; + mailComp.Penalty += component.PriorityMalus; + _appearanceSystem.SetData(uid, MailVisuals.IsPriority, true); + mailComp.PriorityCancelToken = new CancellationTokenSource(); - var container = _containerSystem.EnsureContainer(uid, "contents"); - foreach (var item in EntitySpawnCollection.GetSpawns(mailComp.Contents, _random)) + Timer.Spawn((int) component.PriorityDuration.TotalMilliseconds, () => { - var entity = EntityManager.SpawnEntity(item, Transform(uid).Coordinates); - if (!_containerSystem.Insert(entity, container)) - { - _sawmill.Error($"Can't insert {ToPrettyString(entity)} into new mail delivery {ToPrettyString(uid)}! Deleting it."); - QueueDel(entity); - } - else if (!mailComp.IsFragile && IsEntityFragile(entity, component.FragileDamageThreshold)) + // DeltaV - Expired mail recorded to logistic stats + ExecuteForEachLogisticsStats(uid, (station, logisticStats) => { - mailComp.IsFragile = true; - } - } - - if (_random.Prob(component.PriorityChance)) - mailComp.IsPriority = true; + _logisticsStatsSystem.AddExpiredMailLosses(station, + logisticStats, + mailComp.IsProfitable ? mailComp.Penalty : 0); + }); - // This needs to override both the random probability and the - // entity prototype, so this is fine. - if (!recipient.MayReceivePriorityMail) - mailComp.IsPriority = false; + PenalizeStationFailedDelivery(uid, mailComp, "mail-penalty-expired"); + }, mailComp.PriorityCancelToken.Token); + } - mailComp.RecipientJob = recipient.Job; - mailComp.Recipient = recipient.Name; + _appearanceSystem.SetData(uid, MailVisuals.JobIcon, recipient.JobIcon); - // Frontier: Large mail bonus - MailEntityStrings mailEntityStrings = mailComp.IsLarge ? MailConstants.MailLarge : MailConstants.Mail; - if (mailComp.IsLarge) - { - mailComp.Bounty += component.LargeBonus; - mailComp.Penalty += component.LargeMalus; - } - // End Frontier + _metaDataSystem.SetEntityName(uid, Loc.GetString(mailEntityStrings.NameAddressed, // Frontier: move constant to MailEntityString + ("recipient", recipient.Name))); - if (mailComp.IsFragile) - { - mailComp.Bounty += component.FragileBonus; - mailComp.Penalty += component.FragileMalus; - _appearanceSystem.SetData(uid, MailVisuals.IsFragile, true); - } + var accessReader = EnsureComp(uid); + accessReader.AccessLists.Add(recipient.AccessTags); + } - if (mailComp.IsPriority) - { - mailComp.Bounty += component.PriorityBonus; - mailComp.Penalty += component.PriorityMalus; - _appearanceSystem.SetData(uid, MailVisuals.IsPriority, true); - - mailComp.priorityCancelToken = new CancellationTokenSource(); - - Timer.Spawn((int) component.priorityDuration.TotalMilliseconds, - () => - { - // DeltaV - Expired mail recorded to logistic stats - ExecuteForEachLogisticsStats(uid, (station, logisticStats) => - { - _logisticsStatsSystem.AddExpiredMailLosses(station, - logisticStats, - mailComp.IsProfitable ? mailComp.Penalty : 0); - }); - - PenalizeStationFailedDelivery(uid, mailComp, "mail-penalty-expired"); - }, - mailComp.priorityCancelToken.Token); - } + /// + /// Return the parcels waiting for delivery. + /// + /// The mail teleporter to check. + public List GetUndeliveredParcels(EntityUid uid) + { + // An alternative solution would be to keep a list of the unopened + // parcels spawned by the teleporter and see if they're not carried + // by someone, but this is simple, and simple is good. + List undeliveredParcels = new(); + foreach (var entityInTile in TurfHelpers.GetEntitiesInTile(Transform(uid).Coordinates, LookupFlags.Dynamic | LookupFlags.Sundries)) + { + if (HasComp(entityInTile)) + undeliveredParcels.Add(entityInTile); + } + return undeliveredParcels; + } - _appearanceSystem.SetData(uid, MailVisuals.JobIcon, recipient.JobIcon); + /// + /// Return how many parcels are waiting for delivery. + /// + /// The mail teleporter to check. + public uint GetUndeliveredParcelCount(EntityUid uid) + { + return (uint) GetUndeliveredParcels(uid).Count(); + } - _metaDataSystem.SetEntityName(uid, Loc.GetString(mailEntityStrings.NameAddressed, // Frontier: move constant to MailEntityString - ("recipient", recipient.Name))); + /// + /// Try to match a mail receiver to a mail teleporter. + /// + public bool TryGetMailTeleporterForReceiver(MailReceiverComponent receiver, [NotNullWhen(true)] out MailTeleporterComponent? teleporterComponent) + { + foreach (var mailTeleporter in EntityQuery()) + { + if (_stationSystem.GetOwningStation(receiver.Owner) != _stationSystem.GetOwningStation(mailTeleporter.Owner)) + continue; - var accessReader = EnsureComp(uid); - accessReader.AccessLists.Add(recipient.AccessTags); + teleporterComponent = mailTeleporter; + return true; } - /// - /// Return the parcels waiting for delivery. - /// - /// The mail teleporter to check. - public List GetUndeliveredParcels(EntityUid uid) - { - // An alternative solution would be to keep a list of the unopened - // parcels spawned by the teleporter and see if they're not carried - // by someone, but this is simple, and simple is good. - List undeliveredParcels = new(); - foreach (var entityInTile in TurfHelpers.GetEntitiesInTile(Transform(uid).Coordinates, LookupFlags.Dynamic | LookupFlags.Sundries)) - { - if (HasComp(entityInTile)) - undeliveredParcels.Add(entityInTile); - } - return undeliveredParcels; - } + teleporterComponent = null; + return false; + } - /// - /// Return how many parcels are waiting for delivery. - /// - /// The mail teleporter to check. - public uint GetUndeliveredParcelCount(EntityUid uid) + /// + /// Try to construct a recipient struct for a mail parcel based on a receiver. + /// + public bool TryGetMailRecipientForReceiver(MailReceiverComponent receiver, [NotNullWhen(true)] out MailRecipient? recipient) + { + // Because of the way this works, people are not considered + // candidates for mail if there is no valid PDA or ID in their slot + // or active hand. A better future solution might be checking the + // station records, possibly cross-referenced with the medical crew + // scanner to look for living recipients. TODO + + if (_idCardSystem.TryFindIdCard(receiver.Owner, out var idCard) + && TryComp(idCard.Owner, out var access) + && idCard.Comp.FullName != null + && idCard.Comp.JobTitle != null) { - return (uint) GetUndeliveredParcels(uid).Count(); - } + var accessTags = access.Tags; - /// - /// Try to match a mail receiver to a mail teleporter. - /// - public bool TryGetMailTeleporterForReceiver(MailReceiverComponent receiver, [NotNullWhen(true)] out MailTeleporterComponent? teleporterComponent) - { - foreach (var mailTeleporter in EntityQuery()) - { - if (_stationSystem.GetOwningStation(receiver.Owner) == _stationSystem.GetOwningStation(mailTeleporter.Owner)) - { - teleporterComponent = mailTeleporter; - return true; - } - } + var mayReceivePriorityMail = !(_mindSystem.GetMind(receiver.Owner) == null); - teleporterComponent = null; - return false; - } + recipient = new MailRecipient(idCard.Comp.FullName, + idCard.Comp.JobTitle, + idCard.Comp.JobIcon, + accessTags, + mayReceivePriorityMail); - /// - /// Try to construct a recipient struct for a mail parcel based on a receiver. - /// - public bool TryGetMailRecipientForReceiver(MailReceiverComponent receiver, [NotNullWhen(true)] out MailRecipient? recipient) - { - // Because of the way this works, people are not considered - // candidates for mail if there is no valid PDA or ID in their slot - // or active hand. A better future solution might be checking the - // station records, possibly cross-referenced with the medical crew - // scanner to look for living recipients. TODO - - if (_idCardSystem.TryFindIdCard(receiver.Owner, out var idCard) - && TryComp(idCard.Owner, out var access) - && idCard.Comp.FullName != null - && idCard.Comp.JobTitle != null) - { - var accessTags = access.Tags; + return true; + } - var mayReceivePriorityMail = !(_mindSystem.GetMind(receiver.Owner) == null); + recipient = null; + return false; + } - recipient = new MailRecipient(idCard.Comp.FullName, - idCard.Comp.JobTitle, - idCard.Comp.JobIcon, - accessTags, - mayReceivePriorityMail); + /// + /// Get the list of valid mail recipients for a mail teleporter. + /// + public List GetMailRecipientCandidates(EntityUid uid) + { + List candidateList = new(); - return true; - } + foreach (var receiver in EntityQuery()) + { + if (_stationSystem.GetOwningStation(receiver.Owner) != _stationSystem.GetOwningStation(uid)) + continue; - recipient = null; - return false; + if (TryGetMailRecipientForReceiver(receiver, out MailRecipient? recipient)) + candidateList.Add(recipient.Value); } - /// - /// Get the list of valid mail recipients for a mail teleporter. - /// - public List GetMailRecipientCandidates(EntityUid uid) + return candidateList; + } + + /// + /// Handle the spawning of all the mail for a mail teleporter. + /// + public void SpawnMail(EntityUid uid, MailTeleporterComponent? component = null) + { + if (!Resolve(uid, ref component)) { - List candidateList = new(); + _sawmill.Error($"Tried to SpawnMail on {ToPrettyString(uid)} without a valid MailTeleporterComponent!"); + return; + } - foreach (var receiver in EntityQuery()) - { - if (_stationSystem.GetOwningStation(receiver.Owner) != _stationSystem.GetOwningStation(uid)) - continue; + if (GetUndeliveredParcelCount(uid) >= component.MaximumUndeliveredParcels) + return; - if (TryGetMailRecipientForReceiver(receiver, out MailRecipient? recipient)) - candidateList.Add(recipient.Value); - } + var candidateList = GetMailRecipientCandidates(uid); - return candidateList; + if (candidateList.Count <= 0) + { + _sawmill.Error("List of mail candidates was empty!"); + return; } - /// - /// Handle the spawning of all the mail for a mail teleporter. - /// - public void SpawnMail(EntityUid uid, MailTeleporterComponent? component = null) + if (!_prototypeManager.TryIndex(component.MailPool, out var pool)) { - if (!Resolve(uid, ref component)) - { - _sawmill.Error($"Tried to SpawnMail on {ToPrettyString(uid)} without a valid MailTeleporterComponent!"); - return; - } - - if (GetUndeliveredParcelCount(uid) >= component.MaximumUndeliveredParcels) - return; + _sawmill.Error($"Can't index {ToPrettyString(uid)}'s MailPool {component.MailPool}!"); + return; + } - var candidateList = GetMailRecipientCandidates(uid); + for (int i = 0; + i < component.MinimumDeliveriesPerTeleport + candidateList.Count / component.CandidatesPerDelivery; + i++) + { + var candidate = _random.Pick(candidateList); + var possibleParcels = new Dictionary(pool.Everyone); - if (candidateList.Count <= 0) + if (TryMatchJobTitleToPrototype(candidate.Job, out JobPrototype? jobPrototype) + && pool.Jobs.TryGetValue(jobPrototype.ID, out Dictionary? jobParcels)) { - _sawmill.Error("List of mail candidates was empty!"); - return; + possibleParcels = possibleParcels.Union(jobParcels) + .GroupBy(g => g.Key) + .ToDictionary(pair => pair.Key, pair => pair.First().Value); } - if (!_prototypeManager.TryIndex(component.MailPool, out var pool)) + if (TryMatchJobTitleToDepartment(candidate.Job, out string? department) + && pool.Departments.TryGetValue(department, out Dictionary? departmentParcels)) { - _sawmill.Error($"Can't index {ToPrettyString(uid)}'s MailPool {component.MailPool}!"); - return; + possibleParcels = possibleParcels.Union(departmentParcels) + .GroupBy(g => g.Key) + .ToDictionary(pair => pair.Key, pair => pair.First().Value); } - for (int i = 0; - i < component.MinimumDeliveriesPerTeleport + candidateList.Count / component.CandidatesPerDelivery; - i++) + var accumulated = 0f; + var randomPoint = _random.NextFloat(possibleParcels.Values.Sum()); + string? chosenParcel = null; + foreach (var (key, weight) in possibleParcels) { - var candidate = _random.Pick(candidateList); - var possibleParcels = new Dictionary(pool.Everyone); - - if (TryMatchJobTitleToPrototype(candidate.Job, out JobPrototype? jobPrototype) - && pool.Jobs.TryGetValue(jobPrototype.ID, out Dictionary? jobParcels)) - { - possibleParcels = possibleParcels.Union(jobParcels) - .GroupBy(g => g.Key) - .ToDictionary(pair => pair.Key, pair => pair.First().Value); - } - - if (TryMatchJobTitleToDepartment(candidate.Job, out string? department) - && pool.Departments.TryGetValue(department, out Dictionary? departmentParcels)) - { - possibleParcels = possibleParcels.Union(departmentParcels) - .GroupBy(g => g.Key) - .ToDictionary(pair => pair.Key, pair => pair.First().Value); - } - - var accumulated = 0f; - var randomPoint = _random.NextFloat(possibleParcels.Values.Sum()); - string? chosenParcel = null; - foreach (var (key, weight) in possibleParcels) - { - accumulated += weight; - if (accumulated >= randomPoint) - { - chosenParcel = key; - break; - } - } - - if (chosenParcel == null) + accumulated += weight; + if (accumulated >= randomPoint) { - _sawmill.Error($"MailSystem wasn't able to find a deliverable parcel for {candidate.Name}, {candidate.Job}!"); - return; + chosenParcel = key; + break; } + } - var mail = EntityManager.SpawnEntity(chosenParcel, Transform(uid).Coordinates); - SetupMail(mail, component, candidate); - - _tagSystem.AddTag(mail, "Mail"); // Frontier + if (chosenParcel == null) + { + _sawmill.Error($"MailSystem wasn't able to find a deliverable parcel for {candidate.Name}, {candidate.Job}!"); + return; } - if (_containerSystem.TryGetContainer(uid, "queued", out var queued)) - _containerSystem.EmptyContainer(queued); + var mail = EntityManager.SpawnEntity(chosenParcel, Transform(uid).Coordinates); + SetupMail(mail, component, candidate); - _audioSystem.PlayPvs(component.TeleportSound, uid); + _tagSystem.AddTag(mail, "Mail"); // Frontier } - public void OpenMail(EntityUid uid, MailComponent? component = null, EntityUid? user = null) - { - if (!Resolve(uid, ref component)) - return; - - _audioSystem.PlayPvs(component.OpenSound, uid); + if (_containerSystem.TryGetContainer(uid, "queued", out var queued)) + _containerSystem.EmptyContainer(queued); - if (user != null) - _handsSystem.TryDrop((EntityUid) user); + _audioSystem.PlayPvs(component.TeleportSound, uid); + } - if (!_containerSystem.TryGetContainer(uid, "contents", out var contents)) - { - // I silenced this error because it fails non deterministically in tests and doesn't seem to effect anything else. - // _sawmill.Error($"Mail {ToPrettyString(uid)} was missing contents container!"); - return; - } + public void OpenMail(EntityUid uid, MailComponent? component = null, EntityUid? user = null) + { + if (!Resolve(uid, ref component)) + return; - foreach (var entity in contents.ContainedEntities.ToArray()) - { - _handsSystem.PickupOrDrop(user, entity); - } + _audioSystem.PlayPvs(component.OpenSound, uid); - _tagSystem.AddTag(uid, "Trash"); - _tagSystem.AddTag(uid, "Recyclable"); - component.IsEnabled = false; - UpdateMailTrashState(uid, true); - } + if (user != null) + _handsSystem.TryDrop((EntityUid) user); - private void UpdateAntiTamperVisuals(EntityUid uid, bool isLocked) + if (!_containerSystem.TryGetContainer(uid, "contents", out var contents)) { - _appearanceSystem.SetData(uid, MailVisuals.IsLocked, isLocked); + // I silenced this error because it fails non deterministically in tests and doesn't seem to effect anything else. + // _sawmill.Error($"Mail {ToPrettyString(uid)} was missing contents container!"); + return; } - private void UpdateMailTrashState(EntityUid uid, bool isTrash) + foreach (var entity in contents.ContainedEntities.ToArray()) { - _appearanceSystem.SetData(uid, MailVisuals.IsTrash, isTrash); + _handsSystem.PickupOrDrop(user, entity); } - // DeltaV - Helper function that executes for each StationLogisticsStatsComponent - // For updating MailMetrics stats - private void ExecuteForEachLogisticsStats(EntityUid uid, - Action action) - { + _tagSystem.AddTag(uid, "Trash"); + _tagSystem.AddTag(uid, "Recyclable"); + component.IsEnabled = false; + UpdateMailTrashState(uid, true); + } - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var station, out var logisticStats)) - { - if (_stationSystem.GetOwningStation(uid) != station) - continue; - action(station, logisticStats); - } - } + private void UpdateAntiTamperVisuals(EntityUid uid, bool isLocked) + { + _appearanceSystem.SetData(uid, MailVisuals.IsLocked, isLocked); + } + + private void UpdateMailTrashState(EntityUid uid, bool isTrash) + { + _appearanceSystem.SetData(uid, MailVisuals.IsTrash, isTrash); } - public struct MailRecipient( - string name, - string job, - string jobIcon, - HashSet> accessTags, - bool mayReceivePriorityMail) + // DeltaV - Helper function that executes for each StationLogisticsStatsComponent + // For updating MailMetrics stats + private void ExecuteForEachLogisticsStats(EntityUid uid, + Action action) { - public string Name = name; - public string Job = job; - public string JobIcon = jobIcon; - public HashSet> AccessTags = accessTags; - public bool MayReceivePriorityMail = mayReceivePriorityMail; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var station, out var logisticStats)) + { + if (_stationSystem.GetOwningStation(uid) != station) + continue; + action(station, logisticStats); + } } } + +public struct MailRecipient( + string name, + string job, + string jobIcon, + HashSet> accessTags, + bool mayReceivePriorityMail) +{ + public string Name = name; + public string Job = job; + public string JobIcon = jobIcon; + public HashSet> AccessTags = accessTags; + public bool MayReceivePriorityMail = mayReceivePriorityMail; +} From 6cacf275e06812d34a24183e265d8814dce0abbd Mon Sep 17 00:00:00 2001 From: fox Date: Sun, 13 Oct 2024 22:16:46 +0300 Subject: [PATCH 12/14] More cleanup --- Content.Server/Mail/MailCommands.cs | 2 +- .../VendingMachines/Inventories/courierdrobe.yml | 14 +++++++------- .../DeltaV/Entities/Objects/Specific/Mail/mail.yml | 1 - .../Objects/Specific/Mail/mail_civilian.yml | 1 - 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Content.Server/Mail/MailCommands.cs b/Content.Server/Mail/MailCommands.cs index 124db2f325c..74c8a421780 100644 --- a/Content.Server/Mail/MailCommands.cs +++ b/Content.Server/Mail/MailCommands.cs @@ -108,7 +108,7 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args) mailComponent.IsFragile = isFragile; mailComponent.IsPriority = isPriority; - mailComponent.IsLarge = isLarge; //Frontier Mail + mailComponent.IsLarge = isLarge; mailSystem.SetupMail(mailUid, teleporterComponent, recipient.Value); diff --git a/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml b/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml index fbbec89a269..778b3725858 100644 --- a/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml +++ b/Resources/Prototypes/DeltaV/Catalog/VendingMachines/Inventories/courierdrobe.yml @@ -7,10 +7,10 @@ CourierBag: 2 ClothingHeadsetCargo: 2 ClothingOuterWinterCargo: 2 - ClothingUniformMailCarrier: 2 # Nyanotrasen - Mail Carrier old gear - ClothingUniformSkirtMailCarrier: 2 # Nyanotrasen - Mail Carrier old gear - ClothingHeadMailCarrier: 2 # Nyanotrasen - Mail Carrier old gear - MailBag: 2 # Nyanotrasen - Mail Carrier old gear - ClothingOuterWinterCoatMail: 2 # Nyanotrasen - Mail Carrier old gear - WeaponMailLake: 2 # Frontier Mail Port - BoxMailCapsulePrimed: 4 # Frontier Mail Port + ClothingUniformMailCarrier: 2 + ClothingUniformSkirtMailCarrier: 2 + ClothingHeadMailCarrier: 2 + MailBag: 2 + ClothingOuterWinterCoatMail: 2 + WeaponMailLake: 2 + BoxMailCapsulePrimed: 4 diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml index 25b7ec40803..6f96930078b 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml @@ -1,5 +1,4 @@ # DeltaV Mail - - type: entity noSpawn: true parent: BaseMail diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_civilian.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_civilian.yml index aea3131daeb..19a1ee3c536 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_civilian.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail_civilian.yml @@ -1,5 +1,4 @@ # Frontier Mail - - type: entity noSpawn: true parent: BaseMailLarge From 95cd02548dc7c72b9565a5cde0db30a608d73a32 Mon Sep 17 00:00:00 2001 From: fox Date: Sun, 13 Oct 2024 22:17:59 +0300 Subject: [PATCH 13/14] Typo apparently --- Content.Server/Mail/MailCommands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Mail/MailCommands.cs b/Content.Server/Mail/MailCommands.cs index 74c8a421780..390de93fb3a 100644 --- a/Content.Server/Mail/MailCommands.cs +++ b/Content.Server/Mail/MailCommands.cs @@ -94,7 +94,7 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args) return; } - var mailUid = _entityManager.SpawnEntity(mailPrototype, _entityManager.GetComponent(containerUid).Coordinates);x + var mailUid = _entityManager.SpawnEntity(mailPrototype, _entityManager.GetComponent(containerUid).Coordinates); var mailContents = containerSystem.EnsureContainer(mailUid, _mailContainer); if (!_entityManager.TryGetComponent(mailUid, out MailComponent? mailComponent)) From 017b5a6b9d1dac3d6557f9745e162503c312f2aa Mon Sep 17 00:00:00 2001 From: fox Date: Sun, 13 Oct 2024 22:25:58 +0300 Subject: [PATCH 14/14] Do not return from the mail teleporter update loop --- Content.Server/Mail/Systems/MailSystem.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Content.Server/Mail/Systems/MailSystem.cs b/Content.Server/Mail/Systems/MailSystem.cs index 1db45e4fa3b..e80febd2308 100644 --- a/Content.Server/Mail/Systems/MailSystem.cs +++ b/Content.Server/Mail/Systems/MailSystem.cs @@ -98,10 +98,9 @@ public override void Update(float frameTime) foreach (var mailTeleporter in EntityQuery()) { if (TryComp(mailTeleporter.Owner, out var power) && !power.Powered) - return; + continue; mailTeleporter.Accumulator += frameTime; - if (mailTeleporter.Accumulator < mailTeleporter.TeleportInterval.TotalSeconds) continue;