90803bcd3cb12b6cbb95796e99624157c23b8cf8
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
90803bcd3c |
feat(bootstrap): wire DI host, hosted services, and plugin entry
The plugin is now loadable. Dalamud injects five services into the Plugin constructor (Lightless pattern), the constructor builds the generic-host container synchronously, and PluginLifecycle drives StartAsync from LoadAsync. Module 02+ extends PluginHostFactory; this file set stays put. - PluginHostDependencies (record): bundles the five Dalamud services v0.1.0 needs (IDalamudPluginInterface, IPluginLog, IDataManager, IFramework, ISelfTestRegistry). - PluginHostFactory.Build: HostBuilder + AddDalamudLogging + the four service blocks (Dalamud services, Anvil singletons, ISelfTestStep collection, IHostedService init chain). Every registration uses an explicit factory lambda - the default activator only sees public ctors and Anvil follows the internal-sealed convention. - PluginLifecycle (IAsyncDisposable): owns Host.StartAsync, marshals the Host.Dispose call onto the framework thread, idempotency guard via Interlocked, ExceptionDispatchInfo.Capture preserves the original load-throw stack when a failure cascades. - Plugin (IAsyncDalamudPlugin): constructor injection of the five Dalamud services, builds the dependencies record, kicks off the host build, hands DisposeAsync to the lifecycle. - Hosting/RecipeDataLoadHostedService: dispatches LuminaRecipeAdapter .LoadInternal onto the framework thread on StartAsync. Lumina sheet reads have no documented thread safety; conservative default. - Hosting/SelfTestRegistrationHostedService: collects every ISelfTestStep registration from DI and hands them to ISelfTestRegistry.RegisterTestSteps once the host is up. - SelfTest/RecipeDataAdapterLoadStep: nine pass criteria per spec §4.1 (IsLoaded, RecipeCount > 0, ActionCount in 30..80, BuffsByKind.Count == 14, ConditionsByKind.Count == 11, Foods >= 30, Medicines >= 5, BasicSynthesis.RowIdByClassJob[8] == 100001, Cosmic-surface silent-degradation warning). Returns Waiting while the catalog is still loading. - Infrastructure/Logging trio: DalamudLogger maps Microsoft.Extensions.Logging levels to IPluginLog, the provider emits an Anvil bootstrap banner with a Forge-Bronze fingerprint on ctor, the extension wires the provider into the ILoggingBuilder via TryAddEnumerable. |
||
|
|
401ebc9495 |
feat(recipedata): add LuminaRecipeAdapter + AnvilStrings resx
The adapter is the only place in the plugin that touches Lumina and Dalamud types - everything outside Anvil.RecipeData.Internal stays on the BCL surface (Critical Boundary per 00-Anvil-Scope §3.3). - LuminaRecipeAdapter: walks Status, CraftAction, Action, Item, ItemFood, and Recipe + RecipeLevelTable, builds the AnvilXxx records, and swaps the CatalogState into RecipeDataCatalog in one atomic write. Cosmic actions normalise the Action-sheet ClassJob=-1 sentinel to RowIdByClassJob key 0 (spec §2.3.1); the legacy ARR singletons (Manipulation 278, Waste Not 279, Innovation 284, Waste Not II 285) drop out via the PrimaryCostValue == 0 filter (spec §3.1 #3). The CraftAction sheet wins the canonical icon at the CRP variant (ClassJobId 8). Per-job rows are cross-checked for Cost, ClassJobLevel, and Specialist consistency; mismatches log a warning. - SH-15 option B is hard-wired: every AnvilRecipe ships with MissionHasMaterialMiracle = false, MissionHasSteadyHand = false, and IsSplendorCosmic = false in v0.1.0. IsCosmic is still set from Recipe.Number == 0 so the catalog can label Cosmic recipes; the WKS mission sheet chain is not walked. v0.2.0 will replace those constant assignments with the resolver and the rest of the adapter stays put. - The adapter invariant (Cosmic sub-flag implies the master IsCosmic flag) throws on inconsistent recipe states at catalog-build time so v0.2.0+ catches a broken WKS resolver before it corrupts the simulator. - ItemFood walk uses ItemAction.Data[0] (48 = "well fed", 49 = "medicated") instead of an ItemAction.Type column that does not exist in the current Lumina schema. The bonus extractor filters ItemFood.Params to the three crafting BaseParam ids (CP=11, Craftsmanship=70, Control=71). Item rows are populated only for the ItemIds that recipes / foods actually reference - no 50k-row mirror. - AnvilStrings.resx + AnvilStrings.de.resx + AnvilStrings.Designer.cs: Localization layer for condition display names and the SelfTest step name. The adapter looks the condition strings up through the generated ResourceManager so culture-switching is a no-restart change later on. |
||
|
|
eb5753eea6 |
feat(recipedata): add catalog + load result, wire csharpier
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. |
||
|
|
d7e8c42cc7 |
feat(recipedata): add hardcoded mechanics tables
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. |
||
|
|
47790a3f68 |
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). |
||
|
|
96553a849a |
chore: bootstrap Anvil repo skeleton
First commit on feature/v0.1.0 establishes the Hellion Forge plugin scaffold: - .gitattributes: Linux-first LF defaults, Windows-script CRLF exceptions, binary markers for fonts / images / archives. Pre-empts the Forgeimizer pre-push hook crash that was caused by Asriels CRLF default. - .editorconfig: Hellion Forge .NET conventions (private fields _camelCase, Allman braces, var-preferred). - .gitignore: VisualStudio baseline + secrets bucket + Anvil.Tests excluded (build-suite lives in the local Hellion Build test repo). - LICENSE: MIT, Hellion Online Media 2026. - NOTICE.md: goodwill attribution to Craftimizer and clean-room anonymisation note. - PRIVACY.md: zero-telemetry statement matching 00-Anvil-Scope. - README.md: v0.1.0 status + planned-feature outline + custom-repo URL. - Anvil.sln + Anvil/Anvil.csproj: Dalamud.NET.Sdk/15.0.0, x64 platform pinned (forge-wide rule), Microsoft.Extensions.Hosting stack closed-range pin to 10.0.7 matching HellionChat v1.5.0. No DalamudPackager.targets override - SDK 15 default packager handles images / icon / image_urls. - Anvil/Anvil.yaml: plugin manifest with explicit icon_url / image_urls (top-level fields required for SDK 15 default packager) and a v0.1.0 changelog entry that names RecipeData as the first module. |