fix: herb/ore categorization via static ID lookup table
SplitByCategory() guessed herb/ore from display-name keywords written for the original 5-entry Northrend pool. Outland/Classic ore uses 'Deposit' not 'Vein', and most herb names match no keyword, so both buckets came back empty for almost every v2 zone and the code silently fell back to the unsplit pool (confirmed live in Hellfire Peninsula). Replace the keyword guess with a static ID->category lookup table built from the DB-verified entry IDs in docs/zone-specific-resources-spec.md. The old keyword check is retained only as a fallback for entries not in the table.
This commit is contained in:
parent
5d292b3d9c
commit
24b0815fc6
2 changed files with 68 additions and 3 deletions
|
|
@ -17,6 +17,15 @@ All notable changes to `mod-gold-rush` will be documented in this file.
|
|||
global `GoldRush.NodeEntries` pool exactly as before.
|
||||
|
||||
### Fixed
|
||||
- Herb/ore categorization no longer guesses from display-name keywords. The old
|
||||
`SplitByCategory()` matched "lotus"/"clover"/"thorn"/"bloom" for herbs and
|
||||
"vein" for ore, which only worked for the original Northrend default pool and
|
||||
silently fell back to the unsplit pool for almost every v2 zone (Outland/Classic
|
||||
ore uses "Deposit", not "Vein"; most herb names match no keyword). Replaced with
|
||||
a static ID→category lookup table built from the DB-verified entry IDs in
|
||||
`docs/zone-specific-resources-spec.md`, with the old keyword check retained only
|
||||
as a fallback for entries not in the table. See
|
||||
`docs/herb-ore-category-fix-spec.md`.
|
||||
- Event start/end announcements no longer crash the server. `StartEvent()` and
|
||||
`EndEvent()` both used `ChatHandler(nullptr).SendWorldText(...)` to broadcast
|
||||
server-wide -- `ChatHandler::SendWorldText` assumes a real session and calls
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -41,6 +42,47 @@ static constexpr float MaxVerticalDrift = 20.0f; // reject ground this far
|
|||
// Mirrors INVALID_HEIGHT from GridTerrainData.h without taking a dependency on that header.
|
||||
static constexpr float InvalidHeightSentinel = -99999.0f;
|
||||
|
||||
// Static ID -> category lookup for herb/ore classification. Every entry ID used
|
||||
// across the 57-zone GoldRush.ZonePool (plus the module's own default global
|
||||
// GoldRush.NodeEntries) was individually verified against
|
||||
// acore_world.gameobject_template when the pool was built
|
||||
// (docs/zone-specific-resources-spec.md). Guessing the category from the display
|
||||
// name (the old keyword-list approach) broke for almost every zone: Outland/Classic
|
||||
// ore uses "Deposit" rather than "Vein", and most herb names don't contain any of
|
||||
// the four hardcoded herb keywords. true = herb, false = ore.
|
||||
static const std::unordered_map<uint32, bool> IsHerbById = {
|
||||
// Classic herbs
|
||||
{ 1618, true }, { 3724, true }, { 1617, true }, { 3725, true }, { 1619, true }, { 3726, true }, // Peacebloom, Silverleaf, Earthroot
|
||||
{ 1620, true }, { 3727, true }, { 1621, true }, { 3729, true }, { 2045, true }, { 1622, true }, { 3730, true }, // Mageroyal, Briarthorn, Stranglekelp, Bruiseweed
|
||||
{ 1623, true }, { 1624, true }, { 2041, true }, { 2042, true }, { 2046, true }, { 2043, true }, { 2866, true }, // Wild Steelbloom, Kingsblood, Liferoot, Fadeleaf, Goldthorn, Khadgar's Whisker, Firebloom
|
||||
{ 142140, true }, { 180165, true }, { 142141, true }, { 176642, true }, // Purple Lotus, Arthas' Tears
|
||||
{ 142142, true }, { 176636, true }, { 180164, true }, { 142143, true }, { 183046, true }, // Sungrass, Blindweed
|
||||
{ 142144, true }, { 142145, true }, { 176637, true }, { 176587, true }, { 176641, true }, // Ghost Mushroom, Gromsblood, Plaguebloom
|
||||
{ 176583, true }, { 176638, true }, { 180167, true }, { 176584, true }, { 176639, true }, // Golden Sansam, Dreamfoil
|
||||
{ 180168, true }, { 176586, true }, { 176640, true }, { 180166, true }, { 176588, true }, // Mountain Silversage, Icecap
|
||||
{ 191303, true }, { 176589, true }, // Firethorn, Black Lotus
|
||||
// Outland herbs
|
||||
{ 181270, true }, { 183044, true }, { 181271, true }, { 183045, true }, { 181275, true }, // Felweed, Dreaming Glory, Ragveil
|
||||
{ 183043, true }, { 181277, true }, { 181276, true }, { 181279, true }, { 181280, true }, { 181281, true }, // Terocone, Flame Cap, Netherbloom, Nightmare Vine, Mana Thistle
|
||||
// Northrend herbs
|
||||
{ 189973, true }, { 190171, true }, { 190172, true }, { 190176, true }, { 190170, true }, // Goldclover, Lichbloom, Icethorn, Frost Lotus, Talandra's Rose
|
||||
{ 191019, true }, { 190169, true }, // Adder's Tongue, Tiger Lily
|
||||
// Classic ore
|
||||
{ 1731, false }, { 2055, false }, { 3763, false }, { 103713, false }, { 181248, false }, // Copper Vein
|
||||
{ 1732, false }, { 2054, false }, { 3764, false }, { 103711, false }, { 181249, false }, // Tin Vein
|
||||
{ 1733, false }, { 105569, false }, // Silver Vein
|
||||
{ 1735, false }, // Iron Deposit
|
||||
{ 1734, false }, { 150080, false }, { 181109, false }, // Gold Vein
|
||||
{ 2040, false }, { 150079, false }, { 176645, false }, // Mithril Deposit
|
||||
{ 2047, false }, { 150081, false }, { 181108, false }, // Truesilver Deposit
|
||||
{ 324, false }, { 150082, false }, { 176643, false }, { 175404, false }, // Small/Rich Thorium Vein
|
||||
{ 165658, false }, // Dark Iron Deposit
|
||||
// Outland ore
|
||||
{ 181555, false }, { 181556, false }, { 181569, false }, { 181570, false }, { 181557, false }, // Fel Iron, Adamantite (+ Rich), Khorium
|
||||
// Northrend ore
|
||||
{ 189978, false }, { 189979, false }, { 189980, false }, { 189981, false }, { 191133, false }, // Cobalt/Saronite Deposit (+ Rich), Titanium Vein
|
||||
};
|
||||
|
||||
struct GoldRushSite
|
||||
{
|
||||
std::string ZoneLabel;
|
||||
|
|
@ -657,9 +699,23 @@ private:
|
|||
if (!goinfo)
|
||||
continue;
|
||||
|
||||
std::string name = Normalize(goinfo->name);
|
||||
bool isHerb = ContainsWord(name, "lotus") || ContainsWord(name, "clover") || ContainsWord(name, "thorn") || ContainsWord(name, "bloom");
|
||||
bool isOre = ContainsWord(name, "vein");
|
||||
// Prefer the verified ID -> category lookup table. The old name-keyword
|
||||
// guess is kept only as a defensive fallback for entries not in the table
|
||||
// (e.g. the original global-pool defaults or anything added by hand later
|
||||
// without an explicit table update).
|
||||
bool isHerb;
|
||||
auto const it = IsHerbById.find(entry);
|
||||
if (it != IsHerbById.end())
|
||||
{
|
||||
isHerb = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = Normalize(goinfo->name);
|
||||
isHerb = ContainsWord(name, "lotus") || ContainsWord(name, "clover") || ContainsWord(name, "thorn") || ContainsWord(name, "bloom");
|
||||
}
|
||||
|
||||
bool isOre = !isHerb;
|
||||
|
||||
if (herbs && isHerb)
|
||||
result.push_back(entry);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue