Item refactor and more (#1)
This commit is contained in:
@@ -2,6 +2,10 @@ package itemwatcher
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/faiface/beep"
|
"github.com/faiface/beep"
|
||||||
"github.com/faiface/beep/speaker"
|
"github.com/faiface/beep/speaker"
|
||||||
"github.com/faiface/beep/wav"
|
"github.com/faiface/beep/wav"
|
||||||
@@ -11,9 +15,6 @@ import (
|
|||||||
"github.com/hectorgimenez/d2go/pkg/itemfilter"
|
"github.com/hectorgimenez/d2go/pkg/itemfilter"
|
||||||
"github.com/hectorgimenez/d2go/pkg/memory"
|
"github.com/hectorgimenez/d2go/pkg/memory"
|
||||||
"github.com/hectorgimenez/d2go/pkg/nip"
|
"github.com/hectorgimenez/d2go/pkg/nip"
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Watcher struct {
|
type Watcher struct {
|
||||||
@@ -53,7 +54,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.Ground {
|
for _, i := range d.Items.ByLocation(item.LocationGround) {
|
||||||
if !itemfilter.Evaluate(i, w.rules) {
|
if !itemfilter.Evaluate(i, w.rules) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -85,7 +86,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.Ground {
|
for _, it := range d.Items.ByLocation(item.LocationGround) {
|
||||||
if t.Match(d.PlayerUnit.Area, it) {
|
if t.Match(d.PlayerUnit.Area, it) {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,23 @@ func (a Area) IsTown() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a Area) Act() int {
|
||||||
|
if a < 40 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if a >= 40 && a < 75 {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if a >= 75 && a < 103 {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
if a >= 103 && a < 109 {
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Abaddon Area = 125
|
Abaddon Area = 125
|
||||||
AncientTunnels Area = 65
|
AncientTunnels Area = 65
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ type Data struct {
|
|||||||
Rooms []Room
|
Rooms []Room
|
||||||
OpenMenus OpenMenus
|
OpenMenus OpenMenus
|
||||||
Roster Roster
|
Roster Roster
|
||||||
|
HoverData HoverData
|
||||||
}
|
}
|
||||||
|
|
||||||
type Room struct {
|
type Room struct {
|
||||||
@@ -48,6 +49,12 @@ type Room struct {
|
|||||||
Height int
|
Height int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HoverData struct {
|
||||||
|
IsHovered bool
|
||||||
|
UnitID
|
||||||
|
UnitType int
|
||||||
|
}
|
||||||
|
|
||||||
func (r Room) GetCenter() Position {
|
func (r Room) GetCenter() Position {
|
||||||
return Position{
|
return Position{
|
||||||
X: r.Position.X + r.Width/2,
|
X: r.Position.X + r.Width/2,
|
||||||
@@ -100,8 +107,7 @@ func (r Roster) FindByName(name string) (RosterMember, bool) {
|
|||||||
type Level struct {
|
type Level struct {
|
||||||
Area area.Area
|
Area area.Area
|
||||||
Position Position
|
Position Position
|
||||||
IsGoodExit bool
|
IsEntrance bool // This means the area can not be accessed just walking through it, needs to be clicked
|
||||||
CanInteract bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Class uint
|
type Class uint
|
||||||
@@ -129,6 +135,7 @@ type Position struct {
|
|||||||
|
|
||||||
type PlayerUnit struct {
|
type PlayerUnit struct {
|
||||||
Name string
|
Name string
|
||||||
|
ID UnitID
|
||||||
Area area.Area
|
Area area.Area
|
||||||
Position Position
|
Position Position
|
||||||
Stats map[stat.ID]int
|
Stats map[stat.ID]int
|
||||||
@@ -226,4 +233,5 @@ type OpenMenus struct {
|
|||||||
QuitMenu bool
|
QuitMenu bool
|
||||||
Cube bool
|
Cube bool
|
||||||
SkillSelect bool
|
SkillSelect bool
|
||||||
|
Anvil bool
|
||||||
}
|
}
|
||||||
|
|||||||
18
pkg/data/item/location.go
Normal file
18
pkg/data/item/location.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package item
|
||||||
|
|
||||||
|
type Location string
|
||||||
|
|
||||||
|
const (
|
||||||
|
LocationEquipped Location = "equipped"
|
||||||
|
LocationStash Location = "stash"
|
||||||
|
LocationSharedStash1 Location = "shared_stash_1"
|
||||||
|
LocationSharedStash2 Location = "shared_stash_2"
|
||||||
|
LocationSharedStash3 Location = "shared_stash_3"
|
||||||
|
LocationBelt Location = "belt"
|
||||||
|
LocationInventory Location = "inventory"
|
||||||
|
LocationCube Location = "cube"
|
||||||
|
LocationVendor Location = "vendor"
|
||||||
|
LocationGround Location = "ground"
|
||||||
|
LocationSocket Location = "socket"
|
||||||
|
LocationUnknown Location = "unknown"
|
||||||
|
)
|
||||||
@@ -41,6 +41,26 @@ var typeMapping = map[string][]string{
|
|||||||
"voodooheads": {"PreservedHead", "ZombieHead", "UnravellerHead", "GargoyleHead", "DemonHeadShield", "MummifiedTrophy", "FetishTrophy", "SextonTrophy", "CantorTrophy", "HierophantTrophy", "MinionSkull", "HellspawnSkull", "OverseerSkull", "SuccubusSkull", "BloodlordSkull"},
|
"voodooheads": {"PreservedHead", "ZombieHead", "UnravellerHead", "GargoyleHead", "DemonHeadShield", "MummifiedTrophy", "FetishTrophy", "SextonTrophy", "CantorTrophy", "HierophantTrophy", "MinionSkull", "HellspawnSkull", "OverseerSkull", "SuccubusSkull", "BloodlordSkull"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var QuestItems = []string{
|
||||||
|
"TheGidbinn",
|
||||||
|
"WirtsLeg",
|
||||||
|
"HoradricMalus",
|
||||||
|
"HellforgeHammer",
|
||||||
|
"HoradricStaff",
|
||||||
|
"StaffOfKings",
|
||||||
|
"KhalimsFlail",
|
||||||
|
"AmuletOfTheViper",
|
||||||
|
"KhalimsEye",
|
||||||
|
"KhalimsHeart",
|
||||||
|
"KhalimsBrain",
|
||||||
|
"KhalimsWill",
|
||||||
|
"ScrollOfInifuss",
|
||||||
|
"HoradricCube",
|
||||||
|
"HoradricScroll",
|
||||||
|
"MephistosSoulstone",
|
||||||
|
"BookOfSkill",
|
||||||
|
}
|
||||||
|
|
||||||
func TypeForItemName(itemName string) (string, bool) {
|
func TypeForItemName(itemName string) (string, bool) {
|
||||||
for t, itemNames := range typeMapping {
|
for t, itemNames := range typeMapping {
|
||||||
for _, name := range itemNames {
|
for _, name := range itemNames {
|
||||||
|
|||||||
@@ -9,13 +9,42 @@ import (
|
|||||||
|
|
||||||
type Items struct {
|
type Items struct {
|
||||||
Belt Belt
|
Belt Belt
|
||||||
Inventory Inventory
|
AllItems []Item
|
||||||
Shop []Item
|
}
|
||||||
Ground []Item
|
|
||||||
Equipped []Item
|
func (i Items) Find(name item.Name, locations ...item.Location) (Item, bool) {
|
||||||
|
for _, it := range i.AllItems {
|
||||||
|
if strings.EqualFold(string(it.Name), string(name)) {
|
||||||
|
// If no locations are specified, return the first item found
|
||||||
|
if len(locations) == 0 {
|
||||||
|
return it, true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range locations {
|
||||||
|
if it.Location == l {
|
||||||
|
return it, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Item{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Items) ByLocation(locations ...item.Location) []Item {
|
||||||
|
var items []Item
|
||||||
|
|
||||||
|
for _, it := range i.AllItems {
|
||||||
|
for _, l := range locations {
|
||||||
|
if it.Location == l {
|
||||||
|
items = append(items, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
type Inventory []Item
|
|
||||||
type UnitID int
|
type UnitID int
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
@@ -23,11 +52,11 @@ type Item struct {
|
|||||||
Name item.Name
|
Name item.Name
|
||||||
Quality item.Quality
|
Quality item.Quality
|
||||||
Position Position
|
Position Position
|
||||||
|
Location item.Location
|
||||||
Ethereal bool
|
Ethereal bool
|
||||||
IsHovered bool
|
IsHovered bool
|
||||||
Stats map[stat.ID]stat.Data
|
Stats map[stat.ID]stat.Data
|
||||||
Identified bool
|
Identified bool
|
||||||
IsVendor bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) Type() string {
|
func (i Item) Type() string {
|
||||||
@@ -47,6 +76,17 @@ func (i Item) IsHealingPotion() bool {
|
|||||||
func (i Item) IsManaPotion() bool {
|
func (i Item) IsManaPotion() bool {
|
||||||
return strings.Contains(string(i.Name), string(ManaPotion))
|
return strings.Contains(string(i.Name), string(ManaPotion))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) IsRejuvPotion() bool {
|
func (i Item) IsRejuvPotion() bool {
|
||||||
return strings.Contains(string(i.Name), string(RejuvenationPotion))
|
return strings.Contains(string(i.Name), string(RejuvenationPotion))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i Item) IsFromQuest() bool {
|
||||||
|
for _, q := range item.QuestItems {
|
||||||
|
if strings.EqualFold(string(i.Name), q) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (m Monsters) FindOne(id npc.ID, t MonsterType) (Monster, bool) {
|
|||||||
func (m Monsters) Enemies(filters ...MonsterFilter) []Monster {
|
func (m Monsters) Enemies(filters ...MonsterFilter) []Monster {
|
||||||
monsters := make([]Monster, 0)
|
monsters := make([]Monster, 0)
|
||||||
for _, mo := range m {
|
for _, mo := range m {
|
||||||
if !mo.IsMerc() && !mo.IsGoodNPC() {
|
if !mo.IsMerc() && !mo.IsGoodNPC() && mo.Stats[stat.Life] > 0 {
|
||||||
monsters = append(monsters, mo)
|
monsters = append(monsters, mo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ func (o Object) IsWaypoint() bool {
|
|||||||
object.Act2Waypoint,
|
object.Act2Waypoint,
|
||||||
object.Act3TownWaypoint,
|
object.Act3TownWaypoint,
|
||||||
object.PandamoniumFortressWaypoint,
|
object.PandamoniumFortressWaypoint,
|
||||||
|
object.Act2CellerWaypoint,
|
||||||
|
object.Act2SewerWaypoint,
|
||||||
|
object.Act3TravincalWaypoint,
|
||||||
|
object.ValleyWaypoint,
|
||||||
|
object.WorldstoneWaypoint,
|
||||||
|
object.ExpansionWildernessWaypoint,
|
||||||
|
object.IceCaveWaypoint,
|
||||||
|
object.TempleWaypoint,
|
||||||
|
object.InnerHellWaypoint,
|
||||||
|
object.WaypointH,
|
||||||
object.ExpansionWaypoint:
|
object.ExpansionWaypoint:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -85,7 +95,8 @@ func (o Object) IsDoor() bool {
|
|||||||
object.AndarielDoor,
|
object.AndarielDoor,
|
||||||
object.PenBreakableDoor,
|
object.PenBreakableDoor,
|
||||||
object.ArreatSummitDoorToWorldstone,
|
object.ArreatSummitDoorToWorldstone,
|
||||||
object.SecretDoor1:
|
object.SecretDoor1,
|
||||||
|
object.ExpansionTownGate:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,15 +28,17 @@ func (gd *GameReader) GetData() data.Data {
|
|||||||
playerUnitPtr, corpse := gd.GetPlayerUnitPtr(roster)
|
playerUnitPtr, corpse := gd.GetPlayerUnitPtr(roster)
|
||||||
|
|
||||||
pu := gd.GetPlayerUnit(playerUnitPtr)
|
pu := gd.GetPlayerUnit(playerUnitPtr)
|
||||||
|
hover := gd.hoveredData()
|
||||||
|
|
||||||
d := data.Data{
|
d := data.Data{
|
||||||
Corpse: corpse,
|
Corpse: corpse,
|
||||||
Monsters: gd.Monsters(pu.Position),
|
Monsters: gd.Monsters(pu.Position, hover),
|
||||||
PlayerUnit: pu,
|
PlayerUnit: pu,
|
||||||
Items: gd.Items(pu.Position),
|
Items: gd.Items(pu, hover),
|
||||||
Objects: gd.Objects(pu.Position),
|
Objects: gd.Objects(pu.Position, hover),
|
||||||
OpenMenus: gd.openMenus(),
|
OpenMenus: gd.openMenus(),
|
||||||
Roster: roster,
|
Roster: roster,
|
||||||
|
HoverData: hover,
|
||||||
}
|
}
|
||||||
|
|
||||||
if playerUnitPtr == 0 {
|
if playerUnitPtr == 0 {
|
||||||
@@ -74,21 +76,26 @@ func (gd *GameReader) openMenus() data.OpenMenus {
|
|||||||
QuitMenu: buffer[0x09] != 0,
|
QuitMenu: buffer[0x09] != 0,
|
||||||
Cube: buffer[0x19] != 0,
|
Cube: buffer[0x19] != 0,
|
||||||
SkillSelect: buffer[0x03] != 0,
|
SkillSelect: buffer[0x03] != 0,
|
||||||
|
Anvil: buffer[0x0D] != 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gd *GameReader) hoveredData() (hoveredUnitID uint, hoveredType uint, isHovered bool) {
|
func (gd *GameReader) hoveredData() data.HoverData {
|
||||||
hoverAddressPtr := gd.Process.moduleBaseAddressPtr + gd.offset.Hover
|
hoverAddressPtr := gd.Process.moduleBaseAddressPtr + gd.offset.Hover
|
||||||
hoverBuffer := gd.Process.ReadBytesFromMemory(hoverAddressPtr, 12)
|
hoverBuffer := gd.Process.ReadBytesFromMemory(hoverAddressPtr, 12)
|
||||||
isUnitHovered := ReadUIntFromBuffer(hoverBuffer, 0, Uint16)
|
isUnitHovered := ReadUIntFromBuffer(hoverBuffer, 0, Uint16)
|
||||||
if isUnitHovered > 0 {
|
if isUnitHovered > 0 {
|
||||||
hoveredType = ReadUIntFromBuffer(hoverBuffer, 0x04, Uint32)
|
hoveredType := ReadUIntFromBuffer(hoverBuffer, 0x04, Uint32)
|
||||||
hoveredUnitID = ReadUIntFromBuffer(hoverBuffer, 0x08, Uint32)
|
hoveredUnitID := ReadUIntFromBuffer(hoverBuffer, 0x08, Uint32)
|
||||||
|
|
||||||
return hoveredUnitID, hoveredType, true
|
return data.HoverData{
|
||||||
|
IsHovered: true,
|
||||||
|
UnitID: data.UnitID(hoveredUnitID),
|
||||||
|
UnitType: int(hoveredType),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, 0, false
|
return data.HoverData{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gd *GameReader) getStatsData(statCount uint, statPtr uintptr) []stat.Data {
|
func (gd *GameReader) getStatsData(statCount uint, statPtr uintptr) []stat.Data {
|
||||||
@@ -124,15 +131,3 @@ func (gd *GameReader) getStatsData(statCount uint, statPtr uintptr) []stat.Data
|
|||||||
|
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
func setProperties(item *data.Item, flags uint32) {
|
|
||||||
if 0x00400000&flags != 0 {
|
|
||||||
item.Ethereal = true
|
|
||||||
}
|
|
||||||
if 0x00000010&flags != 0 {
|
|
||||||
item.Identified = true
|
|
||||||
}
|
|
||||||
if 0x00002000&flags != 0 {
|
|
||||||
item.IsVendor = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import (
|
|||||||
"github.com/hectorgimenez/d2go/pkg/utils"
|
"github.com/hectorgimenez/d2go/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (gd *GameReader) Items(playerPosition data.Position) data.Items {
|
func (gd *GameReader) Items(pu data.PlayerUnit, hover data.HoverData) data.Items {
|
||||||
hoveredUnitID, hoveredType, isHovered := gd.hoveredData()
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
@@ -38,7 +36,7 @@ func (gd *GameReader) Items(playerPosition data.Position) data.Items {
|
|||||||
flags := ReadUIntFromBuffer(unitDataBuffer, 0x18, Uint32)
|
flags := ReadUIntFromBuffer(unitDataBuffer, 0x18, Uint32)
|
||||||
invPage := ReadUIntFromBuffer(unitDataBuffer, 0x55, Uint8)
|
invPage := ReadUIntFromBuffer(unitDataBuffer, 0x55, Uint8)
|
||||||
itemQuality := ReadUIntFromBuffer(unitDataBuffer, 0x00, Uint32)
|
itemQuality := ReadUIntFromBuffer(unitDataBuffer, 0x00, Uint32)
|
||||||
//itemOwnerNPC := ReadUIntFromBuffer(unitDataBuffer, 0x0C, Uint32)
|
itemOwnerNPC := ReadUIntFromBuffer(unitDataBuffer, 0x0C, Uint32)
|
||||||
|
|
||||||
// Item coordinates (X, Y)
|
// Item coordinates (X, Y)
|
||||||
pathPtr := uintptr(ReadUIntFromBuffer(itemDataBuffer, 0x38, Uint64))
|
pathPtr := uintptr(ReadUIntFromBuffer(itemDataBuffer, 0x38, Uint64))
|
||||||
@@ -58,7 +56,7 @@ func (gd *GameReader) Items(playerPosition data.Position) data.Items {
|
|||||||
|
|
||||||
name := item.GetNameByEnum(txtFileNo)
|
name := item.GetNameByEnum(txtFileNo)
|
||||||
itemHovered := false
|
itemHovered := false
|
||||||
if isHovered && hoveredType == 4 && hoveredUnitID == unitID {
|
if hover.IsHovered && hover.UnitType == 4 && hover.UnitID == data.UnitID(unitID) {
|
||||||
itemHovered = true
|
itemHovered = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,22 +73,53 @@ func (gd *GameReader) Items(playerPosition data.Position) data.Items {
|
|||||||
}
|
}
|
||||||
setProperties(&itm, uint32(flags))
|
setProperties(&itm, uint32(flags))
|
||||||
|
|
||||||
|
location := item.LocationUnknown
|
||||||
switch itemLoc {
|
switch itemLoc {
|
||||||
case 0:
|
case 0:
|
||||||
if itm.IsVendor {
|
if 0x00002000&flags != 0 {
|
||||||
items.Shop = append(items.Shop, itm)
|
location = item.LocationVendor
|
||||||
|
break
|
||||||
} else if invPage == 0 {
|
} else if invPage == 0 {
|
||||||
items.Inventory = append(items.Inventory, itm)
|
location = item.LocationInventory
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if data.UnitID(itemOwnerNPC) == pu.ID || itemOwnerNPC == 1 {
|
||||||
|
location = item.LocationStash
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offline only
|
||||||
|
if itemOwnerNPC == 2 {
|
||||||
|
location = item.LocationSharedStash1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if itemOwnerNPC == 3 {
|
||||||
|
location = item.LocationSharedStash2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if itemOwnerNPC == 4 {
|
||||||
|
location = item.LocationSharedStash3
|
||||||
|
break
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
items.Equipped = append(items.Equipped, itm)
|
location = item.LocationEquipped
|
||||||
if itm.Type() == "belt" {
|
if itm.Type() == "belt" {
|
||||||
belt.Name = itm.Name
|
belt.Name = itm.Name
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
belt.Items = append(belt.Items, itm)
|
location = item.LocationBelt
|
||||||
case 3, 5:
|
case 3, 5:
|
||||||
items.Ground = append(items.Ground, itm)
|
location = item.LocationGround
|
||||||
|
case 6:
|
||||||
|
location = item.LocationSocket
|
||||||
|
}
|
||||||
|
|
||||||
|
itm.Location = location
|
||||||
|
|
||||||
|
if location == item.LocationBelt {
|
||||||
|
belt.Items = append(belt.Items, itm)
|
||||||
|
} else {
|
||||||
|
items.AllItems = append(items.AllItems, itm)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemUnitPtr = uintptr(gd.Process.ReadUInt(itemUnitPtr+0x150, Uint64))
|
itemUnitPtr = uintptr(gd.Process.ReadUInt(itemUnitPtr+0x150, Uint64))
|
||||||
@@ -99,9 +128,9 @@ func (gd *GameReader) Items(playerPosition data.Position) data.Items {
|
|||||||
|
|
||||||
items.Belt = belt
|
items.Belt = belt
|
||||||
|
|
||||||
sort.SliceStable(items.Ground, func(i, j int) bool {
|
sort.SliceStable(items.AllItems, func(i, j int) bool {
|
||||||
distanceI := utils.DistanceFromPoint(playerPosition, items.Ground[i].Position)
|
distanceI := utils.DistanceFromPoint(pu.Position, items.AllItems[i].Position)
|
||||||
distanceJ := utils.DistanceFromPoint(playerPosition, items.Ground[j].Position)
|
distanceJ := utils.DistanceFromPoint(pu.Position, items.AllItems[j].Position)
|
||||||
|
|
||||||
return distanceI < distanceJ
|
return distanceI < distanceJ
|
||||||
})
|
})
|
||||||
@@ -127,3 +156,12 @@ func (gd *GameReader) getItemStats(statCount uint, statPtr uintptr, statExCount
|
|||||||
|
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setProperties(item *data.Item, flags uint32) {
|
||||||
|
if 0x00400000&flags != 0 {
|
||||||
|
item.Ethereal = true
|
||||||
|
}
|
||||||
|
if 0x00000010&flags != 0 {
|
||||||
|
item.Identified = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
package memory
|
package memory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/hectorgimenez/d2go/pkg/data"
|
"github.com/hectorgimenez/d2go/pkg/data"
|
||||||
"github.com/hectorgimenez/d2go/pkg/data/npc"
|
"github.com/hectorgimenez/d2go/pkg/data/npc"
|
||||||
"github.com/hectorgimenez/d2go/pkg/data/stat"
|
"github.com/hectorgimenez/d2go/pkg/data/stat"
|
||||||
"github.com/hectorgimenez/d2go/pkg/utils"
|
"github.com/hectorgimenez/d2go/pkg/utils"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (gd *GameReader) Monsters(playerPosition data.Position) data.Monsters {
|
func (gd *GameReader) Monsters(playerPosition data.Position, hover data.HoverData) data.Monsters {
|
||||||
hoveredUnitID, hoveredType, isHovered := gd.hoveredData()
|
|
||||||
|
|
||||||
baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + 1024
|
baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + 1024
|
||||||
unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8)
|
unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8)
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ func (gd *GameReader) Monsters(playerPosition data.Position) data.Monsters {
|
|||||||
posY := gd.Process.ReadUInt(pathPtr+0x06, Uint16)
|
posY := gd.Process.ReadUInt(pathPtr+0x06, Uint16)
|
||||||
|
|
||||||
hovered := false
|
hovered := false
|
||||||
if isHovered && hoveredType == 1 && hoveredUnitID == unitID {
|
if hover.IsHovered && hover.UnitType == 1 && hover.UnitID == data.UnitID(unitID) {
|
||||||
hovered = true
|
hovered = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package memory
|
package memory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/hectorgimenez/d2go/pkg/data"
|
"github.com/hectorgimenez/d2go/pkg/data"
|
||||||
"github.com/hectorgimenez/d2go/pkg/data/object"
|
"github.com/hectorgimenez/d2go/pkg/data/object"
|
||||||
"github.com/hectorgimenez/d2go/pkg/utils"
|
"github.com/hectorgimenez/d2go/pkg/utils"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (gd *GameReader) Objects(playerPosition data.Position) []data.Object {
|
func (gd *GameReader) Objects(playerPosition data.Position, hover data.HoverData) []data.Object {
|
||||||
hoveredUnitID, hoveredType, isHovered := gd.hoveredData()
|
|
||||||
|
|
||||||
baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + (2 * 1024)
|
baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + (2 * 1024)
|
||||||
unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8)
|
unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8)
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ func (gd *GameReader) Objects(playerPosition data.Position) []data.Object {
|
|||||||
|
|
||||||
obj := data.Object{
|
obj := data.Object{
|
||||||
Name: object.Name(int(txtFileNo)),
|
Name: object.Name(int(txtFileNo)),
|
||||||
IsHovered: unitID == hoveredUnitID && hoveredType == 2 && isHovered,
|
IsHovered: data.UnitID(unitID) == hover.UnitID && hover.UnitType == 2 && hover.IsHovered,
|
||||||
InteractType: object.InteractType(interactType),
|
InteractType: object.InteractType(interactType),
|
||||||
Selectable: mode == 0,
|
Selectable: mode == 0,
|
||||||
Position: data.Position{
|
Position: data.Position{
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ func (gd *GameReader) GetPlayerUnitPtr(roster data.Roster) (playerUnitPtr uintpt
|
|||||||
isCorpse := gd.Process.ReadUInt(playerUnit+0x1A6, Uint8)
|
isCorpse := gd.Process.ReadUInt(playerUnit+0x1A6, Uint8)
|
||||||
if isCorpse == 1 {
|
if isCorpse == 1 {
|
||||||
unitID := gd.Process.ReadUInt(playerUnit+0x08, Uint32)
|
unitID := gd.Process.ReadUInt(playerUnit+0x08, Uint32)
|
||||||
hoveredUnitID, hoveredType, isHovered := gd.hoveredData()
|
hover := gd.hoveredData()
|
||||||
corpse = data.Corpse{
|
corpse = data.Corpse{
|
||||||
Found: true,
|
Found: true,
|
||||||
IsHovered: isHovered && hoveredUnitID == unitID && hoveredType == 0,
|
IsHovered: hover.IsHovered && hover.UnitID == data.UnitID(unitID) && hover.UnitType == 0,
|
||||||
Position: data.Position{
|
Position: data.Position{
|
||||||
X: int(xPos),
|
X: int(xPos),
|
||||||
Y: int(yPos),
|
Y: int(yPos),
|
||||||
@@ -76,6 +76,8 @@ func (gd *GameReader) GetPlayerUnitPtr(roster data.Roster) (playerUnitPtr uintpt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gd *GameReader) GetPlayerUnit(playerUnit uintptr) data.PlayerUnit {
|
func (gd *GameReader) GetPlayerUnit(playerUnit uintptr) data.PlayerUnit {
|
||||||
|
unitID := gd.Process.ReadUInt(playerUnit+0x08, Uint32)
|
||||||
|
|
||||||
// Read X and Y Positions
|
// Read X and Y Positions
|
||||||
pPath := playerUnit + 0x38
|
pPath := playerUnit + 0x38
|
||||||
pathAddress := uintptr(gd.Process.ReadUInt(pPath, Uint64))
|
pathAddress := uintptr(gd.Process.ReadUInt(pPath, Uint64))
|
||||||
@@ -127,6 +129,7 @@ func (gd *GameReader) GetPlayerUnit(playerUnit uintptr) data.PlayerUnit {
|
|||||||
|
|
||||||
return data.PlayerUnit{
|
return data.PlayerUnit{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
ID: data.UnitID(unitID),
|
||||||
Area: area.Area(levelNo),
|
Area: area.Area(levelNo),
|
||||||
Position: data.Position{
|
Position: data.Position{
|
||||||
X: int(xPos),
|
X: int(xPos),
|
||||||
|
|||||||
Reference in New Issue
Block a user