Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve unsync pathing issue #526

Merged
merged 15 commits into from
Nov 17, 2024
Prev Previous commit
Next Next commit
interact entrance corrections.
  • Loading branch information
elobo91 committed Nov 15, 2024
commit 73388ac0d84a66b89c69839dd74debc00bc2f69f
36 changes: 4 additions & 32 deletions internal/action/clear_level.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,30 @@ func ClearCurrentLevel(openChests bool, filter data.MonsterFilter) error {
ctx := context.Get()
ctx.SetLastAction("ClearCurrentLevel")

// First check if we're in town, if so, exit early
if ctx.Data.PlayerUnit.Area.IsTown() {
return fmt.Errorf("cannot clear level in town")
}

currentArea := ctx.Data.PlayerUnit.Area
rooms := ctx.PathFinder.OptimizeRoomsTraverseOrder()
for _, r := range rooms {
// If we're no longer in the same area (e.g., took portal to town), stop clearing
if ctx.Data.PlayerUnit.Area != currentArea {
return nil
}

err := clearRoom(r, filter)
if err != nil {
ctx.Logger.Warn("Failed to clear room", "error", err)
ctx.Logger.Warn("Failed to clear room: %v", err)
}

if !openChests {
continue
}

// Again check area before chest operations
if ctx.Data.PlayerUnit.Area != currentArea {
return nil
}

for _, o := range ctx.Data.Objects {
if o.IsChest() && o.Selectable && r.IsInside(o.Position) {
err = MoveToCoords(o.Position)
if err != nil {
ctx.Logger.Warn("Failed moving to chest", "error", err)
ctx.Logger.Warn("Failed moving to chest: %v", err)
continue
}
err = InteractObject(o, func() bool {
chest, _ := ctx.Data.Objects.FindByID(o.ID)
return !chest.Selectable
})
if err != nil {
ctx.Logger.Warn("Failed interacting with chest", "error", err)
ctx.Logger.Warn("Failed interacting with chest: %v", err)
}
utils.Sleep(500) // Add small delay to allow the game to open the chest and drop the content
}
Expand All @@ -63,12 +47,11 @@ func ClearCurrentLevel(openChests bool, filter data.MonsterFilter) error {

return nil
}

func clearRoom(room data.Room, filter data.MonsterFilter) error {
ctx := context.Get()
ctx.SetLastAction("clearRoom")

currentArea := ctx.Data.PlayerUnit.Area

path, _, found := ctx.PathFinder.GetClosestWalkablePath(room.GetCenter())
if !found {
return errors.New("failed to find a path to the room center")
Expand All @@ -78,23 +61,12 @@ func clearRoom(room data.Room, filter data.MonsterFilter) error {
X: path.To().X + ctx.Data.AreaOrigin.X,
Y: path.To().Y + ctx.Data.AreaOrigin.Y,
}

// Check if we're still in the same area before moving
if ctx.Data.PlayerUnit.Area != currentArea {
return nil
}

err := MoveToCoords(to)
if err != nil {
return fmt.Errorf("failed moving to room center: %w", err)
}

for {
// Exit if we've changed areas
if ctx.Data.PlayerUnit.Area != currentArea {
return nil
}

monsters := getMonstersInRoom(room, filter)
if len(monsters) == 0 {
return nil
Expand Down
35 changes: 27 additions & 8 deletions internal/action/step/interact_entrance.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

const (
maxEntranceDistance = 6
maxMoveRetries = 3
)

func InteractEntrance(area area.ID) error {
Expand All @@ -25,12 +26,9 @@ func InteractEntrance(area area.ID) error {
ctx.SetLastStep("InteractEntrance")

for {
// Pause the execution if the priority is not the same as the execution priority
ctx.PauseIfNotPriority()

// Give some extra time to render the UI
if ctx.Data.AreaData.Area == area && time.Since(lastRun) > time.Millisecond*500 && ctx.Data.AreaData.IsInside(ctx.Data.PlayerUnit.Position) {
// We've successfully entered the new area
return nil
}

Expand All @@ -47,25 +45,46 @@ func InteractEntrance(area area.ID) error {
if l.Area == area {
distance := ctx.PathFinder.DistanceFromMe(l.Position)
if distance > maxEntranceDistance {
return fmt.Errorf("entrance too far away (distance: %d)", distance)
// Try to move closer with retries
for retry := 0; retry < maxMoveRetries; retry++ {
if err := MoveTo(l.Position); err != nil {
// If MoveTo fails, try direct movement
screenX, screenY := ctx.PathFinder.GameCoordsToScreenCords(
l.Position.X-2,
l.Position.Y-2,
)
ctx.HID.Click(game.LeftButton, screenX, screenY)
utils.Sleep(800)
ctx.RefreshGameData()
}

// Check if we're close enough now
newDistance := ctx.PathFinder.DistanceFromMe(l.Position)
if newDistance <= maxEntranceDistance {
break
}

if retry == maxMoveRetries-1 {
return fmt.Errorf("entrance too far away (distance: %d)", distance)
}
}
}

if l.IsEntrance {
// Adjust click position to be slightly closer to entrance
lx, ly := ctx.PathFinder.GameCoordsToScreenCords(l.Position.X-1, l.Position.Y-1)
if ctx.Data.HoverData.UnitType == 5 || ctx.Data.HoverData.UnitType == 2 && ctx.Data.HoverData.IsHovered {
ctx.HID.Click(game.LeftButton, currentMouseCoords.X, currentMouseCoords.Y)
waitingForInteraction = true
utils.Sleep(200) // Small delay after click
utils.Sleep(200)
}

x, y := utils.Spiral(interactionAttempts)
x = x / 3 // Reduce spiral size further
x = x / 3
y = y / 3
currentMouseCoords = data.Position{X: lx + x, Y: ly + y}
ctx.HID.MovePointer(lx+x, ly+y)
interactionAttempts++
utils.Sleep(100) // Small delay for mouse movement
utils.Sleep(100)
continue
}

Expand Down