186e02c3eefa7b1a4bbcea043dacf31f15f44519
8 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
186e02c3ee |
fix(plugin): register UiBuilder.OpenConfigUi / OpenMainUi stubs
Dalamud's plugin validator flagged two issues on v0.1.0: - "The plugin does not register a config UI callback." - "The plugin does not register a main UI callback." v0.1.0 ships the RecipeData layer only - the actual SettingsWindow and MainWindow arrive with module 08 (UI). To pass validation and to give users a useful response when they click "Open Settings" or "Open Main" in the plugin installer, both callbacks now fire toast notifications via INotificationManager that point at the roadmap. The handlers wire up in the constructor right after the host build and unwire in DisposeAsync. INotificationManager joins the Block A Dalamud services in PluginHostDependencies + PluginHostFactory so the DI container also exposes it for later modules. |
||
|
|
d8efc213e3 |
chore: add pre-push preflight + setup-hooks
Four-block pre-push gate matching the HellionChat pattern: - Block A (verify-version-consistency.sh): csproj <Version> vs repo.json AssemblyVersion / TestingAssemblyVersion / DownloadLink* tag presence. Tolerant of repo.json being absent so v0.1.0 (which has no public release manifest yet) does not fail at push time; the missing-file path turns into the full cross-check once repo.json lands. - Block B: dotnet build Anvil.sln -p:Platform=x64 -c Release. Platform pin is forge-wide (Forgeimizer v0.1.0 lesson: solution build defaults drift to AnyCPU otherwise). - Block C: dotnet csharpier check ./Anvil. Catches the accumulated formatter drift that hit HellionChat v1.5.6 (12 files) when only build was checked per task. - Block D: markdownlint-cli2 over the repo's *.md files (excludes node_modules, bin, obj, .claude, CLAUDE.md). Plus setup-hooks.sh as the one-shot installer that points core.hooksPath at .githooks/ and chmods the scripts. README.md: MD040 fix for the custom-repo URL fence (added text language tag). |
||
|
|
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. |