get base stats and stats from player and fetch life/mana from stats instead of base stats

This commit is contained in:
Héctor Giménez
2024-05-02 19:13:14 +09:00
parent 345e37bbf9
commit 0d5c108721
3 changed files with 29 additions and 55 deletions

View File

@@ -1,40 +1,16 @@
package data package data
import ( import (
"github.com/hectorgimenez/d2go/pkg/data/quest"
"strings" "strings"
"github.com/hectorgimenez/d2go/pkg/data/quest"
"github.com/hectorgimenez/d2go/pkg/data/area" "github.com/hectorgimenez/d2go/pkg/data/area"
"github.com/hectorgimenez/d2go/pkg/data/skill" "github.com/hectorgimenez/d2go/pkg/data/skill"
"github.com/hectorgimenez/d2go/pkg/data/stat" "github.com/hectorgimenez/d2go/pkg/data/stat"
"github.com/hectorgimenez/d2go/pkg/data/state" "github.com/hectorgimenez/d2go/pkg/data/state"
) )
// since stat.MaxLife is returning max life without stats, we are setting the max life value that we read from the
// game memory, overwriting this value each time it increases. It's not a good solution but it will provide
// more accurate values for the life %. This value is checked for each memory iteration.
type PointCounter struct {
MaxPoint int
MaxPointBo int
}
func (pc *PointCounter) Percent(point int, maxPoint int, hasBo bool) int {
if pc.MaxPoint == 0 && pc.MaxPointBo == 0 {
pc.MaxPoint = maxPoint
pc.MaxPointBo = maxPoint
}
if hasBo {
if pc.MaxPointBo < point {
pc.MaxPointBo = point
}
return int((float64(point) / float64(pc.MaxPointBo)) * 100)
}
if pc.MaxPoint < point {
pc.MaxPoint = point
}
return int((float64(point) / float64(pc.MaxPoint)) * 100)
}
const ( const (
goldPerLevel = 10000 goldPerLevel = 10000
@@ -162,14 +138,13 @@ type PlayerUnit struct {
Area area.ID Area area.ID
Position Position Position Position
Stats map[stat.ID]int Stats map[stat.ID]int
BaseStats map[stat.ID]int
Skills map[skill.ID]skill.Points Skills map[skill.ID]skill.Points
States state.States States state.States
Class Class Class Class
LeftSkill skill.ID LeftSkill skill.ID
RightSkill skill.ID RightSkill skill.ID
AvailableWaypoints []area.ID // Is only filled when WP menu is open and only for the specific selected tab AvailableWaypoints []area.ID // Is only filled when WP menu is open and only for the specific selected tab
MaxHPValue *PointCounter
MaxMPValue *PointCounter
} }
func (pu PlayerUnit) MaxGold() int { func (pu PlayerUnit) MaxGold() int {
@@ -182,19 +157,11 @@ func (pu PlayerUnit) TotalGold() int {
} }
func (pu PlayerUnit) HPPercent() int { func (pu PlayerUnit) HPPercent() int {
_, found := pu.Stats[stat.MaxLife] return int((float64(pu.Stats[stat.Life]) / float64(pu.Stats[stat.MaxLife])) * 100)
if !found {
return 100
}
return pu.MaxHPValue.Percent(pu.Stats[stat.Life], pu.Stats[stat.MaxLife], pu.States.HasState(state.Battleorders))
} }
func (pu PlayerUnit) MPPercent() int { func (pu PlayerUnit) MPPercent() int {
_, found := pu.Stats[stat.MaxMana] return int((float64(pu.Stats[stat.Mana]) / float64(pu.Stats[stat.MaxMana])) * 100)
if !found {
return 100
}
return pu.MaxMPValue.Percent(pu.Stats[stat.Mana], pu.Stats[stat.MaxMana], pu.States.HasState(state.Battleorders))
} }
func (pu PlayerUnit) HasDebuff() bool { func (pu PlayerUnit) HasDebuff() bool {

View File

@@ -26,7 +26,7 @@ func (gd *GameReader) GetData() data.Data {
roster := gd.getRoster() roster := gd.getRoster()
playerUnitPtr, corpse := gd.GetPlayerUnitPtr(roster) playerUnitPtr, corpse := gd.GetPlayerUnitPtr(roster)
pu := gd.GetPlayerUnit(playerUnitPtr, gd.previousRead.PlayerUnit.MaxHPValue, gd.previousRead.PlayerUnit.MaxMPValue) pu := gd.GetPlayerUnit(playerUnitPtr)
hover := gd.hoveredData() hover := gd.hoveredData()
// Quests // Quests

View File

@@ -2,6 +2,7 @@ package memory
import ( import (
"encoding/binary" "encoding/binary"
"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/skill" "github.com/hectorgimenez/d2go/pkg/data/skill"
@@ -76,14 +77,7 @@ func (gd *GameReader) GetPlayerUnitPtr(roster data.Roster) (playerUnitPtr uintpt
return return
} }
func (gd *GameReader) GetPlayerUnit(playerUnit uintptr, previousHP, previousMP *data.PointCounter) data.PlayerUnit { func (gd *GameReader) GetPlayerUnit(playerUnit uintptr) data.PlayerUnit {
if previousHP == nil {
previousHP = &data.PointCounter{}
}
if previousMP == nil {
previousMP = &data.PointCounter{}
}
unitID := gd.Process.ReadUInt(playerUnit+0x08, Uint32) unitID := gd.Process.ReadUInt(playerUnit+0x08, Uint32)
// Read X and Y Positions // Read X and Y Positions
@@ -99,8 +93,10 @@ func (gd *GameReader) GetPlayerUnit(playerUnit uintptr, previousHP, previousMP *
// Get Stats // Get Stats
statsListExPtr := uintptr(gd.Process.ReadUInt(playerUnit+0x88, Uint64)) statsListExPtr := uintptr(gd.Process.ReadUInt(playerUnit+0x88, Uint64))
statPtr := gd.Process.ReadUInt(statsListExPtr+0x30, Uint64) baseStatPtr := gd.Process.ReadUInt(statsListExPtr+0x30, Uint64)
statCount := gd.Process.ReadUInt(statsListExPtr+0x38, Uint64) baseStatsCount := gd.Process.ReadUInt(statsListExPtr+0x38, Uint64)
statPtr := gd.Process.ReadUInt(statsListExPtr+0x88, Uint64)
statCount := gd.Process.ReadUInt(statsListExPtr+0x90, Uint64)
stats := map[stat.ID]int{} stats := map[stat.ID]int{}
for j := 0; j < int(statCount); j++ { for j := 0; j < int(statCount); j++ {
@@ -119,6 +115,23 @@ func (gd *GameReader) GetPlayerUnit(playerUnit uintptr, previousHP, previousMP *
} }
} }
baseStats := map[stat.ID]int{}
for j := 0; j < int(baseStatsCount); j++ {
statOffset := uintptr(baseStatPtr) + 0x2 + uintptr(j*8)
statNumber := gd.Process.ReadUInt(statOffset, Uint16)
statValue := gd.Process.ReadUInt(statOffset+0x02, Uint32)
switch stat.ID(statNumber) {
case stat.Life,
stat.MaxLife,
stat.Mana,
stat.MaxMana:
baseStats[stat.ID(statNumber)] = int(uint32(statValue) >> 8)
default:
baseStats[stat.ID(statNumber)] = int(statValue)
}
}
// States (Buff, Debuff, Auras) // States (Buff, Debuff, Auras)
states := gd.getStates(statsListExPtr) states := gd.getStates(statsListExPtr)
@@ -170,14 +183,8 @@ func (gd *GameReader) GetPlayerUnit(playerUnit uintptr, previousHP, previousMP *
LeftSkill: skill.ID(leftSkillId), LeftSkill: skill.ID(leftSkillId),
RightSkill: skill.ID(rightSkillId), RightSkill: skill.ID(rightSkillId),
AvailableWaypoints: availableWPs, AvailableWaypoints: availableWPs,
MaxHPValue: previousHP,
MaxMPValue: previousMP,
} }
// Recalculate max HP and MP
d.HPPercent()
d.MPPercent()
return d return d
} }