# 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.