Two concerns bundled into one commit because the csharpier tool restore
reformatted four earlier files as soon as the manifest landed:
- .config/dotnet-tools.json: csharpier 1.2.6 as local tool, follows
the standard .config layout (dotnet tool restore will find it).
- Anvil/packages.lock.json: produced by dotnet restore, pinned alongside
the csproj's RestorePackagesWithLockFile=true.
- Anvil/RecipeData/RecipeDataLoadResult.cs: public record carrying the
adapter's load-pass summary (counts + duration + warnings). Surfaced
to the SelfTest step and future UI status surfaces.
- Anvil/RecipeData/RecipeDataCatalog.cs: public DI singleton with all
seven dictionary lookups, the two helper methods (ActionsForClassJob,
TryResolveActionRowId), and the four meta properties from spec §2.7.
Backed by a private CatalogState record that the adapter swaps in via
a volatile reference - readers either see the empty initial state or
the fully populated post-load snapshot, never a partial mid-build.
TryResolveActionRowId carries the Cosmic-sentinel logic so hook code
does not need to know about the CosmicOnly flag itself.
- Reformatting in AnvilAction.cs, ActionMechanicsTable.cs,
ConditionMechanicsTable.cs, and Anvil.csproj: csharpier-mandated
line-wrap / blank-line tweaks. No semantic changes.
Three game-mechanics tables for the simulator-relevant constants that the
Lumina sheets do not expose, plus the reverse name map the adapter uses
to walk the CraftAction + Action sheets.
- ActionMechanicsTable: 38 entries with Category, CP cost, durability,
efficiency, IQ-stack bonus, charges, granted buff, and flags.
Cross-checked against the spec mechanics table in 01-RecipeData.md
§2.3.2 (verified there against Artisan's RawInformation/Character/
Skills.cs). Combo-state CP costs (Standard/Advanced Touch) carry the
base value; the simulator applies the discount. TrainedEye uses
short.MaxValue as the sentinel for "fill Recipe.QualityMax in one
step"; ByregotsBlessing carries base EfficiencyQuality=100 with the
IQ multiplier added by the simulator.
- BuffMechanicsTable: 14 entries with StatusId, Icon, StackMax, Behavior,
the three duration fields (Steps / Seconds / Actions populated per
Behavior), Category, and LegacyStatusId for the older Innovation 259
and Manipulation 258 ids. Cross-checked against ffxiv-datamining
Status.csv (StatusId / Icon / StackMax) and Artisan's tooltip-derived
step durations. Expedience uses the explicit StatusId 3812 - the other
two "Expedience" rows (2712 / 3092) are non-crafting status effects
that would otherwise produce an ambiguous name match.
- ConditionMechanicsTable: 11 entries with Quality / Progress / CP /
Durability multipliers plus a BaseProbability slot. Robust mirrors
Sturdy's durability discount and keeps Quality neutral (per the
spec mechanics table - the enum doc comment in AnvilCondition.cs
predates rev 5 and is noted as superseded in the table header).
SplendorCosmic's Good=1.75 override lives in the simulator.
BaseProbability stays 0.0; the static catalog has no useful per-recipe
spawn distribution because FFXIV derives that from Recipe.IsExpert +
RecipeLevelTable.Stars at runtime.
- ActionKindByName: reverse map from English action names to
AnvilActionKind, plus the Action-sheet whitelist (seven step-counter
buff actions + two Cosmic singletons) used to filter the Action sheet
walk down to the crafting subset.
Module 01 public-API surface: six sealed records with init-only
properties plus their nine enums. All BCL-only - no Lumina or Dalamud
types in any public property, which is what keeps the simulator and
catalog xUnit-testable per the Critical Boundary in 00-Anvil-Scope §3.3.
- AnvilRecipe + AnvilRecipeIngredient: flat representation of the
Recipe + RecipeLevelTable sheet pair with the five Cosmic-Exploration
flags. v0.1.0 ships with MissionHas* always false (SH-15 option B);
the schema stays in place so v0.2.0 can wire the WKS mission sheet
without touching the type.
- AnvilItem: slim per-recipe / per-food item view (full ~50k-row item
mirror is left to the UI layer).
- AnvilAction + AnvilActionKind + AnvilActionCategory + AnvilActionFlags:
one logical action per Kind value with RowIdByClassJob mapping; Cosmic
actions use ClassJobId 0 as the sentinel for "every crafter".
AnvilActionFlags bit 1 << 2 is intentionally vacant (ConsumesGreatStrides
was removed in spec rev 5; consumption logic lives in 02-CraftingSimulator).
- AnvilBuff + AnvilBuffKind + AnvilBuffBehavior + AnvilBuffCategory:
static buff catalog entry with the duration field that matches Behavior
(Steps / Seconds / Actions). Two Cosmic buffs (MaterialMiracleBuff,
StellarSteadyHandBuff).
- AnvilCondition + AnvilConditionKind: eleven conditions including the
Cosmic Robust variant. DisplayName comes from AnvilStrings.resx, not
Lumina (the Status sheet does not expose the crafting condition labels
cleanly).
- AnvilFood + AnvilFoodBonus + AnvilFoodKind + AnvilFoodStat: ItemFood
mirror with IsRelative flag (percentage vs flat bonus).