Created: 20 days ago on 05/25/2025, 03:37:43 AMUpdated: 19 days ago on 05/26/2025, 01:14:53 AM
Description:
-- Updated 05/25/2025:
Better bandage and cure timing
-- Updated 05/25/2025:
BugFix - consider refresh potions, potions
BugFix - only clear a hand if consume timer is ready
-- Updated 05/25/2025:
Added refresh potion support.
-- Updated 05/25/2025:
I now have Healing so I added a bandaging.
Made the script generally more robust.
TODO: I don't know what the minimum action and targeting delays are, I'm suspicious of them being constant across all clients.
-- Initial post 05/24/2025:
I don't have Healing or Magery...
So I drink a lot of potions. This does it automatically.
local RED = 32
local GREEN = 67
local CURE_POTION = 0xF07
local HEAL_POTION = 0xF0C
local REFR_POTION = 0x0F0B
local BANDAGE = 0x0E21
local POTION_THRESHOLD = 0.75
local BANDAGE_THRESHOLD = 0.9
local STAM_THRESHOLD = 0.75
local ACTION_DELAY = 650
local TARGET_DELAY = 500
local CONSUME_DELAY = 10000
local CONSUME_TIMERS = {
[HEAL_POTION] = 0,
[CURE_POTION] = 0,
[REFR_POTION] = 0,
[BANDAGE] = 0
}
local WARN_DELAY = 5000
local WARN_TIMERS = {
[HEAL_POTION] = 0,
[CURE_POTION] = 0,
[REFR_POTION] = 0,
[BANDAGE] = 0
}
local function IsPotion(graphic)
return graphic == HEAL_POTION or graphic == CURE_POTION or graphic == REFR_POTION
end
local lastT = os.clock()
local function DeltaT()
local now = os.clock()
local dt = 1000 * (now - lastT)
lastT = now
return dt
end
local function Tick(dt)
for key, value in pairs(WARN_TIMERS) do
if value > 0 then
WARN_TIMERS[key] = math.max(value - dt, 0)
end
end
for key, value in pairs(CONSUME_TIMERS) do
if value > 0 then
CONSUME_TIMERS[key] = math.max(value - dt, 0)
end
end
end
local function Wait(duration)
Pause(duration)
Tick(DeltaT())
end
local function Consume(item)
Player.UseObject(item.Serial)
CONSUME_TIMERS[item.Graphic] = CONSUME_DELAY
if item.Graphic == BANDAGE then
if Targeting.WaitForTarget(TARGET_DELAY) then
Targeting.TargetSelf()
Tick(DeltaT()) -- Catch up on DT since waiting for target
end
end
WARN_TIMERS[item.Graphic] = 0
end
local function Try(graphic, name)
local items = Items.FindByFilter({onground=false, graphics=graphic})
local item = nil
if items then
item = items[1]
end
if item == nil then
if WARN_TIMERS[graphic] and WARN_TIMERS[graphic] <= 0 then
WARN_TIMERS[graphic] = WARN_DELAY
Messages.Overhead("[No "..name.."]", RED, Player.Serial)
end
return
else
if CONSUME_TIMERS[graphic] and CONSUME_TIMERS[graphic] <= 0 then
local rightHandObj = Items.FindByLayer(2)
local needHand = IsPotion(graphic) and rightHandObj ~= nil and Skills.GetValue("Alchemy") < 80
if needHand then
if Player.ClearHands("right") then
Wait(ACTION_DELAY)
end
end
Messages.Overhead("[Using "..name.."]", GREEN, Player.Serial)
Consume(item)
Wait(ACTION_DELAY)
if needHand then
Player.Equip(rightHandObj.Serial)
Wait(ACTION_DELAY)
end
end
end
end
while true do
if Player.IsHidden or Player.IsDead then
goto continue
end
if Player.IsPoisoned then
Try(CURE_POTION, "cure potion")
end
if Player.Hits / Player.HitsMax < POTION_THRESHOLD then
Try(HEAL_POTION, "heal potion")
end
if Player.Hits / Player.HitsMax < BANDAGE_THRESHOLD then
Try(BANDAGE, "bandage")
end
if Player.Stam / Player.MaxStam < STAM_THRESHOLD then
Try(REFR_POTION, "refresh potion")
end
::continue::
Wait(100)
end