get stashed gold

This commit is contained in:
Héctor Giménez
2024-05-15 17:23:53 +09:00
parent ffae8296af
commit 2a5f31885e
7 changed files with 48 additions and 31 deletions

View File

@@ -53,7 +53,7 @@ func (w *Watcher) Start(ctx context.Context) error {
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
d := w.gr.GetData() d := w.gr.GetData()
for _, i := range d.Items.ByLocation(item.LocationGround) { for _, i := range d.Inventory.ByLocation(item.LocationGround) {
for _, r := range w.rules { for _, r := range w.rules {
res, err := r.Evaluate(i) res, err := r.Evaluate(i)
if err != nil { if err != nil {
@@ -92,7 +92,7 @@ func (w *Watcher) Start(ctx context.Context) error {
purgedNotifiedItems := make([]itemFootprint, 0) purgedNotifiedItems := make([]itemFootprint, 0)
for _, t := range w.alreadyNotifiedItemIDs { for _, t := range w.alreadyNotifiedItemIDs {
found := false found := false
for _, it := range d.Items.ByLocation(item.LocationGround) { for _, it := range d.Inventory.ByLocation(item.LocationGround) {
if t.Match(d.PlayerUnit.Area, it) { if t.Match(d.PlayerUnit.Area, it) {
found = true found = true
} }

View File

@@ -31,7 +31,7 @@ type Data struct {
CollisionGrid [][]bool CollisionGrid [][]bool
PlayerUnit PlayerUnit PlayerUnit PlayerUnit
NPCs NPCs NPCs NPCs
Items Items Inventory Inventory
Objects Objects Objects Objects
AdjacentLevels []Level AdjacentLevels []Level
Rooms []Room Rooms []Room
@@ -163,8 +163,8 @@ func (pu PlayerUnit) MaxGold() int {
return goldPerLevel * lvl.Value return goldPerLevel * lvl.Value
} }
// TotalGold returns the amount of gold, including inventory and stash // TotalPlayerGold returns the amount of gold, including inventory and player stash (excluding shared stash)
func (pu PlayerUnit) TotalGold() int { func (pu PlayerUnit) TotalPlayerGold() int {
gold, _ := pu.FindStat(stat.Gold, 0) gold, _ := pu.FindStat(stat.Gold, 0)
stashGold, _ := pu.FindStat(stat.StashGold, 0) stashGold, _ := pu.FindStat(stat.StashGold, 0)

View File

@@ -7,12 +7,14 @@ import (
"github.com/hectorgimenez/d2go/pkg/data/stat" "github.com/hectorgimenez/d2go/pkg/data/stat"
) )
type Items struct { type Inventory struct {
Belt Belt Belt Belt
AllItems []Item AllItems []Item
Gold int
StashedGold [4]int
} }
func (i Items) Find(name item.Name, locations ...item.Location) (Item, bool) { func (i Inventory) Find(name item.Name, locations ...item.Location) (Item, bool) {
for _, it := range i.AllItems { for _, it := range i.AllItems {
if strings.EqualFold(string(it.Name), string(name)) { if strings.EqualFold(string(it.Name), string(name)) {
// If no locations are specified, return the first item found // If no locations are specified, return the first item found
@@ -31,7 +33,7 @@ func (i Items) Find(name item.Name, locations ...item.Location) (Item, bool) {
return Item{}, false return Item{}, false
} }
func (i Items) ByLocation(locations ...item.Location) []Item { func (i Inventory) ByLocation(locations ...item.Location) []Item {
var items []Item var items []Item
for _, it := range i.AllItems { for _, it := range i.AllItems {
@@ -75,19 +77,19 @@ func (i Item) IsPotion() bool {
} }
func (i Item) IsHealingPotion() bool { func (i Item) IsHealingPotion() bool {
return strings.Contains(string(i.Name), string(HealingPotion)) return i.Type().IsType(item.TypeHealingPotion)
} }
func (i Item) IsManaPotion() bool { func (i Item) IsManaPotion() bool {
return strings.Contains(string(i.Name), string(ManaPotion)) return i.Type().IsType(item.TypeManaPotion)
} }
func (i Item) IsRejuvPotion() bool { func (i Item) IsRejuvPotion() bool {
return strings.Contains(string(i.Name), string(RejuvenationPotion)) return i.Type().IsType(item.TypeRejuvPotion)
} }
func (i Item) IsFromQuest() bool { func (i Item) IsFromQuest() bool {
return i.Desc().Type == item.TypeQuest return i.Type().IsType(item.TypeQuest)
} }
func (i Item) FindStat(id stat.ID, layer int) (stat.Data, bool) { func (i Item) FindStat(id stat.ID, layer int) (stat.Data, bool) {

View File

@@ -49,7 +49,7 @@ func (gd *GameReader) GetData() data.Data {
}, },
Monsters: gd.Monsters(pu.Position, hover), Monsters: gd.Monsters(pu.Position, hover),
PlayerUnit: pu, PlayerUnit: pu,
Items: gd.Items(rawPlayerUnits, hover), Inventory: gd.Inventory(rawPlayerUnits, hover),
Objects: gd.Objects(pu.Position, hover), Objects: gd.Objects(pu.Position, hover),
OpenMenus: gd.openMenus(), OpenMenus: gd.openMenus(),
Roster: roster, Roster: roster,

View File

@@ -11,7 +11,7 @@ import (
"github.com/hectorgimenez/d2go/pkg/utils" "github.com/hectorgimenez/d2go/pkg/utils"
) )
func (gd *GameReader) Items(rawPlayerUnits RawPlayerUnits, hover data.HoverData) data.Items { func (gd *GameReader) Inventory(rawPlayerUnits RawPlayerUnits, hover data.HoverData) data.Inventory {
mainPlayer := rawPlayerUnits.GetMainPlayer() mainPlayer := rawPlayerUnits.GetMainPlayer()
baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + (4 * 1024) baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + (4 * 1024)
unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8) unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8)
@@ -27,7 +27,20 @@ func (gd *GameReader) Items(rawPlayerUnits RawPlayerUnits, hover data.HoverData)
} }
slices.Sort(stashPlayerUnitOrder) slices.Sort(stashPlayerUnitOrder)
items := data.Items{} // Gold
inventoryGold, _ := mainPlayer.BaseStats.FindStat(stat.Gold, 0)
mainPlayerStashedGold, _ := mainPlayer.BaseStats.FindStat(stat.StashGold, 0)
stashedGold := [4]int{}
stashedGold[0] = mainPlayerStashedGold.Value
for i, puKey := range stashPlayerUnitOrder {
stashGold, _ := stashPlayerUnits[puKey].BaseStats.FindStat(stat.StashGold, 0)
stashedGold[i+1] = stashGold.Value
}
inventory := data.Inventory{
Gold: inventoryGold.Value,
StashedGold: stashedGold,
}
belt := data.Belt{} belt := data.Belt{}
for i := 0; i < 128; i++ { for i := 0; i < 128; i++ {
itemOffset := 8 * i itemOffset := 8 * i
@@ -122,7 +135,7 @@ func (gd *GameReader) Items(rawPlayerUnits RawPlayerUnits, hover data.HoverData)
itm.Location = location itm.Location = location
// We don't care about the items we don't know where they are, probably previous games or random crap // We don't care about the inventory we don't know where they are, probably previous games or random crap
if location != item.LocationUnknown { if location != item.LocationUnknown {
// Item Stats // Item Stats
statsListExPtr := uintptr(ReadUIntFromBuffer(itemDataBuffer, 0x88, Uint64)) statsListExPtr := uintptr(ReadUIntFromBuffer(itemDataBuffer, 0x88, Uint64))
@@ -133,7 +146,7 @@ func (gd *GameReader) Items(rawPlayerUnits RawPlayerUnits, hover data.HoverData)
if location == item.LocationBelt { if location == item.LocationBelt {
belt.Items = append(belt.Items, itm) belt.Items = append(belt.Items, itm)
} else { } else {
items.AllItems = append(items.AllItems, itm) inventory.AllItems = append(inventory.AllItems, itm)
} }
} }
@@ -141,16 +154,16 @@ func (gd *GameReader) Items(rawPlayerUnits RawPlayerUnits, hover data.HoverData)
} }
} }
items.Belt = belt inventory.Belt = belt
sort.SliceStable(items.AllItems, func(i, j int) bool { sort.SliceStable(inventory.AllItems, func(i, j int) bool {
distanceI := utils.DistanceFromPoint(mainPlayer.Position, items.AllItems[i].Position) distanceI := utils.DistanceFromPoint(mainPlayer.Position, inventory.AllItems[i].Position)
distanceJ := utils.DistanceFromPoint(mainPlayer.Position, items.AllItems[j].Position) distanceJ := utils.DistanceFromPoint(mainPlayer.Position, inventory.AllItems[j].Position)
return distanceI < distanceJ return distanceI < distanceJ
}) })
return items return inventory
} }
func (gd *GameReader) getItemStats(statsListExPtr uintptr) (stat.Stats, stat.Stats) { func (gd *GameReader) getItemStats(statsListExPtr uintptr) (stat.Stats, stat.Stats) {

View File

@@ -43,6 +43,8 @@ func (gd *GameReader) GetRawPlayerUnits() RawPlayerUnits {
isCorpse := gd.Process.ReadUInt(playerUnit+0x1A6, Uint8) isCorpse := gd.Process.ReadUInt(playerUnit+0x1A6, Uint8)
statsListExPtr := uintptr(gd.Process.ReadUInt(playerUnit+0x88, Uint64)) statsListExPtr := uintptr(gd.Process.ReadUInt(playerUnit+0x88, Uint64))
baseStats := gd.getStatsList(statsListExPtr + 0x30)
stats := gd.getStatsList(statsListExPtr + 0x88)
states := gd.getStates(statsListExPtr) states := gd.getStates(statsListExPtr)
rawPlayerUnits = append(rawPlayerUnits, RawPlayerUnit{ rawPlayerUnits = append(rawPlayerUnits, RawPlayerUnit{
@@ -58,6 +60,8 @@ func (gd *GameReader) GetRawPlayerUnits() RawPlayerUnits {
}, },
IsHovered: hover.IsHovered && hover.UnitID == data.UnitID(unitID) && hover.UnitType == 0, IsHovered: hover.IsHovered && hover.UnitID == data.UnitID(unitID) && hover.UnitType == 0,
States: states, States: states,
Stats: stats,
BaseStats: baseStats,
}) })
playerUnit = uintptr(gd.Process.ReadUInt(playerUnit+0x150, Uint64)) playerUnit = uintptr(gd.Process.ReadUInt(playerUnit+0x150, Uint64))
} }
@@ -67,11 +71,6 @@ func (gd *GameReader) GetRawPlayerUnits() RawPlayerUnits {
} }
func (gd *GameReader) GetPlayerUnit(mainPlayerUnit RawPlayerUnit) data.PlayerUnit { func (gd *GameReader) GetPlayerUnit(mainPlayerUnit RawPlayerUnit) data.PlayerUnit {
// Get Stats
statsListExPtr := uintptr(gd.Process.ReadUInt(mainPlayerUnit.Address+0x88, Uint64))
baseStats := gd.getStatsList(statsListExPtr + 0x30)
stats := gd.getStatsList(statsListExPtr + 0x88)
// Skills // Skills
skillListPtr := uintptr(gd.Process.ReadUInt(mainPlayerUnit.Address+0x100, Uint64)) skillListPtr := uintptr(gd.Process.ReadUInt(mainPlayerUnit.Address+0x100, Uint64))
skills := gd.getSkills(skillListPtr) skills := gd.getSkills(skillListPtr)
@@ -104,8 +103,8 @@ func (gd *GameReader) GetPlayerUnit(mainPlayerUnit RawPlayerUnit) data.PlayerUni
ID: mainPlayerUnit.UnitID, ID: mainPlayerUnit.UnitID,
Area: mainPlayerUnit.Area, Area: mainPlayerUnit.Area,
Position: mainPlayerUnit.Position, Position: mainPlayerUnit.Position,
Stats: stats, Stats: mainPlayerUnit.Stats,
BaseStats: baseStats, BaseStats: mainPlayerUnit.BaseStats,
Skills: skills, Skills: skills,
States: mainPlayerUnit.States, States: mainPlayerUnit.States,
Class: class, Class: class,

View File

@@ -3,6 +3,7 @@ package memory
import ( import (
"github.com/hectorgimenez/d2go/pkg/data" "github.com/hectorgimenez/d2go/pkg/data"
"github.com/hectorgimenez/d2go/pkg/data/area" "github.com/hectorgimenez/d2go/pkg/data/area"
"github.com/hectorgimenez/d2go/pkg/data/stat"
"github.com/hectorgimenez/d2go/pkg/data/state" "github.com/hectorgimenez/d2go/pkg/data/state"
) )
@@ -16,6 +17,8 @@ type RawPlayerUnit struct {
Position data.Position Position data.Position
IsHovered bool IsHovered bool
States state.States States state.States
Stats stat.Stats
BaseStats stat.Stats
} }
type RawPlayerUnits []RawPlayerUnit type RawPlayerUnits []RawPlayerUnit