Artemis Auto Bard by abianche
Description from the author:
# ------------------------------------------------------------
# AutoBard
# Made by @abianche on Discord (Artemis)
#
# Description
# This script automates the buffing and attacking process for bards.
# NOTE: WORK IN PROGRESS - PLEASE PROVIDE FEEDBACK!
# ------------------------------------------------------------
# =========================
# USER SETTINGS
# =========================
@setvar! EnablePeacemaking 1
@setvar! EnableProvocation 1
@setvar! EnableDiscordance 1
@setvar! useStrengthPots 0
@setvar! useMagicResistPots 0
@setvar! useStaminaPots 0
@setvar! usePets 1
@setvar! useSongBuffs 1
@setvar! amountOfGoldToDrop 500
@setvar! diffHitsToHeal 40
@setvar! useWarmode 1
# =========================
# DO NOT EDIT BELOW UNLESS YOU KNOW THE SCRIPT
# =========================
cooldown "Auto Bard" 6000
clearsysmsg
# Combat ranges.
@setvar! TargetAttackRange 10
@setvar! TargetSearchRange 12
@setvar! SecondaryTargetRange 8
# Throttle values. Increase these if the script still feels too spammy.
@setvar! AttackCommandCD 800
@setvar! PetKillCommandCD 3000
@setvar! PetGuardCommandCD 30000
@setvar! VetKitTimerCD 5000
@setvar! TargetSearchCD 1200
@setvar! SecondaryTargetSearchCD 3000
@setvar! BardStateCheckCD 2000
@setvar! TargetOverheadCD 3500
@setvar! NoTargetMessageCD 3000
@setvar! OverweightMessageCD 3000
# Safety / wait tuning.
@setvar! maxwaittimeinms 650
# Stable target state.
if not varexist currentTarget
@setvar! currentTarget 0
endif
if not varexist secondaryTarget
@setvar! secondaryTarget 0
endif
if not varexist foundTarget
@setvar! foundTarget 0
endif
if not varexist previousTarget
@setvar! previousTarget 0
endif
# Bard decision state.
@setvar! NeedtoDiscord 0
@setvar! NeedtoProvoke 0
@setvar! NeedtoPacify 0
# =========================
# TIMER INITIALIZATION
# =========================
if not timerexists "AttackCommandTimer"
createtimer "AttackCommandTimer"
settimer "AttackCommandTimer" AttackCommandCD
endif
if not timerexists "PetKillCommandTimer"
createtimer "PetKillCommandTimer"
settimer "PetKillCommandTimer" PetKillCommandCD
endif
if not timerexists "PetGuardCommandTimer"
createtimer "PetGuardCommandTimer"
settimer "PetGuardCommandTimer" PetGuardCommandCD
endif
if not timerexists "VetKitTimer"
createtimer "VetKitTimer"
settimer "VetKitTimer" VetKitTimerCD
endif
if not timerexists "TargetSearchTimer"
createtimer "TargetSearchTimer"
settimer "TargetSearchTimer" TargetSearchCD
endif
if not timerexists "SecondaryTargetSearchTimer"
createtimer "SecondaryTargetSearchTimer"
settimer "SecondaryTargetSearchTimer" SecondaryTargetSearchCD
endif
if not timerexists "BardStateCheckTimer"
createtimer "BardStateCheckTimer"
settimer "BardStateCheckTimer" BardStateCheckCD
endif
if not timerexists "TargetOverheadTimer"
createtimer "TargetOverheadTimer"
settimer "TargetOverheadTimer" TargetOverheadCD
endif
if not timerexists "NoTargetMessageTimer"
createtimer "NoTargetMessageTimer"
settimer "NoTargetMessageTimer" NoTargetMessageCD
endif
if not timerexists "OverweightMessageTimer"
createtimer "OverweightMessageTimer"
settimer "OverweightMessageTimer" OverweightMessageCD
endif
# Bard skill cooldown timers.
if not timerexists "Musicianship"
createtimer "Musicianship"
settimer "Musicianship" 5000
endif
if not timerexists "Discordance"
createtimer "Discordance"
settimer "Discordance" 11000
endif
if not timerexists "Provocation"
createtimer "Provocation"
settimer "Provocation" 11000
endif
if not timerexists "Peacemaking"
createtimer "Peacemaking"
settimer "Peacemaking" 11000
endif
# Song buff timers.
if not timerexists "SongBuffDelay"
createtimer "SongBuffDelay"
settimer "SongBuffDelay" 11000
endif
if not timerexists "DiscordanceTimer"
createtimer "DiscordanceTimer"
settimer "DiscordanceTimer" 11000
endif
if not timerexists "PeacemakingTimer"
createtimer "PeacemakingTimer"
settimer "PeacemakingTimer" 11000
endif
if not timerexists "ProvocationTimer"
createtimer "ProvocationTimer"
settimer "ProvocationTimer" 11000
endif
# Target effect timers. These are conservative markers only;
# labels are still the main source of truth.
if not timerexists "Discorded"
createtimer "Discorded"
settimer "Discorded" 31000
endif
if not timerexists "Provoked"
createtimer "Provoked"
settimer "Provoked" 31000
endif
if not timerexists "Pacified"
createtimer "Pacified"
settimer "Pacified" 31000
endif
# =========================
# PET GUARD
# =========================
if usePets = 1 and timer "PetGuardCommandTimer" > PetGuardCommandCD
say "all guard me"
settimer "PetGuardCommandTimer" 0
endif
# =========================
# SURVIVAL / UTILITY BLOCK
# =========================
# Drink heal potion if missing HP is above configured threshold.
if diffhits >= diffHitsToHeal
if findtype "Yellow Potion" backpack as HealPot
getlabel HealPot HealPotlabel
if "next" in HealPotlabel
# Potion is still on cooldown. Do nothing.
else
dclick HealPot
wait 250
endif
else
overhead "[ NO HEALING POTS! ]" 337
endif
endif
# Cure poison.
while poisoned
if findtype "Orange Potion" self
dclicktype "Orange Potion"
wait 250
else
overhead "[ NO CURE POTS! ]" 337
endif
# If HP becomes too low, leave cure loop and let other logic run.
if diffhits > diffHitsToHeal
break
endif
endwhile
# Refresh stamina.
if useStaminaPots = 1 and diffstam >= 5
if findtype "Red Potion" self
dclicktype "Red Potion"
overhead "[ REFRESH POTION ]" 37
wait 250
else
overhead "[ NO REFRESH POTS! ]" 337
endif
endif
# Magic resist potion.
if useMagicResistPots = 1 and not findbuff "Magic Resist"
if findtype "Black Potion" self
dclicktype "Black Potion"
overhead "[ RESIST POTION ]" 1109
wait 250
else
overhead "[ NO RESIST POTS! ]" 337
endif
endif
# Break paralysis with pouch command.
if paralyzed
if findtype "pouch" self
yell "[pouch"
wait 250
else
overhead "[ NO POUCHES! ]" 337
endif
endif
if skill "Veterinary" >= 50 and timer "VetKitTimer" >= VetKitTimerCD
if not bandaging and findtype 25750 backpack as item
dclick item
wait 200
endif
settimer "VetKitTimer" 0
endif
# Drop gold if overweight.
if weight > maxweight
if timer "OverweightMessageTimer" > OverweightMessageCD
overhead "OVERWEIGHT!!" 34
settimer "OverweightMessageTimer" 0
endif
if amountOfGoldToDrop != 0
while weight > maxweight
if findtype "gold coin" backpack as item
lift item amountOfGoldToDrop
droprelloc 0 0
getlabel backpack xxx
wait 200
if insysmsg "cannot drop anything"
drop backpack -1 -1 -1
endif
wait maxwaittimeinms
overhead "* Gold dropped *" 55
else
break
endif
endwhile
endif
endif
# Eat food if not satisfied.
if not findbuff "food satisfaction" and findtype "tray" self
if findtype "tray" self as Food
overhead "[ EATING FOOD... ]" 88
dclick Food
wait 500
endif
endif
# =========================
# SONG BUFF MAINTENANCE
# =========================
# These are the self/bag-targeted bard songs, not the mob debuffs.
# They are throttled by Musicianship + SongBuffDelay.
if useSongBuffs = 1
if not findbuff "Song Of Peacemaking" and timer "Musicianship" > 5000 and timer "PeacemakingTimer" > 11000 and timer "SongBuffDelay" > 10500
skill "Peacemaking"
wait 150
if insysmsg "What instrument shall you play?"
if findtype "standing harp|sackbut|bamboo flute|tambourine|drum|lute|lap harp|gemshorn|hurdy gurdy|psaltery|shawm|vielle" as Instrument
target Instrument
wait 250
else
overhead "[ NO INSTRUMENT! ]" 337
endif
endif
if not insysmsg "This is not a musical instrument"
wft 1500
target backpack
overhead "[ ♪ Peacemaking Buff ♪ ]" 84
settimer "Musicianship" 0
settimer "SongBuffDelay" 0
endif
endif
if not findbuff "Song Of Discordance" and timer "Musicianship" > 5000 and timer "DiscordanceTimer" > 11000 and timer "SongBuffDelay" > 10500
skill "Discordance"
wft 1500
if insysmsg "What instrument shall you play?"
if findtype "standing harp|sackbut|bamboo flute|tambourine|drum|lute|lap harp|gemshorn|hurdy gurdy|psaltery|shawm|vielle" as Instrument
target Instrument
wait 250
else
overhead "[ NO INSTRUMENT! ]" 337
endif
endif
if not insysmsg "This is not a musical instrument"
wft 1500
target backpack
overhead "[ ♪ Discordance Buff ♪ ]" 69
settimer "Musicianship" 0
settimer "SongBuffDelay" 0
endif
endif
if not findbuff "Song of Provocation" and timer "Musicianship" > 5000 and timer "ProvocationTimer" > 11000 and timer "SongBuffDelay" > 10500
skill "Provocation"
wft 1500
if insysmsg "What instrument shall you play?"
if findtype "standing harp|sackbut|bamboo flute|tambourine|drum|lute|lap harp|gemshorn|hurdy gurdy|psaltery|shawm|vielle" as Instrument
target Instrument
wait 250
else
overhead "[ NO INSTRUMENT! ]" 337
endif
endif
if not insysmsg "This is not a musical instrument"
wft 1500
target backpack
overhead "[ ♪ Provocation Buff ♪ ]" 2117
settimer "Musicianship" 0
settimer "SongBuffDelay" 0
endif
endif
endif
# =========================
# WAR MODE MAINTENANCE
# =========================
if useWarmode = 1 and not warmode
replay
endif
# =========================
# TARGET ACQUISITION
# =========================
# Only search for a new primary target when currentTarget is missing,
# dead, or out of range.
if foundTarget = 1
if dead currentTarget
@setvar! foundTarget 0
@setvar! currentTarget 0
@setvar! secondaryTarget 0
elseif not find currentTarget ground -1 -1 TargetSearchRange
@setvar! foundTarget 0
@setvar! currentTarget 0
@setvar! secondaryTarget 0
endif
endif
if foundTarget = 0 and timer "TargetSearchTimer" > TargetSearchCD
if targetexists
hotkey "cancel current target"
endif
hotkey "target closest grey monster"
wait 150
if find lasttarget ground -1 -1 TargetSearchRange and not dead lasttarget
@setvar! currentTarget lasttarget
@setvar! previousTarget currentTarget
@setvar! foundTarget 1
@setvar! secondaryTarget 0
getlabel currentTarget currentLabel
overhead "▼ TARGET ▼" 69 currentTarget
sysmsg "Target: {{currentLabel}}" 55
# Attack immediately on acquisition.
attack currentTarget
settimer "AttackCommandTimer" 0
# Pets attack immediately on target change, then only on cooldown.
if usePets = 1
say "all kill"
wft 150
target currentTarget
settimer "PetKillCommandTimer" 0
endif
else
if timer "NoTargetMessageTimer" > NoTargetMessageCD
overhead "[ NO TARGET ]" 33
settimer "NoTargetMessageTimer" 0
endif
endif
if targetexists
hotkey "cancel current target"
endif
settimer "TargetSearchTimer" 0
endif
# =========================
# COMBAT LOOP - STABLE TARGET
# =========================
# Once a target is found, keep operating on the same currentTarget.
# The loop ends naturally when the target dies/leaves range or player HP is too low.
while foundTarget = 1 and not dead currentTarget and find currentTarget ground -1 -1 TargetSearchRange and diffhits < diffHitsToHeal
# Keep attacking.
if timer "AttackCommandTimer" > AttackCommandCD
if find currentTarget ground -1 -1 TargetAttackRange
attack currentTarget
settimer "AttackCommandTimer" 0
endif
endif
# Pet kill command is intentionally slower than attack.
if usePets = 1 and timer "PetKillCommandTimer" > PetKillCommandCD
if find currentTarget ground -1 -1 TargetAttackRange
say "all kill"
wft 150
target currentTarget
settimer "PetKillCommandTimer" 0
endif
endif
# Show current target marker occasionally only.
if timer "TargetOverheadTimer" > TargetOverheadCD
overhead "▼ TARGET ▼" 69 currentTarget
settimer "TargetOverheadTimer" 0
endif
# Re-run critical survival checks inside the combat loop.
if diffhits >= diffHitsToHeal
if findtype "Yellow Potion" backpack as HealPotLoop
getlabel HealPotLoop HealPotLoopLabel
if "next" in HealPotLoopLabel
# Heal potion unavailable. Let loop end because HP is high-risk.
else
dclick HealPotLoop
wait 250
endif
endif
@setvar! foundTarget 0
replay
endif
while poisoned
if findtype "Orange Potion" self
dclicktype "Orange Potion"
wait 250
else
overhead "[ NO CURE POTS! ]" 337
endif
if diffhits > diffHitsToHeal
break
endif
endwhile
if skill "Veterinary" >= 50 and timer "VetKitTimer" >= VetKitTimerCD
if not bandaging and findtype 25750 backpack as item
dclick item
wait 200
endif
settimer "VetKitTimer" 0
endif
if useStaminaPots = 1 and diffstam >= 5
if findtype "Red Potion" self
dclicktype "Red Potion"
overhead "[ REFRESH POTION ]" 37
wait 250
endif
endif
if paralyzed
if findtype "pouch" self
yell "[pouch"
wait 250
endif
endif
# --------------------------------------------
# SECONDARY TARGET SEARCH
# --------------------------------------------
# Only needed for Provocation. Search occasionally and keep the result stable.
if EnableProvocation = 1 and skill "Provocation" >= 50 and timer "SecondaryTargetSearchTimer" > SecondaryTargetSearchCD
@setvar! secondaryTarget 0
if targetexists
hotkey "cancel current target"
endif
# Try a few candidates, but do not do this every loop pass.
for 4
hotkey "Next Grey Monster Target"
wait 150
@setvar! candidateTarget lasttarget
if find candidateTarget ground -1 -1 TargetSearchRange and candidateTarget != currentTarget and not dead candidateTarget
@setvar! secondaryTarget candidateTarget
getlabel secondaryTarget secondaryLabel
if "Paragon" in secondaryLabel
overhead "▼ PARAGON PROVO TARGET ▼" 12 secondaryTarget
else
overhead "▼ PROVO TARGET ▼" 2117 secondaryTarget
endif
break
endif
endfor
if targetexists
hotkey "cancel current target"
endif
settimer "SecondaryTargetSearchTimer" 0
endif
# If the stored secondary target is no longer valid, clear it.
if secondaryTarget != 0
if dead secondaryTarget
@setvar! secondaryTarget 0
elseif not find secondaryTarget ground -1 -1 TargetSearchRange
@setvar! secondaryTarget 0
endif
endif
# --------------------------------------------
# BARD STATE CHECK
# --------------------------------------------
if timer "BardStateCheckTimer" > BardStateCheckCD
@setvar! NeedtoDiscord 0
@setvar! NeedtoProvoke 0
@setvar! NeedtoPacify 0
getlabel currentTarget currentLabel
# Priority 1: current target must be discorded first.
if EnableDiscordance = 1 and skill "Discordance" >= 50
if "discord" in currentLabel
@setvar! NeedtoDiscord 0
else
@setvar! NeedtoDiscord 1
endif
endif
# Priority 2: only consider Provocation AFTER current target is discorded.
if NeedtoDiscord = 0 and EnableProvocation = 1 and skill "Provocation" >= 50 and secondaryTarget != 0
if find secondaryTarget ground -1 -1 TargetSearchRange and currentTarget != secondaryTarget
getlabel secondaryTarget secondaryLabel
if "provoked" in currentLabel
@setvar! NeedtoProvoke 0
elseif "provoked" in secondaryLabel
@setvar! NeedtoProvoke 0
else
@setvar! NeedtoProvoke 1
endif
endif
endif
# Priority 3: Peacemaking only if Discordance is done and Provocation is not needed.
if NeedtoDiscord = 0 and NeedtoProvoke = 0 and EnablePeacemaking = 1 and skill "Peacemaking" >= 50
if "pacified" in currentLabel
@setvar! NeedtoPacify 0
elseif "provoked" in currentLabel
# If already provoked, do not pacify the current target.
@setvar! NeedtoPacify 0
else
@setvar! NeedtoPacify 1
endif
endif
settimer "BardStateCheckTimer" 0
endif
# --------------------------------------------
# BARD EXECUTION - ONE ACTION PER CYCLE
# --------------------------------------------
if NeedtoDiscord = 1 and EnableDiscordance = 1 and skill "Discordance" >= 50 and timer "Discordance" > 11000 and timer "Musicianship" > 5000
clearsysmsg
skill "Discordance"
wft 1500
if insysmsg "What instrument shall you play?"
if findtype "standing harp|sackbut|bamboo flute|tambourine|drum|lute|lap harp|gemshorn|hurdy gurdy|psaltery|shawm|vielle" as Instrument
target Instrument
wait 250
else
overhead "[ NO INSTRUMENT! ]" 337
endif
endif
if not insysmsg "This is not a musical instrument"
target currentTarget
wait 250
endif
if insysmsg "Target cannot be seen"
overhead "[ DISCORD: CANNOT SEE TARGET ]" 337 currentTarget
settimer "Discordance" 0
elseif insysmsg "That is too far away."
overhead "[ DISCORD: TOO FAR ]" 337 currentTarget
settimer "Discordance" 0
elseif insysmsg "You must wait"
wait 500
elseif insysmsg "You play successfully"
overhead "[ ♪ DISCORDED! ♪ ]" 69 currentTarget
settimer "Musicianship" 0
settimer "Discordance" 0
settimer "Discorded" 0
@setvar! NeedtoDiscord 0
elseif insysmsg "fail to discord"
overhead "[ DISCORD FAIL ]" 337 currentTarget
settimer "Discordance" 5500
endif
elseif NeedtoProvoke = 1 and EnableProvocation = 1 and skill "Provocation" >= 50 and timer "Provocation" > 11000 and timer "Musicianship" > 5000
clearsysmsg
if secondaryTarget = 0
@setvar! NeedtoProvoke 0
elseif not find secondaryTarget ground -1 -1 TargetSearchRange
@setvar! NeedtoProvoke 0
else
skill "Provocation"
wft 1000
if insysmsg "What instrument shall you play?"
if findtype "standing harp|sackbut|bamboo flute|tambourine|drum|lute|lap harp|gemshorn|hurdy gurdy|psaltery|shawm|vielle" as Instrument
target Instrument
wait 250
else
overhead "[ NO INSTRUMENT! ]" 337
endif
endif
if not insysmsg "This is not a musical instrument"
target secondaryTarget
wait 150
endif
if insysmsg "Target cannot be seen"
overhead "[ PROVO: CANNOT SEE TARGET ]" 339 secondaryTarget
@setvar! NeedtoProvoke 0
settimer "Provocation" 0
elseif insysmsg "That is too far away."
overhead "[ PROVO: TOO FAR ]" 339 secondaryTarget
@setvar! NeedtoProvoke 0
settimer "Provocation" 0
elseif insysmsg "You must wait"
wait 500
else
target currentTarget
wait 250
if insysmsg "You play successfully, provoking"
overhead "[ ♪ PROVOKED! ♪ ]" 2117 currentTarget
overhead "[ ♪ PROVOKED! ♪ ]" 2117 secondaryTarget
settimer "Musicianship" 0
settimer "Provocation" 0
settimer "Provoked" 0
@setvar! NeedtoProvoke 0
@setvar! NeedtoPacify 0
elseif insysmsg "You fail to incite"
overhead "[ PROVO FAIL ]" 337
settimer "Provocation" 5500
elseif insysmsg "The creatures you are trying to provoke are too far away from each"
overhead "[ PROVO: TOO FAR APART ]" 153 currentTarget
overhead "[ PROVO: TOO FAR APART ]" 153 secondaryTarget
@setvar! NeedtoProvoke 0
settimer "Provocation" 0
elseif insysmsg "tell someone to attack themselves!"
overhead "[ PROVO: SELF TARGET FAIL ]" 337
@setvar! NeedtoProvoke 0
endif
endif
endif
elseif NeedtoPacify = 1 and EnablePeacemaking = 1 and skill "Peacemaking" >= 50 and timer "Peacemaking" > 11000 and timer "Musicianship" > 5000
clearsysmsg
skill "Peacemaking"
wft 1500
if insysmsg "What instrument shall you play?"
if findtype "standing harp|sackbut|bamboo flute|tambourine|drum|lute|lap harp|gemshorn|hurdy gurdy|psaltery|shawm|vielle" as Instrument
target Instrument
wait 250
else
overhead "[ NO INSTRUMENT! ]" 337
endif
endif
if not insysmsg "This is not a musical instrument"
target currentTarget
wait 250
endif
if insysmsg "Target cannot be seen"
overhead "[ PEACE: CANNOT SEE TARGET ]" 337 currentTarget
settimer "Peacemaking" 0
elseif insysmsg "That is too far away."
overhead "[ PEACE: TOO FAR ]" 337 currentTarget
settimer "Peacemaking" 0
elseif insysmsg "You must wait"
wait 500
elseif insysmsg "You play successfully, pacifying your"
overhead "[ ♪ PACIFIED! ♪ ]" 84 currentTarget
settimer "Musicianship" 0
settimer "Peacemaking" 0
settimer "Pacified" 0
@setvar! NeedtoPacify 0
elseif insysmsg "you fail to pacify your opponent"
overhead "[ PEACE FAIL ]" 337 currentTarget
settimer "Peacemaking" 5500
endif
endif
# Small loop wait. This keeps responsiveness while avoiding frantic looping.
wait 100
endwhile
# If the combat loop ended, clear stale state before the next script pass.
if foundTarget = 1
if dead currentTarget
@setvar! foundTarget 0
@setvar! currentTarget 0
@setvar! secondaryTarget 0
elseif not find currentTarget ground -1 -1 TargetSearchRange
@setvar! foundTarget 0
@setvar! currentTarget 0
@setvar! secondaryTarget 0
endif
endif
replay
WORK IN PROGRESS - PLEASE PROVIDE FEEDBACK!








