CharacterKit/AppearanceCatalog.ExpandedPresets.cs

Part of the character appearance catalog, defines expanded built-in appearance presets and helpers. It yields a sequence of AppearancePreset entries for humans, children and fantasy races, sets face/hair/skin/ear/horn/tail properties, and assigns clothing and eye colors via DressPreset.

File Access
namespace CharacterEditor;
public static partial class AppearanceCatalog
{
	static IEnumerable<AppearancePreset> ExpandedPresets()
	{
		foreach (var item in new[]
		{
			("sculptor", "Sculptor", "female08", "human04", "bob", "black"),
			("envoy", "Envoy", "female09", "human02", "ponytail", "black"),
			("performer", "Performer", "female10", "human04", "long_bob", "brown")
		}

		)
		{
			var data = Preset(item.Item4, item.Item5, "none", item.Item6);
			BuiltInFaces.Select(data, item.Item3);
			data.BaseShape.MaleBody = 0;
			yield return new(item.Item1, item.Item2, data);
		}

		yield return new("boy", "Boy", ChildPreset(false));
		yield return new("girl", "Girl", ChildPreset(true));

		var goblin = FantasyPreset("goblin", new Color(.42f, .66f, .32f), true);
		goblin.SkinPath = Skins.Single(x => x.Id == "human03").ResourcePath;
		goblin.SkinStyle = "original";
		goblin.Height = .15f;
		goblin.MaturityLinked = false;
		goblin.BodyMaturity = .3f;
		goblin.FaceMaturity = 1;
		goblin.EarSize = .43f;
		EarShapes.SetPosition(goblin, EarShapes.Goblin);
		goblin.HairPath = Hair.Single(x => x.Id == "slicked_balding").ResourcePath;
		yield return new("goblin", "Goblin", goblin);
		var bovine = FantasyPreset("bovine", new Color(.65f, .48f, .33f), true);
		bovine.SkinStyle = "original";
		bovine.Height = .88f;
		bovine.Fitness = .78f;
		bovine.ChestSize = .65f;
		EarShapes.SetPosition(bovine, EarShapes.Animal);
		bovine.EarSize = .52f;
		bovine.HairPath = Hair.Single(x => x.Id == "short_dreads").ResourcePath;
		bovine.Horns.Left = new()
		{
			Family = "recurved",
			Thickness = .68f,
			Length = .5f,
			Splay = .7f,
			Color = new Color(.68f, .58f, .4f)
		};
		bovine.Tail = new()
		{
			Enabled = true,
			Tip = "tuft",
			Length = .62f,
			Thickness = .38f,
			CustomTipColor = true,
			TipColor = new Color(.12f, .07f, .04f)
		};
		yield return new("bovine", "Bovine", bovine);
		var demon = FantasyPreset("female10", new Color(.82f, .19f, .16f), false);
		demon.EyeGlow = .6f;
		demon.RightEyeGlow = .6f;
		demon.HairPath = Hair.Single(x => x.Id == "long_bob").ResourcePath;
		demon.Horns.Left = new()
		{
			Family = "swept",
			Length = .45f,
			Thickness = .4f,
			Color = new Color(.15f, .08f, .07f),
			TipColor = new Color(.035f, .02f, .02f)
		};
		demon.Tail = new()
		{
			Enabled = true,
			Tip = "single",
			Length = .6f,
			Thickness = .12f
		};
		yield return new("demon", "Demon", demon);
		var orc = FantasyPreset("orc", new Color(.49f, .61f, .68f), true);
		orc.SkinPath = Skins.Single(x => x.Id == "human03").ResourcePath;
		orc.Height = .78f;
		orc.Fitness = .9f;
		orc.ChestSize = .7f;
		EarShapes.SetPosition(orc, Vector2.Lerp(EarShapes.Goblin, EarShapes.Animal, .32f));
		orc.EarSize = .27f;
		orc.Teeth.LowerStyle = "vampire";
		yield return new("orc", "Orc", orc);
	}

