From 6c1fb3042a3f3bb91765a23246d99ee55a114403 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sun, 27 Oct 2024 17:43:32 -0700 Subject: [PATCH 1/3] port Punpun --- Content.Server/Punpun/PunpunComponent.cs | 4 + Content.Server/Punpun/PunpunSystem.cs | 109 ++++++++++++++++++ .../Prototypes/Entities/Mobs/NPCs/pets.yml | 8 +- .../Entities/Objects/Misc/paper.yml | 10 ++ SpaceStation14.sln.DotSettings | 1 + 5 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 Content.Server/Punpun/PunpunComponent.cs create mode 100644 Content.Server/Punpun/PunpunSystem.cs diff --git a/Content.Server/Punpun/PunpunComponent.cs b/Content.Server/Punpun/PunpunComponent.cs new file mode 100644 index 00000000000..5879b0c4058 --- /dev/null +++ b/Content.Server/Punpun/PunpunComponent.cs @@ -0,0 +1,4 @@ +namespace Content.Server.Punpun; + +[RegisterComponent] +public sealed partial class PunpunComponent : Component; diff --git a/Content.Server/Punpun/PunpunSystem.cs b/Content.Server/Punpun/PunpunSystem.cs new file mode 100644 index 00000000000..f743f08be46 --- /dev/null +++ b/Content.Server/Punpun/PunpunSystem.cs @@ -0,0 +1,109 @@ +using System.Linq; +using Content.Server.GameTicking; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Inventory; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Robust.Server.GameObjects; + +namespace Content.Server.Punpun; + +public sealed class PunpunSystem : EntitySystem +{ + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly ServerMetaDataSystem _meta = default!; + + private (int, string, string) _punpunData = (0, string.Empty, string.Empty); + + // All the roman numerals we'll need to display + private readonly Dictionary _numerals = new() + { + { 0, "I" }, + { 1, "II" }, + { 2, "III" }, + { 3, "IV" }, + { 4, "V" }, + { 5, "VI" }, + { 6, "VII" }, + { 7, "VIII" }, + { 8, "IX" }, + { 9, "X" }, + { 10, "XI" }, + { 11, "XII" }, + { 12, "XIII" }, + { 13, "XIV" } + }; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRoundStart); + SubscribeLocalEvent(OnRoundEnd); + } + + // Checks if the Punpun data has any items to equip, and names the Punpun upon initialization + private void OnRoundStart(EntityUid uid, PunpunComponent component, ComponentStartup args) + { + if (_punpunData.Item1 > 13) + { + EntityManager.SpawnEntity("PaperWrittenPunpunNote", Transform(uid).Coordinates); + EntityManager.QueueDeleteEntity(uid); + _punpunData = (0, string.Empty, string.Empty); + + return; + } + + var meta = MetaData(uid); + _meta.SetEntityName(uid, $"{meta.EntityName} {_numerals[_punpunData.Item1]}", meta); + + if (!EntityManager.TryGetComponent(uid, out _)) + return; + EquipItem(uid, "head", _punpunData.Item2); + EquipItem(uid, "mask", _punpunData.Item3); + } + + // Checks if Punpun exists, and is alive at round end + // If so, stores the items and increments the Punpun count + private void OnRoundEnd(RoundEndTextAppendEvent ev) + { + // I couldn't find a method to get a single entity, so this just enumerated over the first and disposes it + var punpunComponents = EntityManager.EntityQueryEnumerator(); + punpunComponents.MoveNext(out var punpun, out _); + + if (!EntityManager.TryGetComponent(punpun, out var mobState) + || mobState.CurrentState == MobState.Dead) + _punpunData = (0, string.Empty, string.Empty); + + _punpunData.Item1++; + + if (EntityManager.HasComponent(punpun)) + { + _punpunData.Item2 = CheckSlot(punpun, "head"); + _punpunData.Item3 = CheckSlot(punpun, "mask"); + } + + punpunComponents.Dispose(); + } + + // Equips an item to a slot, and names it. + private void EquipItem(EntityUid uid, string slot, string item) + { + if (item == string.Empty) + return; + + var itemEnt = EntityManager.SpawnEntity(item, EntityManager.GetComponent(uid).Coordinates); + if (_inventory.TryEquip(uid, itemEnt, slot, true, true)) + _meta.SetEntityName(itemEnt, $"{MetaData(uid).EntityName}'s {MetaData(itemEnt).EntityName}"); + else + EntityManager.DeleteEntity(itemEnt); + } + + // Checks if an item exists in a slot, and returns its name + private string CheckSlot(EntityUid uid, string slot) + { + return _inventory.TryGetSlotEntity(uid, slot, out var item) + ? EntityManager.GetComponent(item.Value).EntityPrototype!.ID + : string.Empty; + } +} diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 420e7ed50da..f19e76ecf54 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -825,13 +825,6 @@ id: MobMonkeyPunpun description: A prominent representative of monkeys with unlimited access to alcohol. components: - - type: GhostRole - prob: 1 - makeSentient: true - allowSpeech: true - allowMovement: true - name: ghost-role-information-punpun-name - description: ghost-role-information-punpun-description - type: GhostTakeoverAvailable - type: Butcherable butcheringType: Spike @@ -859,6 +852,7 @@ - TauCetiBasic - Monkey - Kobold + - type: Punpun - type: entity name: Tropico diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index d3db29b4209..c72f7a2e91e 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -159,6 +159,16 @@ backgroundPatchMargin: 16.0, 16.0, 16.0, 16.0 contentMargin: 32.0, 16.0, 32.0, 0.0 +- type: entity + name: note + description: A piece of white paper. + id: PaperWrittenPunpunNote + parent: PaperCaptainsThoughts + suffix: Punpun Note + components: + - type: Paper + content: I, Punpun, invoke my right to have all of my clones on the NT family vacation to the meat packaging plant one out of every 15 shifts. + - type: entity name: cargo invoice parent: Paper diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index 15424a68ec7..156e5d27014 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -655,6 +655,7 @@ public sealed partial class $CLASS$ : Shared$CLASS$ { True True True + True True True True From 2c026052e81e29992383b2e6ed5ae44365c2c66a Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sun, 27 Oct 2024 18:29:30 -0700 Subject: [PATCH 2/3] Punpun, the lord of Roman Numerals --- Content.Server/Punpun/PunpunComponent.cs | 7 +++- Content.Server/Punpun/PunpunSystem.cs | 49 +++++++++++++----------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Content.Server/Punpun/PunpunComponent.cs b/Content.Server/Punpun/PunpunComponent.cs index 5879b0c4058..19d2da42c9d 100644 --- a/Content.Server/Punpun/PunpunComponent.cs +++ b/Content.Server/Punpun/PunpunComponent.cs @@ -1,4 +1,9 @@ namespace Content.Server.Punpun; [RegisterComponent] -public sealed partial class PunpunComponent : Component; +public sealed partial class PunpunComponent : Component +{ + /// How many rounds Punpun will be around for before disappearing with a note + [DataField] + public int Lifetime = 14; +} diff --git a/Content.Server/Punpun/PunpunSystem.cs b/Content.Server/Punpun/PunpunSystem.cs index f743f08be46..ede893ca51f 100644 --- a/Content.Server/Punpun/PunpunSystem.cs +++ b/Content.Server/Punpun/PunpunSystem.cs @@ -13,26 +13,8 @@ public sealed class PunpunSystem : EntitySystem [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly ServerMetaDataSystem _meta = default!; - private (int, string, string) _punpunData = (0, string.Empty, string.Empty); + private (int, string, string) _punpunData = (1, string.Empty, string.Empty); - // All the roman numerals we'll need to display - private readonly Dictionary _numerals = new() - { - { 0, "I" }, - { 1, "II" }, - { 2, "III" }, - { 3, "IV" }, - { 4, "V" }, - { 5, "VI" }, - { 6, "VII" }, - { 7, "VIII" }, - { 8, "IX" }, - { 9, "X" }, - { 10, "XI" }, - { 11, "XII" }, - { 12, "XIII" }, - { 13, "XIV" } - }; public override void Initialize() { @@ -42,20 +24,21 @@ public override void Initialize() SubscribeLocalEvent(OnRoundEnd); } + // Checks if the Punpun data has any items to equip, and names the Punpun upon initialization private void OnRoundStart(EntityUid uid, PunpunComponent component, ComponentStartup args) { - if (_punpunData.Item1 > 13) + if (_punpunData.Item1 > component.Lifetime) { EntityManager.SpawnEntity("PaperWrittenPunpunNote", Transform(uid).Coordinates); EntityManager.QueueDeleteEntity(uid); - _punpunData = (0, string.Empty, string.Empty); + _punpunData = (1, string.Empty, string.Empty); return; } var meta = MetaData(uid); - _meta.SetEntityName(uid, $"{meta.EntityName} {_numerals[_punpunData.Item1]}", meta); + _meta.SetEntityName(uid, $"{meta.EntityName} {ToRomanNumeral(_punpunData.Item1)}", meta); if (!EntityManager.TryGetComponent(uid, out _)) return; @@ -67,7 +50,7 @@ private void OnRoundStart(EntityUid uid, PunpunComponent component, ComponentSta // If so, stores the items and increments the Punpun count private void OnRoundEnd(RoundEndTextAppendEvent ev) { - // I couldn't find a method to get a single entity, so this just enumerated over the first and disposes it + // I couldn't find a method to get a single entity, so this just enumerates over the first and disposes it var punpunComponents = EntityManager.EntityQueryEnumerator(); punpunComponents.MoveNext(out var punpun, out _); @@ -106,4 +89,24 @@ private string CheckSlot(EntityUid uid, string slot) ? EntityManager.GetComponent(item.Value).EntityPrototype!.ID : string.Empty; } + + + // Punpun, the lord of Roman Numerals + public static List RomanNumerals = new() { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; + public static List Numerals = new() { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; + + public static string ToRomanNumeral(int number) + { + var romanNumeral = string.Empty; + while (number > 0) + { + // Find the biggest numeral that is less than equal to number + var index = Numerals.FindIndex(x => x <= number); + // Subtract its value from your number + number -= Numerals[index]; + // Add it onto the end of your roman numeral + romanNumeral += RomanNumerals[index]; + } + return romanNumeral; + } } From baea2450d59d301f601f5831521c3982d0a897ad Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sun, 27 Oct 2024 18:33:59 -0700 Subject: [PATCH 3/3] jumpsuit --- Content.Server/Punpun/PunpunSystem.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Content.Server/Punpun/PunpunSystem.cs b/Content.Server/Punpun/PunpunSystem.cs index ede893ca51f..5f1f22b42a1 100644 --- a/Content.Server/Punpun/PunpunSystem.cs +++ b/Content.Server/Punpun/PunpunSystem.cs @@ -13,7 +13,7 @@ public sealed class PunpunSystem : EntitySystem [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly ServerMetaDataSystem _meta = default!; - private (int, string, string) _punpunData = (1, string.Empty, string.Empty); + private (int, string, string, string) _punpunData = (1, string.Empty, string.Empty, string.Empty); public override void Initialize() @@ -32,7 +32,7 @@ private void OnRoundStart(EntityUid uid, PunpunComponent component, ComponentSta { EntityManager.SpawnEntity("PaperWrittenPunpunNote", Transform(uid).Coordinates); EntityManager.QueueDeleteEntity(uid); - _punpunData = (1, string.Empty, string.Empty); + _punpunData = (1, string.Empty, string.Empty, string.Empty); return; } @@ -44,6 +44,7 @@ private void OnRoundStart(EntityUid uid, PunpunComponent component, ComponentSta return; EquipItem(uid, "head", _punpunData.Item2); EquipItem(uid, "mask", _punpunData.Item3); + EquipItem(uid, "jumpsuit", _punpunData.Item4); } // Checks if Punpun exists, and is alive at round end @@ -56,7 +57,7 @@ private void OnRoundEnd(RoundEndTextAppendEvent ev) if (!EntityManager.TryGetComponent(punpun, out var mobState) || mobState.CurrentState == MobState.Dead) - _punpunData = (0, string.Empty, string.Empty); + _punpunData = (1, string.Empty, string.Empty, string.Empty); _punpunData.Item1++; @@ -64,6 +65,7 @@ private void OnRoundEnd(RoundEndTextAppendEvent ev) { _punpunData.Item2 = CheckSlot(punpun, "head"); _punpunData.Item3 = CheckSlot(punpun, "mask"); + _punpunData.Item4 = CheckSlot(punpun, "jumpsuit"); } punpunComponents.Dispose();