Dress people at generation from a separate apparel stream.
Wardrobes live on the person in people.json: everyday layers, textbooks per parallel, and chance-based bags from catalog data. Hauling and the carry cap are defs, not constants. The golden roster gains an items column; later family members shift because Hauling consumes extra appearance rolls. Old saves without items are dressed on load. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -609,6 +609,11 @@ public sealed class CatalogLoader
|
||||
throw new ContentLoadException($"ThingDef '{thing.DefName}' has unknown skirtLength '{thing.SkirtLength}'.");
|
||||
}
|
||||
|
||||
if (thing.CarryChance is < 0f or > 1f)
|
||||
{
|
||||
throw new ContentLoadException($"ThingDef '{thing.DefName}' carryChance must be 0–1.");
|
||||
}
|
||||
|
||||
var layers = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var layer in thing.Layers)
|
||||
{
|
||||
|
||||
@@ -104,6 +104,12 @@ public sealed class ThingDef : Def
|
||||
|
||||
/// <summary>PE kit. Worn for that lesson; not a second wardrobe of everyday clothes.</summary>
|
||||
public bool Pe { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Chance the dress generator issues this portable non-apparel item. 0 — not rolled (textbooks
|
||||
/// are granted per subject instead). Apparel ignores this and fills layers.
|
||||
/// </summary>
|
||||
public float CarryChance { get; init; }
|
||||
}
|
||||
|
||||
public sealed class PositionDef : Def;
|
||||
|
||||
@@ -513,6 +513,19 @@ internal static class PeopleDefValidator
|
||||
throw new ContentLoadException($"BehaviorDef '{behavior.DefName}' goal weights cannot be negative.");
|
||||
}
|
||||
|
||||
if (behavior.CarryMassBase < 0f
|
||||
|| behavior.CarryMassPerStrength < 0f
|
||||
|| behavior.CarryMassPerEndurance < 0f
|
||||
|| behavior.CarryMassPerHauling < 0f)
|
||||
{
|
||||
throw new ContentLoadException($"BehaviorDef '{behavior.DefName}' carry mass cannot be negative.");
|
||||
}
|
||||
|
||||
if (behavior.OptionalApparelChance is < 0f or > 1f)
|
||||
{
|
||||
throw new ContentLoadException($"BehaviorDef '{behavior.DefName}' optionalApparelChance must be 0–1.");
|
||||
}
|
||||
|
||||
// A pack may invert this on purpose — lunch then pulls the class out of the lesson.
|
||||
// The warning is the catch; refusing to load would make the number unmoddable.
|
||||
if (behavior.LunchWeight > behavior.DutyLessonWeight)
|
||||
|
||||
@@ -250,6 +250,18 @@ public sealed class BehaviorDef : Def
|
||||
/// pulls anybody out of a lesson.
|
||||
/// </summary>
|
||||
public float LunchWeight { get; init; } = 6f;
|
||||
|
||||
/// <summary>Kilograms a person can carry at strength/endurance/hauling 0, before the per-skill terms.</summary>
|
||||
public float CarryMassBase { get; init; } = 5f;
|
||||
|
||||
public float CarryMassPerStrength { get; init; } = 0.08f;
|
||||
|
||||
public float CarryMassPerEndurance { get; init; } = 0.04f;
|
||||
|
||||
public float CarryMassPerHauling { get; init; } = 0.08f;
|
||||
|
||||
/// <summary>Chance each optional layer (sweater, coat, hat, accessory) is worn at generation.</summary>
|
||||
public float OptionalApparelChance { get; init; } = 0.4f;
|
||||
}
|
||||
|
||||
public enum BodyAttributeKind
|
||||
|
||||
Reference in New Issue
Block a user