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

Repair loop fix, add support for items with quantity #630

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 62 additions & 78 deletions internal/action/repair.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,102 +20,86 @@ func Repair() error {
ctx := context.Get()
ctx.SetLastAction("Repair")

for _, i := range ctx.Data.Inventory.ByLocation(item.LocationEquipped) {
if RepairRequired() {

_, indestructible := i.FindStat(stat.Indestructible, 0)
// Get the repair NPC for the town
repairNPC := town.GetTownByArea(ctx.Data.PlayerUnit.Area).RepairNPC()

if i.Ethereal || indestructible {
continue
// Act3 repair NPC handling
if repairNPC == npc.Hratli {
MoveToCoords(data.Position{X: 5224, Y: 5045})
}

// Get the durability stats

durability, found := i.FindStat(stat.Durability, 0)
maxDurability, maxDurabilityFound := i.FindStat(stat.MaxDurability, 0)
err := InteractNPC(repairNPC)
if err != nil {
return err
}

// Calculate Durability percent
durabilityPercent := -1
if repairNPC != npc.Halbu {
ctx.HID.KeySequence(win.VK_HOME, win.VK_DOWN, win.VK_RETURN)
} else {
ctx.HID.KeySequence(win.VK_HOME, win.VK_RETURN)
}

if maxDurabilityFound && found {
durabilityPercent = int((float64(durability.Value) / float64(maxDurability.Value)) * 100)
utils.Sleep(100)
if ctx.Data.LegacyGraphics {
ctx.HID.Click(game.LeftButton, ui.RepairButtonXClassic, ui.RepairButtonYClassic)
} else {
ctx.HID.Click(game.LeftButton, ui.RepairButtonX, ui.RepairButtonY)
}
utils.Sleep(500)

// Restructured conditionals for when to attempt repair
if (maxDurabilityFound && !found) ||
(durabilityPercent != -1 && found && durabilityPercent <= 20) ||
(found && durabilityPercent == -1 && durability.Value <= 2) {
return step.CloseAllMenus()
}

ctx.Logger.Info(fmt.Sprintf("Repairing %s, item durability is %d percent", i.Name, durabilityPercent))
return nil
}

// Get the repair NPC for the town
repairNPC := town.GetTownByArea(ctx.Data.PlayerUnit.Area).RepairNPC()
func RepairRequired() bool {
ctx := context.Get()
ctx.SetLastAction("RepairRequired")

// Act3 repair NPC handling
if repairNPC == npc.Hratli {
MoveToCoords(data.Position{X: 5224, Y: 5045})
}
for _, i := range ctx.Data.Inventory.ByLocation(item.LocationEquipped) {
// Skip indestructible items
_, indestructible := i.FindStat(stat.Indestructible, 0)
if i.Ethereal || indestructible {
continue
}

err := InteractNPC(repairNPC)
if err != nil {
return err
currentDurability, currentDurabilityFound := i.FindStat(stat.Durability, 0)
maxDurability, maxDurabilityFound := i.FindStat(stat.MaxDurability, 0)
quantity, quantityFound := i.FindStat(stat.Quantity, 0)

// If we have both stats, check percentage
if currentDurabilityFound && maxDurabilityFound && !quantityFound {
durabilityPercent := int((float64(currentDurability.Value) / float64(maxDurability.Value)) * 100)
if durabilityPercent <= 20 {
ctx.Logger.Info(fmt.Sprintf("Repairing %s, item durability is %d percent", i.Name, durabilityPercent))
return true
}
}

if repairNPC != npc.Halbu {
ctx.HID.KeySequence(win.VK_HOME, win.VK_DOWN, win.VK_RETURN)
} else {
ctx.HID.KeySequence(win.VK_HOME, win.VK_RETURN)
// If we only have current durability, check absolute value
if currentDurabilityFound && !quantityFound {
if currentDurability.Value <= 8 {
ctx.Logger.Info(fmt.Sprintf("Repairing %s, item durability is %d", i.Name, currentDurability.Value))
return true
}
}

utils.Sleep(100)
if ctx.Data.LegacyGraphics {
ctx.HID.Click(game.LeftButton, ui.RepairButtonXClassic, ui.RepairButtonYClassic)
} else {
ctx.HID.Click(game.LeftButton, ui.RepairButtonX, ui.RepairButtonY)
}
utils.Sleep(500)
// Handle case where durability stat is missing but max durability exists
// This likely indicates the item needs repair
if maxDurabilityFound && !currentDurabilityFound && !quantityFound {
ctx.Logger.Info(fmt.Sprintf("Repairing %s, item has max durability but no current durability", i.Name))
return true
}

return step.CloseAllMenus()
// If all other checks pass, look for quantity value (throwables)
if quantityFound && quantity.Value <= 15 {
ctx.Logger.Info(fmt.Sprintf("Repairing %s, item quantity is %d", i.Name, quantity.Value))
return true
}
}

return nil
}

func RepairRequired() bool {
ctx := context.Get()
ctx.SetLastAction("RepairRequired")

for _, i := range ctx.Data.Inventory.ByLocation(item.LocationEquipped) {
// Skip indestructible items
_, indestructible := i.FindStat(stat.Indestructible, 0)
if i.Ethereal || indestructible {
continue
}

currentDurability, currentDurabilityFound := i.FindStat(stat.Durability, 0)
maxDurability, maxDurabilityFound := i.FindStat(stat.MaxDurability, 0)

// If we have both stats, check percentage
if currentDurabilityFound && maxDurabilityFound {
durabilityPercent := int((float64(currentDurability.Value) / float64(maxDurability.Value)) * 100)
if durabilityPercent <= 20 {
return true
}
}

// If we only have current durability, check absolute value
if currentDurabilityFound {
if currentDurability.Value <= 5 {
return true
}
}

// Handle case where durability stat is missing but max durability exists
// This likely indicates the item needs repair
if maxDurabilityFound && !currentDurabilityFound {
return true
}
}

return false
return false
}