	static CharacterAppearanceData FantasyPreset(string face, Color color, bool male)
	{
		var data = Preset("human04", "none", "none", "black");
		BuiltInFaces.Select(data, face);
		data.BaseShape.MaleBody = male ? 1 : 0;
		data.NormalizeSkinTone = true;
		data.SkinColor = color;
		return data;
	}

	static AppearancePreset DressPreset(AppearancePreset preset)
	{
		string[] names = preset.Id switch
		{
			"traveller" => new[]
			{
				"Flannel Shirt",
				"Jeans",
				"Black Boots"
			},
			"scout" => new[]
			{
				"Polo Shirt",
				"Shorts",
				"Trainers"
			},
			"scholar" => new[]
			{
				"Waistcoat and Shirt",
				"Smart Trousers",
				"Flat Shoes"
			},
			"veteran" => new[]
			{
				"Tshirt",
				"Brown Leather Jacket",
				"Jeans",
				"Black Boots"
			},
			"wanderer" => new[]
			{
				"Hoodie",
				"Loose Jeans",
				"Sneakers"
			},
			"artisan" => new[]
			{
				"Blue Jumpsuit",
				"Black Boots"
			},
			"explorer" => new[]
			{
				"Polo Shirt White",
				"Rain Coat",
				"Brown Cargo Pants",
				"Black Boots"
			},
			"sculptor" => new[]
			{
				"Loose Shirt",
				"Black Jeans",
				"Flat Shoes"
			},
			"envoy" => new[]
			{
				"Simple Dress Blue",
				"Boot Heels Black"
			},
			"performer" => new[]
			{
				"Simple Dress Black",
				"Boot Heels Red"
			},
			"goblin" => new[]
			{
				"Loose Shirt",
				"Brown Cargo Pants",
				"Black Boots"
			},
			"bovine" => new[]
			{
				"Blue Shirt",
				"Brown Cargo Pants",
				"Black Boots"
			},
			"demon" => new[]
			{
				"Simple Dress Black",
				"Boot Heels Black"
			},
			"orc" => new[]
			{
				"Tank Top",
				"Black Jeans",
				"Black Boots"
			},
			_ => null
		};
		if (names is not null)
		{
			preset.Appearance.ClothingPaths = names.Select(n => WardrobeCatalog.Items.Single(x => x.Name.Trim() == n).Path).ToArray();
			preset.Appearance.Version = 2;
		}

		// Muted iris colors complement each preset; the Demon keeps its glowing eyes.
		Color? eyeColor = preset.Id switch
		{
			"traveller" => new Color(.34f, .27f, .14f), // Hazel
			"scout" => new Color(.20f, .095f, .045f), // Deep warm brown
			"scholar" => new Color(.30f, .36f, .25f), // Sage green
			"veteran" => new Color(.32f, .39f, .44f), // Slate blue
			"wanderer" => new Color(.14f, .075f, .045f), // Espresso brown
			"artisan" => new Color(.31f, .29f, .16f), // Olive hazel
			"explorer" => new Color(.29f, .15f, .065f), // Chestnut brown
			"sculptor" => new Color(.35f, .43f, .45f), // Grey blue
			"envoy" => new Color(.34f, .20f, .085f), // Amber brown
			"performer" => new Color(.30f, .38f, .24f), // Green hazel
			"boy" => new Color(.30f, .22f, .12f), // Soft brown
			"girl" => new Color(.34f, .42f, .48f), // Muted blue
			"goblin" => new Color(.43f, .31f, .10f), // Ochre
			"bovine" => new Color(.22f, .12f, .055f), // Dark brown
			"orc" => new Color(.39f, .41f, .35f), // Grey green
			_ => null
		};
		if (eyeColor is Color color)
		{
			preset.Appearance.CustomEyeColor = true;
			preset.Appearance.CustomRightEyeColor = true;
			preset.Appearance.EyeColor = color;
			preset.Appearance.RightEyeColor = color;
		}

		return preset;
	}
}