AI/Guests/Guest.Identity.cs
using System;
using System.Text.Json.Nodes;
namespace HC3;
public struct Identity
{
public Color ShirtColor { get; set; }
public Color HeadColor { get; set; }
public Color ForearmsColor { get; set; }
public Color PantsColor { get; set; }
public Color ShoesColor { get; set; }
public Color HairColor { get; set; }
public float Scale { get; set; }
public bool LoadedFromSave { get; set; }
private static Color GetRandomShirt( Random random )
{
var colors = new Color[]
{
new( 0.8f, 0.2f, 0.2f ), // Brick Red
new( 0.2f, 0.4f, 0.8f ), // Royal Blue
new( 0.3f, 0.7f, 0.4f ), // Forest Green
new( 0.7f, 0.3f, 0.7f ), // Purple
new( 0.2f, 0.7f, 0.8f ), // Teal
new( 0.9f, 0.6f, 0.2f ), // Orange
new( 0.8f, 0.8f, 0.2f ), // Yellow
new( 0.5f, 0.3f, 0.1f ), // Brown
new( 0.9f, 0.5f, 0.5f ), // Salmon
new( 0.5f, 0.5f, 0.5f ), // Gray
new( 0.2f, 0.2f, 0.3f ), // Navy Blue
new( 0.6f, 0.3f, 0.4f ), // Maroon
new( 0.9f, 0.9f, 0.9f ), // Off-White
new( 0.1f, 0.1f, 0.1f ), // Charcoal
new( 0.7f, 0.2f, 0.3f ), // Crimson
new( 0.4f, 0.7f, 0.1f ), // Lime Green
new( 0.6f, 0.8f, 0.9f ), // Sky Blue
new( 0.9f, 0.7f, 0.8f ), // Pink
new( 0.4f, 0.3f, 0.6f ), // Lavender
new( 0.5f, 0.8f, 0.6f ) // Mint Green
};
return random.FromArray( colors );
}
private static Color GetRandomHair( Random random )
{
var colors = new Color[]
{
new( 0.05f, 0.05f, 0.05f ), // Black
new( 0.2f, 0.15f, 0.1f ), // Dark Brown
new( 0.4f, 0.3f, 0.2f ), // Medium Brown
new( 0.6f, 0.5f, 0.35f ), // Light Brown
new( 0.8f, 0.7f, 0.45f ), // Dirty Blonde
new( 0.9f, 0.8f, 0.5f ), // Blonde
new( 0.8f, 0.3f, 0.2f ), // Ginger/Red
new( 0.5f, 0.5f, 0.5f ), // Silver/Gray
new( 0.7f, 0.7f, 0.7f ), // White/Platinum
new( 0.3f, 0.2f, 0.15f ), // Auburn
new( 0.15f, 0.1f, 0.05f ), // Very Dark Brown
new( 0.7f, 0.6f, 0.4f ) // Sandy Blonde
};
return random.FromArray( colors );
}
private static Color GetRandomPants( Random random )
{
var colors = new Color[]
{
new( .1f, 0.1f, 0.15f ), // Navy Blue
new( 0.2f, 0.2f, 0.2f ), // Charcoal
new( 0.05f, 0.05f, 0.05f ), // Black
new( 0.3f, 0.3f, 0.3f ), // Dark Gray
new( 0.2f, 0.15f, 0.1f ), // Dark Brown
new( 0.35f, 0.2f, 0.15f ), // Medium Brown
new( 0.7f, 0.7f, 0.75f ), // Light Gray
new( 0.15f, 0.25f, 0.35f ), // Dark Denim Blue
new( 0.25f, 0.35f, 0.45f ), // Medium Denim Blue
new( 0.35f, 0.45f, 0.55f ), // Light Denim Blue
new( 0.5f, 0.35f, 0.2f ), // Khaki
new( 0.6f, 0.5f, 0.4f ), // Tan
new(0.3f, 0.25f, 0.2f ), // Olive Green
new( 0.4f, 0.2f, 0.15f ) // Burgundy
};
return random.FromArray( colors );
}
private static Color GetRandomSkin( Random random )
{
var colors = new Color[]
{
new( 0.97f, 0.85f, 0.73f ), // Very Light
new( 0.94f, 0.78f, 0.67f ), // Light
new( 0.87f, 0.72f, 0.60f ), // Light Medium
new( 0.80f, 0.65f, 0.52f ), // Medium
new( 0.75f, 0.60f, 0.48f ), // Medium Tan
new( 0.65f, 0.48f, 0.35f ), // Tan
new( 0.55f, 0.38f, 0.27f ), // Medium Dark
new( 0.45f, 0.30f, 0.22f ), // Dark
new( 0.35f, 0.22f, 0.16f ), // Deep Dark
new( 0.25f, 0.15f, 0.10f ), // Very Deep Dark
new( 0.90f, 0.75f, 0.65f ), // Peach
new( 0.85f, 0.68f, 0.55f ), // Warm Medium
new( 0.70f, 0.55f, 0.42f ), // Olive
new( 0.60f, 0.43f, 0.32f ), // Golden Brown
new( 0.50f, 0.33f, 0.24f ) // Rich Brown
};
return random.FromArray( colors );
}
public static Identity Generate( Random random )
{
var skinColor = GetRandomSkin( random );
return new Identity
{
ShirtColor = GetRandomShirt( random ),
HeadColor = skinColor,
ForearmsColor = skinColor,
PantsColor = GetRandomPants( random ),
ShoesColor = Color.Parse( "#8E8B8E" ).Value,
HairColor = GetRandomHair( random ),
LoadedFromSave = false,
Scale = random.Float( 0f, 1f ) > 0.75f
? random.Float( 0.5f, 0.7f )
: random.Float( 0.8f, 1.0f )
};
}
public void ApplyTo( SceneModel model )
{
model.Batchable = false;
model.Attributes.Set( "ShirtColor", ShirtColor );
model.Attributes.Set( "HeadColor", HeadColor );
model.Attributes.Set( "ForearmsColor", ForearmsColor );
model.Attributes.Set( "PantsColor", PantsColor );
model.Attributes.Set( "ShoesColor", ShoesColor );
model.Attributes.Set( "HairColor", HairColor );
}
public JsonObject ToJson()
{
return new JsonObject
{
["ShirtColor"] = ShirtColor.Hex,
["HeadColor"] = HeadColor.Hex,
["ForearmsColor"] = ForearmsColor.Hex,
["PantsColor"] = PantsColor.Hex,
["ShoesColor"] = ShoesColor.Hex,
["HairColor"] = HairColor.Hex,
["Scale"] = Scale
};
}
public static Identity FromJson( JsonNode json )
{
return new Identity
{
ShirtColor = Color.Parse( json["ShirtColor"]?.ToString() ?? "#FFFFFF" ).Value,
HeadColor = Color.Parse( json["HeadColor"]?.ToString() ?? "#FFFFFF" ).Value,
ForearmsColor = Color.Parse( json["ForearmsColor"]?.ToString() ?? "#FFFFFF" ).Value,
PantsColor = Color.Parse( json["PantsColor"]?.ToString() ?? "#FFFFFF" ).Value,
ShoesColor = Color.Parse( json["ShoesColor"]?.ToString() ?? "#FFFFFF" ).Value,
HairColor = Color.Parse( json["HairColor"]?.ToString() ?? "#FFFFFF" ).Value,
Scale = json["Scale"]?.GetValue<float>() ?? 1.0f,
LoadedFromSave = true
};
}
}
public partial class Guest
{
[Sync( SyncFlags.FromHost )]
protected Identity Identity { get; set; }
/// <summary>
/// Is this guest a male?
/// </summary>
[Property, Feature( "Identity" ), Group( "Identity" ), Sync( SyncFlags.FromHost )]
public bool IsMale { get; set; }
[Property] Texture _faceTexture { get; set; }
void SetupIdentity()
{
if ( !Game.IsPlaying )
return;
// Already loaded from save
if ( Identity.LoadedFromSave ) return;
IsMale = Game.Random.Int( 0, 1 ) > 0;
FullName = IdentitySystem.FetchName( IsMale, Delinquency );
var seed = GameObject.Id.ToString().FastHash();
var random = new Random( seed );
Identity = Identity.Generate( random );
}
void SetupSkin()
{
// Can't batch these now
Body.SceneModel.Batchable = false;
Body.SceneModel.Attributes.Set( "Slot0", Identity.ShirtColor );
Body.SceneModel.Attributes.Set( "Slot1", Identity.ForearmsColor );
Body.SceneModel.Attributes.Set( "Slot2", Identity.HeadColor );
Body.SceneModel.Attributes.Set( "Slot3", Identity.PantsColor );
Body.SceneModel.Attributes.Set( "Slot4", Identity.ShoesColor );
Body.SceneModel.Attributes.Set( "Slot5", Identity.HairColor );
Body.SceneModel.Attributes.Set( "FaceTexture", _faceTexture );
WorldScale = Identity.Scale;
}
}