diff --git a/docs/zone-specific-resources-spec.md b/docs/zone-specific-resources-spec.md new file mode 100644 index 0000000..fe71cf0 --- /dev/null +++ b/docs/zone-specific-resources-spec.md @@ -0,0 +1,117 @@ +# Zone-specific resource nodes — implementation spec + +Currently `GoldRush.NodeEntries` is one global pool used for every hotspot +regardless of location — an event in Un'Goro Crater and one in Sholazar +Basin draw from the exact same 5 entries. This spec makes node selection +zone-aware: each configured hotspot gets resources that actually belong +there, plus a rare "bonus" node type for extra excitement. + +**Good news for implementation**: the module already tracks which zone/area +an event is anchored to (`GoldRushSite.ZoneLabel`/`ZoneId`/`AreaLabel`) — +this is purely about *using* that existing data to pick node types, not +building zone-tracking from scratch. + +--- + +## 1. Confirmed real, zone-appropriate resources (verified against the live DB, not guessed) + +Looked up directly against `acore_world.gameobject_template` (`type = 3`, +matching the 5 entries the module already uses) for the four zones +currently in `GoldRush.ZonePool`: + +| Hotspot | Herb entries | Ore entries | Bonus entries | +|---|---|---|---| +| Un'Goro Crater | Firethorn (191303) | Small Thorium Vein (324, 150082, 176643), Rich Thorium Vein (175404) | Black Lotus (176589) | +| Winterspring | Purple Lotus (142140, 180165), Sungrass (142142, 176636, 180164) | Small/Rich Thorium Vein (same as above) | Black Lotus (176589) | +| Eastern Plaguelands | Plaguebloom (176587, 176641), Ghost Mushroom (142144) | Small/Rich Thorium Vein (same as above) | Black Lotus (176589) | +| Sholazar Basin | Lichbloom (190171), Icethorn (190172), Goldclover (189973), Talandra's Rose (190170), Adder's Tongue (191019) | Cobalt Deposit (189978), Rich Cobalt Deposit (189979), Saronite Deposit (189980), Rich Saronite Deposit (189981), Titanium Vein (191133) | *(none needed — this zone's base pool is already top-tier; see note below)* | + +**Why Black Lotus for the three Classic zones specifically**: it's a real, +accurate spawn zone match — Black Lotus genuinely spawns in Un'Goro Crater, +Winterspring, and Eastern Plaguelands (among a couple others not in our +current hotspot list). It's a legitimately rare, high-value herb, which is +exactly the "couple of higher level ones" feel being asked for — not an +arbitrary reskin. + +**Sholazar's bonus tier**: Sholazar is already the highest-level zone in +the current hotspot list, and its existing default pool (Frost Lotus, +Lichbloom, Icethorn) is already the good stuff. Rather than reaching for +something contextually odd, treat the **Rich** variants of Cobalt/Saronite +as its "bonus" tier — rarer, better-yielding versions of what's already +appropriate there. Simpler and more thematically honest than importing an +unrelated resource into a zone it doesn't belong in. + +**If more hotspots get added to `ZonePool` later**, they'll need the same +kind of real DB lookup before assigning resources — don't extrapolate a +"probably fine" guess from a different zone's list. + +--- + +## 2. Config format change + +Extend the existing pipe-delimited `Zone|Area` tokens in `GoldRush.ZonePool` +with two more optional segments — `NodeEntries` and `BonusEntries` — using +the same `;`-separated-entries convention `GoldRush.NodeEntries` already +uses: + +``` +GoldRush.ZonePool = Un'Goro Crater|Fire Plume Ridge|191303;324;150082;176643;175404|176589; Winterspring|Frostfire Hot Springs|142140;180165;142142;176636;180164;324;150082;176643;175404|176589; Eastern Plaguelands|Terrorweb Tunnel|176587;176641;142144;324;150082;176643;175404|176589; Sholazar Basin|River's Heart|190171;190172;189973;190170;191019;189978;189979;189980;189981;191133|189979;189981 +``` + +**Backward compatibility matters here** — a hotspot token with only +`Zone|Area` (no node/bonus segments) should fall back to the existing +global `GoldRush.NodeEntries` pool, exactly as it does today. Don't make +the new segments required; this format needs to keep working for anyone +who hasn't customized it (and for a clean upgrade path if more hotspots +get added later without someone remembering to fill in resources for them +immediately). + +## 3. Code changes + +- **`GoldRushSite` struct** (`GoldRush.cpp:44`): add `std::vector + NodeEntries` and `std::vector BonusEntries`, both defaulting + empty. +- **`BuildSites()`** (`GoldRush.cpp:479`): parse the 3rd and 4th `|`-delimited + segments (if present) through the existing `BuildNodeEntries()` parser, + storing them on the site. +- **`SpawnHotspot()`** (`GoldRush.cpp:919`): currently always builds + `oreEntries`/`herbEntries`/`fallbackEntries` from the global `_nodeEntries`. + Change this to use `_currentSite.NodeEntries` when non-empty, falling back + to the global `_nodeEntries` otherwise — same herb/ore + alternating-selection logic (`SplitByCategory`) already in place, just + fed from the per-site pool instead of always the global one. +- **Bonus node mixing**: in the per-node selection loop (`GoldRush.cpp:949` + onward), give each node spawn attempt a small chance (a new config value, + e.g. `GoldRush.BonusChancePercent`, reasonable default around 10-15%) to + pull from `_currentSite.BonusEntries` instead of the normal herb/ore pool + for that one node — so a Gold Rush event yields mostly zone-appropriate + regular resources with an occasional Black Lotus mixed in, not a + guaranteed one every time (that would undercut its rarity and value). + +## 4. Config parameters from the original request + +Already applied directly on the live server (config-only, no code change +needed for these two): + +``` +GoldRush.SpawnRadiusYards = 75.0 +GoldRush.MinNodes = 20 +GoldRush.MaxNodes = 30 +``` + +No action needed here — mentioned for completeness since this spec +originated from the same conversation as those changes. + +## 5. Testing + +- `.goldrush teststart` while standing in each of the four configured + hotspots — confirm the herb/ore mix that spawns actually matches that + zone's table above, not the old global pool. +- Run enough test events per zone to actually observe a bonus node + appear (given a ~10-15% per-node chance across 20-30 nodes, a bonus + should show up in most single events, but don't rely on exactly one + test run to confirm the feature works — false negatives are likely on + a single low-probability roll). +- Confirm a hotspot token with the old 2-segment `Zone|Area` format (no + node/bonus data) still works and falls back to the global pool — + don't let this become a breaking change for the config format.