closet skeleton event (#19802)

This commit is contained in:
Nemanja
2023-09-19 01:05:17 -04:00
committed by GitHub
parent 283a90bf9f
commit fdbadbe579
7 changed files with 105 additions and 3 deletions

View File

@@ -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;
/// <summary>
/// Spawns a single entity in a random EntityStorage on the station
/// </summary>
[RegisterComponent, Access(typeof(RandomEntityStorageSpawnRule))]
public sealed partial class RandomEntityStorageSpawnRuleComponent : Component
{
/// <summary>
/// The entity to be spawned.
/// </summary>
[DataField("prototype", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string Prototype = string.Empty;
}

View File

@@ -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<RandomEntityStorageSpawnRuleComponent>
{
[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<EntityStorageComponent, TransformComponent>();
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);
}
}
}

View File

@@ -2,6 +2,9 @@ namespace Content.Shared.Humanoid;
public static class SkinColor 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)); public static Color ValidHumanSkinTone => Color.FromHsv(new Vector4(0.07f, 0.2f, 1f, 1f));
/// <summary> /// <summary>
@@ -117,8 +120,9 @@ public static class SkinColor
/// <returns>Tinted hue color</returns> /// <returns>Tinted hue color</returns>
public static Color TintedHues(Color color) public static Color TintedHues(Color color)
{ {
var newColor = Color.ToHsv(color); var newColor = Color.ToHsl(color);
newColor.Y *= 0.1f; newColor.Y *= MaxTintedHuesSaturation;
newColor.Z = MathHelper.Lerp(MinTintedHuesLightness, 1f, newColor.Z);
return Color.FromHsv(newColor); return Color.FromHsv(newColor);
} }
@@ -131,7 +135,7 @@ public static class SkinColor
public static bool VerifyTintedHues(Color color) public static bool VerifyTintedHues(Color color)
{ {
// tinted hues just ensures saturation is always .1, or 10% saturation at all times // 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) public static bool VerifySkinColor(HumanoidSkinColor type, Color color)

View File

@@ -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-name = Skeleton Biker
ghost-role-information-skeleton-biker-description = Ride around on your sweet ride. 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-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-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. ghost-role-information-onestar-mecha-rules = Use your weapons to cause havoc. You are an antagonist.

View File

@@ -48,3 +48,16 @@
- type: Loadout - type: Loadout
prototypes: [SkeletonBiker] prototypes: [SkeletonBiker]
- type: RandomHumanoidAppearance - 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

View File

@@ -55,6 +55,17 @@
duration: 1 duration: 1
- type: BureaucraticErrorRule - type: BureaucraticErrorRule
- type: entity
parent: BaseGameRule
id: ClosetSkeleton
noSpawn: true
components:
- type: StationEvent
weight: 10
duration: 1
- type: RandomEntityStorageSpawnRule
prototype: MobSkeletonCloset
- type: entity - type: entity
parent: BaseGameRule parent: BaseGameRule
id: Dragon id: Dragon

View File

@@ -284,6 +284,15 @@
jumpsuit: ClothingUniformJumpsuitJacketMonkey jumpsuit: ClothingUniformJumpsuitJacketMonkey
id: BartenderIDCard id: BartenderIDCard
# Passenger but without the ID, bag, or headset
- type: startingGear
id: LimitedPassengerGear
equipment:
jumpsuit: ClothingUniformJumpsuitColorGrey
shoes: ClothingShoesColorBlack
innerclothingskirt: ClothingUniformJumpskirtColorGrey
# DeathMatch Gear # DeathMatch Gear
- type: startingGear - type: startingGear