docs+fix(chargen): CC1/CC2 review closeout — R2/R3 residuals closed, ledger final
Both narrow re-reviews returned CLOSED. This closeout takes the two cheap
re-review residuals before CC3 takes references to the shared model:
R2: every array handed into the typed chargen model is now wrapped in
Array.AsReadOnly at the projection seam — a T[] behind IReadOnlyList<T>
was still downcast-mutable, and ChargenOptions is a process-shared
singleton graph.
R3: the no-Chorizite-leak guard now also walks public fields; every
current type uses properties, but a public field would have slipped
through the property-only walk.
Ledger: CC1 fix-round sha corrected to cb4703e8 (the cell previously
cited the pre-amend 459a87f2), CC1/CC2 rows flipped to REVIEW-CLOSED
with the re-review outcomes, R1 (retail refunds +1 credit on a
both-tier cost miss; port charges 0 — unreachable via retail's own
listbox, noted for CC3) and the Olthoi-locked-to-template-0 decomp fact
recorded for CC3/CC4.
Core.Tests 4736/1 skip, Content.Tests 145/0, Release.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
55fc51ed8c
commit
f3ef7baae2
3 changed files with 37 additions and 24 deletions
|
|
@ -16,7 +16,7 @@ namespace AcDream.Content.CharGen;
|
|||
/// presentation-free <see cref="AcDream.Core.CharGen.ChargenOptions"/> tree.
|
||||
/// Mirrors <c>MagicCatalog.Load</c>'s shape: one static entry point over
|
||||
/// <see cref="IDatReaderWriter"/>, every returned collection is frozen at
|
||||
/// projection (<c>ToFrozenDictionary</c> / <c>ToArray</c>, matching
|
||||
/// projection (<c>ToFrozenDictionary</c> / <c>Array.AsReadOnly</c>, matching
|
||||
/// <c>MagicCatalog</c>'s pattern), and no Chorizite types cross into the
|
||||
/// returned model. Cross-checked against ACE's
|
||||
/// <c>ACE.DatLoader.FileTypes.CharGen</c> +
|
||||
|
|
@ -94,7 +94,7 @@ public static class ChargenTableReader
|
|||
}
|
||||
|
||||
return new ChargenOptions(
|
||||
starterAreas,
|
||||
Array.AsReadOnly(starterAreas),
|
||||
heritagesById.ToFrozenDictionary(),
|
||||
globalSkillCosts.ToFrozenDictionary());
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ public static class ChargenTableReader
|
|||
position.Frame.Origin,
|
||||
position.Frame.Orientation);
|
||||
}
|
||||
return new ChargenStarterArea(index, area.Name.Value, locations);
|
||||
return new ChargenStarterArea(index, area.Name.Value, Array.AsReadOnly(locations));
|
||||
}
|
||||
|
||||
private static ChargenHeritageOptions ProjectHeritage(uint heritageId, HeritageGroupCG cg)
|
||||
|
|
@ -138,10 +138,10 @@ public static class ChargenTableReader
|
|||
cg.EnvironmentSetupId.DataId,
|
||||
cg.AttributeCredits,
|
||||
cg.SkillCredits,
|
||||
cg.PrimaryStartAreas.ToArray(),
|
||||
cg.SecondaryStartAreas.ToArray(),
|
||||
Array.AsReadOnly(cg.PrimaryStartAreas.ToArray()),
|
||||
Array.AsReadOnly(cg.SecondaryStartAreas.ToArray()),
|
||||
skillCosts.ToFrozenDictionary(),
|
||||
templates,
|
||||
Array.AsReadOnly(templates),
|
||||
gendersByKey.ToFrozenDictionary());
|
||||
}
|
||||
|
||||
|
|
@ -166,8 +166,8 @@ public static class ChargenTableReader
|
|||
template.Quickness,
|
||||
template.Focus,
|
||||
template.Self),
|
||||
normalSkills,
|
||||
primarySkills);
|
||||
Array.AsReadOnly(normalSkills),
|
||||
Array.AsReadOnly(primarySkills));
|
||||
}
|
||||
|
||||
private static ChargenGenderOptions ProjectGender(int genderKey, SexCG sex)
|
||||
|
|
@ -221,20 +221,20 @@ public static class ChargenTableReader
|
|||
sex.MotionTable.DataId,
|
||||
sex.CombatTable.DataId,
|
||||
ProjectObjDesc(sex.BaseObjDesc),
|
||||
sex.HairColors.ToArray(),
|
||||
hairStyles,
|
||||
sex.EyeColors.ToArray(),
|
||||
eyeStrips,
|
||||
noseStrips,
|
||||
mouthStrips,
|
||||
Array.AsReadOnly(sex.HairColors.ToArray()),
|
||||
Array.AsReadOnly(hairStyles),
|
||||
Array.AsReadOnly(sex.EyeColors.ToArray()),
|
||||
Array.AsReadOnly(eyeStrips),
|
||||
Array.AsReadOnly(noseStrips),
|
||||
Array.AsReadOnly(mouthStrips),
|
||||
ProjectGearList(sex.Headgears),
|
||||
ProjectGearList(sex.Shirts),
|
||||
ProjectGearList(sex.Pants),
|
||||
ProjectGearList(sex.Footwear),
|
||||
sex.ClothingColors.ToArray());
|
||||
Array.AsReadOnly(sex.ClothingColors.ToArray()));
|
||||
}
|
||||
|
||||
private static ChargenGearOption[] ProjectGearList(List<GearCG> gearList)
|
||||
private static IReadOnlyList<ChargenGearOption> ProjectGearList(List<GearCG> gearList)
|
||||
{
|
||||
var result = new ChargenGearOption[gearList.Count];
|
||||
for (int i = 0; i < gearList.Count; i++)
|
||||
|
|
@ -242,7 +242,7 @@ public static class ChargenTableReader
|
|||
GearCG gear = gearList[i];
|
||||
result[i] = new ChargenGearOption(gear.Name.Value, gear.ClothingTable.DataId, gear.WeenieDefault);
|
||||
}
|
||||
return result;
|
||||
return Array.AsReadOnly(result);
|
||||
}
|
||||
|
||||
private static CoreChargenObjDesc ProjectObjDesc(DatObjDesc objDesc)
|
||||
|
|
@ -271,6 +271,10 @@ public static class ChargenTableReader
|
|||
animPartChanges[i] = new ChargenAnimPartChange(change.PartIndex, change.PartId.DataId);
|
||||
}
|
||||
|
||||
return new CoreChargenObjDesc(objDesc.PaletteId.DataId, subPalettes, textureChanges, animPartChanges);
|
||||
return new CoreChargenObjDesc(
|
||||
objDesc.PaletteId.DataId,
|
||||
Array.AsReadOnly(subPalettes),
|
||||
Array.AsReadOnly(textureChanges),
|
||||
Array.AsReadOnly(animPartChanges));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue