From fdbadbe579b128020b4686cf12c4111996f5ce70 Mon Sep 17 00:00:00 2001
From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Date: Tue, 19 Sep 2023 01:05:17 -0400
Subject: [PATCH] closet skeleton event (#19802)
---
.../RandomEntityStorageSpawnRuleComponent.cs | 18 ++++++++
.../Events/RandomEntityStorageSpawnRule.cs | 44 +++++++++++++++++++
Content.Shared/Humanoid/SkinColor.cs | 10 +++--
.../ghost/roles/ghost-role-component.ftl | 3 ++
.../Entities/Mobs/Player/skeleton.yml | 13 ++++++
Resources/Prototypes/GameRules/events.yml | 11 +++++
.../Roles/Jobs/Fun/misc_startinggear.yml | 9 ++++
7 files changed, 105 insertions(+), 3 deletions(-)
create mode 100644 Content.Server/StationEvents/Components/RandomEntityStorageSpawnRuleComponent.cs
create mode 100644 Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs
diff --git a/Content.Server/StationEvents/Components/RandomEntityStorageSpawnRuleComponent.cs b/Content.Server/StationEvents/Components/RandomEntityStorageSpawnRuleComponent.cs
new file mode 100644
index 0000000000..141ff1b558
--- /dev/null
+++ b/Content.Server/StationEvents/Components/RandomEntityStorageSpawnRuleComponent.cs
@@ -0,0 +1,18 @@
+using Content.Server.StationEvents.Events;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Server.StationEvents.Components;
+
+///
+/// Spawns a single entity in a random EntityStorage on the station
+///
+[RegisterComponent, Access(typeof(RandomEntityStorageSpawnRule))]
+public sealed partial class RandomEntityStorageSpawnRuleComponent : Component
+{
+ ///
+ /// The entity to be spawned.
+ ///
+ [DataField("prototype", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string Prototype = string.Empty;
+}
diff --git a/Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs b/Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs
new file mode 100644
index 0000000000..a9e8c437ec
--- /dev/null
+++ b/Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs
@@ -0,0 +1,44 @@
+using Content.Server.GameTicking.Rules.Components;
+using Content.Server.StationEvents.Components;
+using Content.Server.Storage.Components;
+using Content.Server.Storage.EntitySystems;
+using Robust.Shared.Random;
+
+namespace Content.Server.StationEvents.Events;
+
+public sealed class RandomEntityStorageSpawnRule : StationEventSystem
+{
+ [Dependency] private readonly EntityStorageSystem _entityStorage = default!;
+
+ protected override void Started(EntityUid uid, RandomEntityStorageSpawnRuleComponent comp, GameRuleComponent gameRule, GameRuleStartedEvent args)
+ {
+ base.Started(uid, comp, gameRule, args);
+
+ if (!TryGetRandomStation(out var station))
+ return;
+
+ var validLockers = new List<(EntityUid, EntityStorageComponent, TransformComponent)>();
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var ent, out var storage, out var xform))
+ {
+ if (StationSystem.GetOwningStation(ent, xform) != station)
+ continue;
+
+ if (!_entityStorage.CanInsert(ent, storage) || storage.Open)
+ continue;
+
+ validLockers.Add((ent, storage, xform));
+ }
+
+ if (validLockers.Count == 0)
+ return;
+
+ var (locker, storageComp, xformComp) = RobustRandom.Pick(validLockers);
+ var spawn = Spawn(comp.Prototype, xformComp.Coordinates);
+ if (!_entityStorage.Insert(spawn, locker, storageComp))
+ {
+ Del(spawn);
+ }
+ }
+}
diff --git a/Content.Shared/Humanoid/SkinColor.cs b/Content.Shared/Humanoid/SkinColor.cs
index b38b426a19..89c78b7ea0 100644
--- a/Content.Shared/Humanoid/SkinColor.cs
+++ b/Content.Shared/Humanoid/SkinColor.cs
@@ -2,6 +2,9 @@ namespace Content.Shared.Humanoid;
public static class SkinColor
{
+ public const float MaxTintedHuesSaturation = 0.1f;
+ public const float MinTintedHuesLightness = 0.85f;
+
public static Color ValidHumanSkinTone => Color.FromHsv(new Vector4(0.07f, 0.2f, 1f, 1f));
///
@@ -117,8 +120,9 @@ public static class SkinColor
/// Tinted hue color
public static Color TintedHues(Color color)
{
- var newColor = Color.ToHsv(color);
- newColor.Y *= 0.1f;
+ var newColor = Color.ToHsl(color);
+ newColor.Y *= MaxTintedHuesSaturation;
+ newColor.Z = MathHelper.Lerp(MinTintedHuesLightness, 1f, newColor.Z);
return Color.FromHsv(newColor);
}
@@ -131,7 +135,7 @@ public static class SkinColor
public static bool VerifyTintedHues(Color color)
{
// tinted hues just ensures saturation is always .1, or 10% saturation at all times
- return Color.ToHsv(color).Y != .1f;
+ return Color.ToHsl(color).Y <= MaxTintedHuesSaturation && Color.ToHsl(color).Z >= MinTintedHuesLightness;
}
public static bool VerifySkinColor(HumanoidSkinColor type, Color color)
diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl
index 81604e8d6b..9ab3e77cb6 100644
--- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl
+++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl
@@ -122,6 +122,9 @@ ghost-role-information-skeleton-pirate-description = Cause chaos and loot the st
ghost-role-information-skeleton-biker-name = Skeleton Biker
ghost-role-information-skeleton-biker-description = Ride around on your sweet ride.
+ghost-role-information-closet-skeleton-name = Closet Skeleton
+ghost-role-information-closet-skeleton-description = Wreak havoc! You are a primordial force with no allegiance. Live happily with the crew or wage sweet skeletal war.
+
ghost-role-information-onestar-mecha-name = Onestar Mecha
ghost-role-information-onestar-mecha-description = You are an experimental mecha created by who-knows-what, all you know is that you have weapons and you detect fleshy moving targets nearby...
ghost-role-information-onestar-mecha-rules = Use your weapons to cause havoc. You are an antagonist.
diff --git a/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml b/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml
index d49ea2fd3f..96abe01b6c 100644
--- a/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml
+++ b/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml
@@ -48,3 +48,16 @@
- type: Loadout
prototypes: [SkeletonBiker]
- type: RandomHumanoidAppearance
+
+- type: entity
+ parent: MobSkeletonPerson
+ id: MobSkeletonCloset
+ name: Closet Skeleton
+ components:
+ - type: GhostRole
+ name: ghost-role-information-closet-skeleton-name
+ description: ghost-role-information-closet-skeleton-description
+ - type: GhostTakeoverAvailable
+ - type: Loadout
+ prototypes: [LimitedPassengerGear]
+ - type: RandomHumanoidAppearance
diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml
index 550163bb7d..a8f5d50684 100644
--- a/Resources/Prototypes/GameRules/events.yml
+++ b/Resources/Prototypes/GameRules/events.yml
@@ -55,6 +55,17 @@
duration: 1
- type: BureaucraticErrorRule
+- type: entity
+ parent: BaseGameRule
+ id: ClosetSkeleton
+ noSpawn: true
+ components:
+ - type: StationEvent
+ weight: 10
+ duration: 1
+ - type: RandomEntityStorageSpawnRule
+ prototype: MobSkeletonCloset
+
- type: entity
parent: BaseGameRule
id: Dragon
diff --git a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml
index 367ffb9dea..066ed49adc 100644
--- a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml
+++ b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml
@@ -284,6 +284,15 @@
jumpsuit: ClothingUniformJumpsuitJacketMonkey
id: BartenderIDCard
+# Passenger but without the ID, bag, or headset
+
+- type: startingGear
+ id: LimitedPassengerGear
+ equipment:
+ jumpsuit: ClothingUniformJumpsuitColorGrey
+ shoes: ClothingShoesColorBlack
+ innerclothingskirt: ClothingUniformJumpskirtColorGrey
+
# DeathMatch Gear
- type: startingGear
--
2.51.2