feat(recipedata): add plain-data records and enums
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).
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
// Plain-data record describing a single FFXIV crafting recipe. Public surface
|
||||
// is intentionally BCL-only (no Lumina or Dalamud types) so the simulator and
|
||||
// solver can be tested in xUnit without loading Dalamud.dll into the test
|
||||
// AppDomain. The adapter (Internal/LuminaRecipeAdapter) builds these from the
|
||||
// Recipe + RecipeLevelTable sheet pair and flattens both sheets into one
|
||||
// record so consumers never have to do a two-sheet walk.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Anvil.RecipeData;
|
||||
|
||||
public sealed record AnvilRecipe
|
||||
{
|
||||
public required uint RecipeId { get; init; }
|
||||
public required uint OutputItemId { get; init; }
|
||||
public required byte OutputAmount { get; init; }
|
||||
public required uint ClassJobId { get; init; }
|
||||
public required ushort RecipeLevel { get; init; }
|
||||
public required int Difficulty { get; init; }
|
||||
public required int QualityMax { get; init; }
|
||||
public required byte Durability { get; init; }
|
||||
public required int RequiredCraftsmanship { get; init; }
|
||||
public required int RequiredControl { get; init; }
|
||||
public required int QualityForHQ { get; init; }
|
||||
public required bool IsExpertRecipe { get; init; }
|
||||
public required bool CanHQ { get; init; }
|
||||
|
||||
// Cosmic Exploration (Patch 7.x). v0.1.0 ships with MissionHas* always
|
||||
// false (SH-15 option B) - the data schema stays in place so v0.2.0+ can
|
||||
// light up the surface by resolving the WKS mission sheet without
|
||||
// touching the type. IsCosmic / IsSplendorCosmic are still set by the
|
||||
// recipe-detection path so the catalog knows which recipes belong to the
|
||||
// Cosmic surface even while the action flags stay dormant.
|
||||
//
|
||||
// Adapter invariant (validated when the catalog is built):
|
||||
// IsSplendorCosmic == true implies IsCosmic == true
|
||||
// MissionHasMaterialMiracle == true implies IsCosmic == true
|
||||
// MissionHasSteadyHand == true implies IsCosmic == true
|
||||
//
|
||||
// Inconsistent recipe states (sub-flag without master flag) throw at
|
||||
// catalog-build time instead of silently corrupting the simulator.
|
||||
public required bool IsCosmic { get; init; }
|
||||
public required bool IsSplendorCosmic { get; init; }
|
||||
public required bool MissionHasMaterialMiracle { get; init; }
|
||||
public required bool MissionHasSteadyHand { get; init; }
|
||||
public required bool IsIshgardExpert { get; init; }
|
||||
|
||||
public required byte Stars { get; init; }
|
||||
public required byte ProgressDivider { get; init; }
|
||||
public required byte ProgressModifier { get; init; }
|
||||
public required byte QualityDivider { get; init; }
|
||||
public required byte QualityModifier { get; init; }
|
||||
public required IReadOnlyList<AnvilRecipeIngredient> Ingredients { get; init; }
|
||||
public required string DisplayName { get; init; }
|
||||
}
|
||||
|
||||
public sealed record AnvilRecipeIngredient(uint ItemId, byte Amount);
|
||||
Reference in New Issue
Block a user