Npc/Monsters Mode and Portals destination + optimization (#49)
* Added States for monsters and corpses
Now can properly identify if a corpse is interactable with a skill ( barbarian, necromancer)
Also getting states about monsters : Exemple Soul Killer with Conviction aura: State 28 // conviction
Also can tell if monster has a state after you used a skill on it Exemple: State 56 Terror ( After using Barbarian skill Howl to fear )
Another Exemple using Grief on Mephistos he now have states : 2 poison
52 Preventheal
will be very useful for further development.
* Added modes to player
Now accessible in koolo using : s.data.PlayerUnit.Mode
Those are Modes for player:
const Death: 0;
const StandingOutsideTown: 1;
const Walking: 2;
const Running: 3;
const GettingHit: 4;
const StandingInTown: 5;
const WalkingInTown: 6;
const Attacking1: 7;
const Attacking2: 8;
const Blocking: 9;
const CastingSkill: 10;
const ThrowingItem: 11;
const Kicking: 12;
const UsingSkill1: 13;
const UsingSkill2: 14;
const UsingSkill3: 15;
const UsingSkill4: 16;
const Dead: 17;
const SkillActionSequence: 18;
const KnockedBack: 19;
* update Added alias(const) for player modes
can be used like this s.data.PlayerUnit.Mode == mode.StandingInTown
* added modes to object
0 = Object idle
1 = Object operating
2 = Object opened
3 = Object special 1 ?? to be determined what it does exactly
4 = Object special 2 ?? to be determined what it does exactly
5 = Object special 3 ?? to be determined what it does exactly
6 = Object special 4 ?? to be determined what it does exactly
7 = Object special 5 ?? to be determined what it does exactly
* update object mode strings
* Update object_mode.go
* Update object_mode.go
* update object modes again. accurate now
* Added IsSealBoss() for Chaos Run
* Npc/Monster Modes and Portals destination
also IsEscapingType() Monster cannot be attacked when airborne or hide in water (NpcMode 8)
* Npc/Monster Modes and Portals destination
also IsEscapingType() Monster cannot be attacked when airborne or hide in water (NpcMode 8)
* Optimized monsters.go and object.go
also catapults have been added to ignore list
* Tz Frigid Higland ingores added
This commit is contained in:
@@ -1,53 +1,73 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"github.com/hectorgimenez/d2go/pkg/data/mode"
|
||||
"sort"
|
||||
|
||||
"github.com/hectorgimenez/d2go/pkg/data/mode"
|
||||
|
||||
"github.com/hectorgimenez/d2go/pkg/data"
|
||||
"github.com/hectorgimenez/d2go/pkg/data/area"
|
||||
"github.com/hectorgimenez/d2go/pkg/data/object"
|
||||
"github.com/hectorgimenez/d2go/pkg/utils"
|
||||
)
|
||||
|
||||
func isPortal(txtFileNo int) bool {
|
||||
desc, ok := object.Desc[txtFileNo]
|
||||
return ok && desc.Name == "Portal"
|
||||
}
|
||||
|
||||
func (gd *GameReader) Objects(playerPosition data.Position, hover data.HoverData) []data.Object {
|
||||
baseAddr := gd.Process.moduleBaseAddressPtr + gd.offset.UnitTable + (2 * 1024)
|
||||
unitTableBuffer := gd.Process.ReadBytesFromMemory(baseAddr, 128*8)
|
||||
|
||||
var objects []data.Object
|
||||
|
||||
for i := 0; i < 128; i++ {
|
||||
objectOffset := 8 * i
|
||||
objectUnitPtr := uintptr(ReadUIntFromBuffer(unitTableBuffer, uint(objectOffset), Uint64))
|
||||
for objectUnitPtr > 0 {
|
||||
objectType := gd.Process.ReadUInt(objectUnitPtr+0x00, Uint32)
|
||||
if objectType == 2 {
|
||||
txtFileNo := gd.Process.ReadUInt(objectUnitPtr+0x04, Uint32)
|
||||
unitID := gd.Process.ReadUInt(objectUnitPtr+0x08, Uint32)
|
||||
|
||||
// Read the object mode
|
||||
for objectUnitPtr > 0 {
|
||||
// Read minimal data first to check object type
|
||||
objectType := gd.Process.ReadUInt(objectUnitPtr+0x00, Uint32)
|
||||
|
||||
if objectType == 2 {
|
||||
rawTxtFileNo := gd.Process.ReadUInt(objectUnitPtr+0x04, Uint32) // Extract actual txtFileNo
|
||||
txtFileNo := rawTxtFileNo & 0xFFFF
|
||||
unitID := gd.Process.ReadUInt(objectUnitPtr+0x08, Uint32)
|
||||
objectMode := mode.ObjectMode(gd.Process.ReadUInt(objectUnitPtr+0x0c, Uint32))
|
||||
// Coordinates (X, Y)
|
||||
unitDataPtr := uintptr(gd.Process.ReadUInt(objectUnitPtr+0x10, Uint64))
|
||||
|
||||
//This offset gives timer for each mode to keep progress in real time. exemple: Mode.Operating fresh timer then Mode.Opened new timer (for objects)
|
||||
// timerValue := uint32(gd.Process.ReadUInt(objectUnitPtr+0x5C, Uint32))
|
||||
|
||||
// Path and position data
|
||||
pathPtr := uintptr(gd.Process.ReadUInt(objectUnitPtr+0x38, Uint64))
|
||||
// Coordinates (X, Y)
|
||||
posX := gd.Process.ReadUInt(pathPtr+0x10, Uint16)
|
||||
posY := gd.Process.ReadUInt(pathPtr+0x14, Uint16)
|
||||
|
||||
unitDataPtr := uintptr(gd.Process.ReadUInt(objectUnitPtr+0x10, Uint64))
|
||||
// checking if this is a shrine
|
||||
shrineTextPtr := uintptr(gd.Process.ReadUInt(objectUnitPtr+0x0A, Uint64))
|
||||
shrineType := uint(0)
|
||||
interactType := uint(0)
|
||||
shrineData := object.ShrineData{}
|
||||
if shrineTextPtr > 0 {
|
||||
shrineType = gd.Process.ReadUInt(unitDataPtr+0x08, Uint8)
|
||||
shrineData = object.ShrineData{
|
||||
ShrineName: object.ShrineTypeNames[object.ShrineType(shrineType)],
|
||||
ShrineType: object.ShrineType(shrineType),
|
||||
}
|
||||
} else {
|
||||
interactType = gd.Process.ReadUInt(unitDataPtr+0x08, Uint8)
|
||||
}
|
||||
var shrineData object.ShrineData
|
||||
var portalData object.PortalData
|
||||
interactType := gd.Process.ReadUInt(unitDataPtr+0x08, Uint8)
|
||||
owner := gd.Process.ReadStringFromMemory(unitDataPtr+0x34, 32)
|
||||
|
||||
obj := data.Object{
|
||||
// Handle portals
|
||||
if isPortal(int(txtFileNo)) {
|
||||
destArea := area.ID(gd.Process.ReadUInt(unitDataPtr+0x08, Uint8))
|
||||
portalData.DestArea = destArea
|
||||
// Handle Shrines
|
||||
} else {
|
||||
shrineTextPtr := uintptr(gd.Process.ReadUInt(objectUnitPtr+0x0A, Uint64))
|
||||
if shrineTextPtr > 0 {
|
||||
shrineType := gd.Process.ReadUInt(unitDataPtr+0x08, Uint8)
|
||||
shrineData = object.ShrineData{
|
||||
ShrineName: object.ShrineTypeNames[object.ShrineType(shrineType)],
|
||||
ShrineType: object.ShrineType(shrineType),
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle objects
|
||||
objects = append(objects, data.Object{
|
||||
ID: data.UnitID(unitID),
|
||||
Name: object.Name(int(txtFileNo)),
|
||||
IsHovered: data.UnitID(unitID) == hover.UnitID && hover.UnitType == 2 && hover.IsHovered,
|
||||
@@ -58,21 +78,22 @@ func (gd *GameReader) Objects(playerPosition data.Position, hover data.HoverData
|
||||
X: int(posX),
|
||||
Y: int(posY),
|
||||
},
|
||||
Owner: owner,
|
||||
Mode: objectMode,
|
||||
}
|
||||
objects = append(objects, obj)
|
||||
Owner: owner,
|
||||
Mode: objectMode,
|
||||
PortalData: portalData,
|
||||
})
|
||||
}
|
||||
objectUnitPtr = uintptr(gd.Process.ReadUInt(objectUnitPtr+0x150, Uint64))
|
||||
}
|
||||
}
|
||||
|
||||
sort.SliceStable(objects, func(i, j int) bool {
|
||||
distanceI := utils.DistanceFromPoint(playerPosition, objects[i].Position)
|
||||
distanceJ := utils.DistanceFromPoint(playerPosition, objects[j].Position)
|
||||
|
||||
return distanceI < distanceJ
|
||||
})
|
||||
if len(objects) > 0 {
|
||||
sort.SliceStable(objects, func(i, j int) bool {
|
||||
distanceI := utils.DistanceFromPoint(playerPosition, objects[i].Position)
|
||||
distanceJ := utils.DistanceFromPoint(playerPosition, objects[j].Position)
|
||||
return distanceI < distanceJ
|
||||
})
|
||||
}
|
||||
|
||||
return objects
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user