diff --git a/pkg/data/game/game.go b/pkg/data/game/game.go new file mode 100644 index 0000000..de34db1 --- /dev/null +++ b/pkg/data/game/game.go @@ -0,0 +1,7 @@ +package game + +const ( + CharClassic uint16 = 1 + CharLoD uint16 = 2 + CharDLC uint16 = 3 +) diff --git a/pkg/data/item/name.go b/pkg/data/item/name.go index 3c5fbfd..278a3e9 100644 --- a/pkg/data/item/name.go +++ b/pkg/data/item/name.go @@ -1,18 +1,16 @@ package item -import "strings" +import ( + "strings" + + "github.com/hectorgimenez/d2go/pkg/data/game" +) const ( ExpCharItemIDThreshold = 508 ExpCharItemIDOffset = 15 ) -var ExpChar uint16 - -func SetExpChar(expChar uint16) { - ExpChar = expChar -} - const ( ScrollOfTownPortal = "ScrollOfTownPortal" ScrollOfIdentify = "ScrollOfIdentify" @@ -21,9 +19,9 @@ const ( Key = "Key" ) -func GetNameByEnum(itemNumber uint) Name { +func GetNameByEnumWithExpChar(expChar uint16, itemNumber uint) Name { idx := int(itemNumber) - if ExpChar >= 3 && idx >= ExpCharItemIDThreshold { + if expChar >= game.CharDLC && idx >= ExpCharItemIDThreshold { idx += ExpCharItemIDOffset } if idx < 0 || idx >= len(Names) { @@ -32,17 +30,16 @@ func GetNameByEnum(itemNumber uint) Name { return Name(Names[idx]) } -func GetIDByName(itemName string) int { +// DescIDByName returns the internal description/index ID for an item name. +// This ID matches the keys used by Desc and the indices in the Names slice. +func DescIDByName(itemName string) (int, bool) { for i, name := range Names { if strings.EqualFold(name, itemName) { - if ExpChar >= 3 && i >= ExpCharItemIDThreshold+ExpCharItemIDOffset { - return i - ExpCharItemIDOffset - } - return i + return i, true } } - return -1 + return -1, false } type Name string diff --git a/pkg/data/items.go b/pkg/data/items.go index 2b0816c..374f0ca 100644 --- a/pkg/data/items.go +++ b/pkg/data/items.go @@ -121,11 +121,17 @@ type Drop struct { } func (i Item) Desc() item.Description { - id := i.ID - if item.ExpChar >= 3 && id >= item.ExpCharItemIDThreshold { - id += item.ExpCharItemIDOffset + if descID, ok := item.DescIDByName(string(i.Name)); ok { + if desc, found := item.Desc[descID]; found { + return desc + } } - return item.Desc[id] + + if desc, found := item.Desc[i.ID]; found { + return desc + } + + return item.Description{} } func (i Item) Type() item.Type { diff --git a/pkg/memory/item.go b/pkg/memory/item.go index 44f06bb..bc86c5b 100644 --- a/pkg/memory/item.go +++ b/pkg/memory/item.go @@ -14,7 +14,6 @@ import ( ) func (gd *GameReader) Inventory(rawPlayerUnits RawPlayerUnits, hover data.HoverData) data.Inventory { - item.SetExpChar(gd.ExpChar) mainPlayer := rawPlayerUnits.GetMainPlayer() baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + (4 * 1024) unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8) @@ -132,7 +131,7 @@ func (gd *GameReader) Inventory(rawPlayerUnits RawPlayerUnits, hover data.HoverD itm := &data.Item{ ID: int(txtFileNo), UnitID: data.UnitID(unitID), - Name: item.GetNameByEnum(txtFileNo), + Name: item.GetNameByEnumWithExpChar(gd.ExpChar, txtFileNo), Quality: item.Quality(itemQuality), Position: data.Position{ X: int(itemX), diff --git a/pkg/memory/player.go b/pkg/memory/player.go index 929bcb7..c187b4d 100644 --- a/pkg/memory/player.go +++ b/pkg/memory/player.go @@ -7,6 +7,7 @@ import ( "github.com/hectorgimenez/d2go/pkg/data" "github.com/hectorgimenez/d2go/pkg/data/area" + "github.com/hectorgimenez/d2go/pkg/data/game" "github.com/hectorgimenez/d2go/pkg/data/skill" "github.com/hectorgimenez/d2go/pkg/data/state" ) @@ -40,7 +41,7 @@ func (gd *GameReader) GetRawPlayerUnits() RawPlayerUnits { expChar := gd.Process.ReadUInt(expCharPtr+0x5C, Uint16) gd.ExpChar = uint16(expChar) isMainPlayer := gd.Process.ReadUInt(inventoryAddr+0x30, Uint16) - if expChar >= 2 { + if expChar >= uint(game.CharLoD) { isMainPlayer = gd.Process.ReadUInt(inventoryAddr+0x70, Uint16) } isCorpse := gd.Process.ReadUInt(playerUnit+0x1AE, Uint8) diff --git a/pkg/nip/rule.go b/pkg/nip/rule.go index 0ec5de8..ff8a1e4 100644 --- a/pkg/nip/rule.go +++ b/pkg/nip/rule.go @@ -250,7 +250,11 @@ func (r Rule) Evaluate(it data.Item) (RuleResult, error) { case "class": stage1Props["class"] = int(it.Desc().Tier()) case "name": - stage1Props["name"] = it.ID + if descID, ok := item.DescIDByName(string(it.Name)); ok { + stage1Props["name"] = descID + } else { + stage1Props["name"] = it.ID + } case "flag": // 0x400000 (eth) | 0x4000000 (runeword) kolbot style currentFlag := 0 @@ -487,7 +491,8 @@ func replaceStringPropertiesInStage1(stage1 string) (string, error) { case "class": replaceWith = strings.ReplaceAll(prop[0], prop[4], fmt.Sprintf("%d", classAliases[prop[4]])) case "name": - replaceWith = strings.ReplaceAll(prop[0], prop[4], fmt.Sprintf("%d", item.GetIDByName(prop[4]))) + descID, _ := item.DescIDByName(prop[4]) + replaceWith = strings.ReplaceAll(prop[0], prop[4], fmt.Sprintf("%d", descID)) case "flag": val := 0 switch strings.ToLower(prop[4]) {