This commit is contained in:
Coryn 2026-08-14 01:46:09 +00:00 committed by GitHub
commit bb18ec1ef4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 84 additions and 4 deletions

View File

@ -87,13 +87,85 @@ public sealed partial class HumanoidCharacterAppearance : IEquatable<HumanoidCha
{
var random = IoCManager.Resolve<IRobustRandom>();
var markingManager = IoCManager.Resolve<MarkingManager>();
// Delta V - Begin
var protoMan = IoCManager.Resolve<IPrototypeManager>();
var speciesPrototype = protoMan.Index<SpeciesPrototype>(species);
// TODO: Add random markings
Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> compiledMarkings =
new();
//build a color pallet for all parts.
var colours = Enumerable.Range(0, 255)
.Select(e => new Color(random.NextByte(), random.NextByte(), random.NextByte()))
.ToArray();
//most likely list of simple physical traits.
HumanoidVisualLayers[] layerFilter =
[
HumanoidVisualLayers.Hair,
HumanoidVisualLayers.Tail,
HumanoidVisualLayers.FacialHair,
HumanoidVisualLayers.Fire,
HumanoidVisualLayers.Snout,
];
//build organ for organ
foreach (var organ in markingManager.GetOrgans(species))
{
//get the marking data for that organ
if (!markingManager.TryGetMarkingData(organ.Value, out var organMarkingData))
continue;
//extract the group based on the organ
var group = protoMan.Index<MarkingsGroupPrototype>(organMarkingData.Value.Group.Id);
// setup an empty dictionary of layers
compiledMarkings[organ.Key] = new();
//layer for layer.
foreach (var layer in organMarkingData.Value.Layers)
{
//only randomize physical traits.
if(!layerFilter.Contains(layer))
continue;
//get all markings for that layer, sex, group and flatten to markings.
var markings =
markingManager.MarkingsByLayerAndGroupAndSex(layer, organMarkingData.Value.Group, sex)
.Select(e => e.Value.AsMarking())
.ToArray();
//skip if no matches
if(markings.Length==0)
continue;
//check restrictions for the layer
int limitOfMarking;
if (!group.Limits.TryGetValue(layer, out var limits))
{
limitOfMarking = markings.Length;
}
else
{
limitOfMarking = limits.Limit;
//blatant skip chance unless required.
if (!limits.Required && limitOfMarking==1 && random.NextDouble() < 0.5)
continue;
}
//pick random feature list within limit
compiledMarkings[organ.Key][layer] = Enumerable.Range(0,limitOfMarking==1?1:random.Next(limitOfMarking))
.Select(e =>
{
// return random.Pick(markings);
var baseMarking = random.Pick(markings);
for (var i = 0; i < baseMarking.MarkingColors.Count&&i<colours.Length; i++)
{
baseMarking= baseMarking.WithColorAt(i, colours[i]);
}
return baseMarking;
// return baseMarking.WithColor(color);
})
.ToList();
}
}
// Delta V - End
var newEyeColor = random.Pick(_realisticEyeColors);
var protoMan = IoCManager.Resolve<IPrototypeManager>();
var skinType = protoMan.Index<SpeciesPrototype>(species).SkinColoration;
var skinType = speciesPrototype.SkinColoration; // Delta V
var strategy = protoMan.Index(skinType).Strategy;
var newSkinColor = strategy.InputType switch
@ -103,7 +175,15 @@ public sealed partial class HumanoidCharacterAppearance : IEquatable<HumanoidCha
_ => strategy.ClosestSkinColor(new Color(random.NextFloat(1), random.NextFloat(1), random.NextFloat(1), 1)),
};
return new HumanoidCharacterAppearance(newEyeColor, newSkinColor, new());
// Delta V - Begin
// Safety step. Most systems which called Random() also called this, and not doing so caused issues with markings.
// In the future it could *maybe* be removed, but it's probably worth the extra CPU cycles to validate this info.
return EnsureValid(
new HumanoidCharacterAppearance(newEyeColor, newSkinColor, compiledMarkings),
species,
sex);
// Delta V - End
}
public static Color ClampColor(Color color)