I DO need help on this however. Having 2 problems. One: when we kill a mob but were attacked my another, it does not want to attack the second one very well. Also, need a better solution to how to "pull". Mine works so-so. Anyhow, what this script does is :
1. Hunts things that are BELOW your level.
2. adds all nasty mobs to a avoidlist.
3. Is coded to work for my chanter too, still very rough there. working on making an include for ALL classes.
4. is much more random. I cannot even predict what this thing will do with all the random calls :)
Parameters are KILL RANGE and Min Level
FYI sometimes it does not want to auto-target when you first start, so just left click the first unlucky sob
Code: Select all
| Hunter.mac
|
| The ultimate melee class.zone farming script
|
#turbo
#include routines.mac
#include spellsub.mac
#define LootTotal v50
#define KSRadius v51
#define NoLOS v38
#define TooFarAway v39
#define MyTarget v40
#define MyHeading v41
#define TargetHeading v42
#define HeadingDelta v43
#define TargetDead v44
#define MyXLoc v46
#define MyYLoc v47
#define KSCheck v49
#define TargetLooted v52
#define LootSlot v54
#define CheckLoot v55
#define AttackedMe v56
#define BackHome v57
#define HomeY v58
#define HomeX v59
#define Attacker v60
#define myrandom v61
#define startlevel v64
#define endlevel v65
#define mobname v66
#define mobid v67
#define bandagedone v68
#define MobLevel v69
#define Realtarget v70
#define CastTimer v71
#define OutRange v72
#define ShieldGone v73
#define spCost v74
#define kRadius v75
#define ipulled v76
#event CannotSee "You cannot see your target"
#event TooFar "Your target is too far away"
#event HitsYou "YOU for"
#event Zoneing "LOADING"
#event IDied "slain by"
#event Bandagedone "The bandaging is complete"
#event Bandagefail "bandage has failed"
#event Bandageout "buy some"
#event NoBandages "You can't bandage without bandages, go buy some."
#event Bandage50 "cannot bandage your target"
#Event ClarityGone "Your mind returns to normal."
#event OutofRange "Your target is out of range"
#event Buffoff "Your shielding fades"
sub Main
/zapvars
/mqlog Hunter script v 20021007a started
| Set up List of Loot to keep
/call SetLootList
| Set KS radius below. The script will not target a mob if a PC is within this radius of it.
/varset KSRadius 500
| Set Loot nodrop
/lootn never
/loc
/varset HomeX $char(x)
/varset HomeY $char(y)
/varset kRadius $int($p0)
/delay 5
/alert clear 4
/if n $AttackedMe!=1 /call makefearlist
/mqlog Home Point is $HomeX, $HomeY
/press esc
/press esc
/press esc
/press esc
/press alt
/press shift
/press ctrl
/doevents
/varset ShieldGone 1
| Start of main Loop
|
/stand
/delay 5
/if n $kRadius==0 /varset kRadius 500
:Start
/call makernum 5
/delay 5
/if n $target(id)==$char(id) /endmacro
/call SetAlerts
/doevents
| RestUp
/if n $target(id)==0 /call RestUp
/varset ipulled 0
/alert clear 4
| Aquire nearest target to attack
/delay 3
/call GetTarget
| Advance
/stand
/call Advance
/stand
/delay 3
/call SetLootList
/call Loot
/if "$char(class)"=="Enchanter" {
/if n $char(pet)!=0 {
/assist $spawn($char(pet),name[clean])
}
}
/doevents
/if n $target(id)==0 /call HomeBase
/doevents
/if n $target(id)==0 /delay $myrandom
/goto :Start
/return
| RestUp
sub RestUp
/doevents
/if "$combat"=="TRUE" /goto :NoRest
/if n $target(id)!=0 /goto :NoRest
/if "$char(class)"=="Enchanter" {
/if n $char(pet)!=0 {
/assist $spawn($char(pet),name[clean])
/if n $target(id)!=0 /goto :NoRest
}
}
/if "$char(class)"=="Enchanter"{
/if n $char(hp,pct)>65 {
/if n $char(mana,pct)>65 /goto :Healthy
}
}
/if "$char(class)"!="Enchanter" /if n $char(hp,pct)>65 /goto :Healthy
|Low on HP's running home
/mqlog HPs at $char(hp,pct) heading home
| Run to Home Base if needed
/call HomeBase
| If we didnt make it home we dont want to rest
/if n $return!=1 {
/mqlog Didnt make it home aborting run home
/goto :NoRest
}
/mqlog Reached home base resting
/varset $bandagedone 1
/if n $target(id)==0 {
/sit on |sit when we are not doing anything
/if "$char(class)"=="Enchanter" {
/varset spCost $spell("$char(gem,3)",mana)
/if n $spCost < $int($char(mana,cur)){
/if n $char(pet)==0 {
/stand
/varset CastTimer $int($spell(3,casttime)*10+$spell(3,recoverytime)*10)
/call SpellSub 3 CastTimer
/delay 20
}
}
}
:Rest
/doevents
| Check if something has aggroed and attack it if it has.
/if n $AttackedMe==1 {
/mqlog aggroed whilst sitting
/stand
/goto :NoRest
}
/if n $target(id)!=0{
/if n $target(id)!=$char(id) {
/varset $AttackedMe 1
/stand
/goto :NoRest
}
}
/doevents
/finditem similar "bandages"
/click left auto
/if $find()!=FALSE /call band
/if "$char(class)"=="Enchanter" {
/if n $char(mana,pct)<65 /goto :Rest
}
/if n $char(hp,pct)<65 /goto :Rest
/mqlog Hps at $char(hp,pct) Off hunting again
/stand
}
:Healthy
/stand
/delay 3
/doevents
/if "$char(class)"=="Enchanter" {
/varset spCost $spell("$char(gem,2)",mana)
/if n $spCost < $int($char(mana,cur)){
/delay 3
/target myself
/delay 3
/if $ShieldGone==1 {
/varset CastTimer $int($spell(2,casttime)*10+$spell(2,recoverytime)*10)
/stand
/delay 3
/call SpellSub 2 CastTimer
/delay 10
/varset ShieldGone 0
}
}
}
/if n $target(id)==0 /sit on |sit when we are not doing anything
:NoRest
/return
sub GetTarget
/if n $target(id)!=0 {
/varset AttackedMe 1
/face nopredict
/return
}
/call getstart
/mqlog targeting mobs between $startlevel and $endlevel
/call SetAlerts
:Acquire
/if AttackedMe==1 {
/mqlog Targeted "$v13" who jumped me
/target "$v13"
/varset AttackedMe 0
} else /if "$alert(1)"=="TRUE" {
/target npc alert 1 notnearalert 4 nopcnear $KSRadius
/mqlog Targeted $target(name) range $target(distance) on alert list 1
} else /if "$alert(2)"=="TRUE" {
/target npc alert 2 notnearalert 4 nopcnear $KSRadius
/mqlog Targeted $target(name) range $target(distance) on alert list 2
|} else /if "$alert(3)"=="TRUE" {
|/target npc alert 3 notnearalert 4 nopcnear $KSRadius
|/mqlog Targeted $target(name) range $target(distance) on alert list 2
} else {
/target npc radius $kRadius range $startlevel $endlevel notnearalert 4 nopcnear $KSRadius
/doevents
/delay 5
}
/if n $target(id)==0 /goto :Acquire
/varset MyTarget $target(id)
/delay 0
/if n $target(id)!=0 /stand
/return
| Advance to mob subroutine
sub Advance
:Engage
|Process any events
/doevents
|Work on sense heading skill
/if $char(ability,"Sense Heading")>0 /doability "Sense Heading"
| Turn towards target
/face fast nopredict
| If we are not within melee range then make sure we are on autorun
/if n $target(distance)>15 /call autorun2 1
| If we are still a distance away from target search for a closer one
/if n $target(distance)>200 {
/call GetTarget
}
| Save our current x,y loc
/varset MyXLoc $char(x)
/varset MyYLoc $char(y)
| Wait a then check loc again if we are on same spot call the obstacle routine to try and get around it
/delay 1
/if n $MyXLoc==$char(x) /if $MyYLoc==$char(y) /call Obstacle
| If we are within melee range stop running check Target again for other players engaged and attack if all OK.
/doevents
/if "$char(class)"=="Enchanter" {
/varset spCost $spell("$char(gem,1)",mana)
/if n $spCost < $int($char(mana,cur)){
/if n $target(distance)<50 {
/mqlog In spell range
/call autorun2 0
/varset KSCheck $target(id)
/call GetTarget
/if n $KSCheck==$MyTarget {
/varset CastTimer $int($spell(1,casttime)*10+$spell(1,recoverytime)*10)
/delay 5
/call SpellSub 1 CastTimer
/delay 30
}
}
}
}
/if n $target(distance)<15 {
/mqlog In melee range
/call autorun2 0
/varset KSCheck $target(id)
/call GetTarget
/if n $KSCheck==$MyTarget /call Melee
|/call checkobstacles
/delay 0
}
/if n $TargetDead!=1 /goto :Engage
/mqlog Target is dead
/target id $MyTarget
/return
| Melee with mob subroutine
sub Melee
/mqlog Started melee
/attack on
/echo Fighting $target(name). It is level $target(level).
:Combat
| Check events
/doevents flush
| Make sure were staring the critter out
/face nopredict
| If we are too far away close in
/if n $target(distance)>15 {
/face nopredict
/delay 2
/call autorun2 1
/mqlog $target(distance,nopredict) from $target(name)
}
| If we are in melee range stop running
/if n $target(distance)<15 {
/call autorun2 0
/delay 2
/mqlog In melee with $target(name) at $target(hp,pct) I am at $char(hp,pct)
}
| If we cannot see the target backup and face it again.
/if n $NoLOS==1 {
/mqlog Cannot see
/face nopredict
/sendkey down down
/delay 4
/sendkey up down
/varset NoLOS 0
/delay 3
}
| If we are too far away close in
/if n $TooFarAway==1 {
/face nopredict
/delay 2
/call autorun2 1
/varset TooFarAway 0
}
/varset v0 $target(name)
/varset v1 $target(id)
/if $char(ability,"Round Kick")>0 /doability "Round Kick"
/if $char(ability,"Kick")>0 /doability "Kick"
/if $char(ability,"Mend")>0 /doability "Mend"
/if $char(ability,"Slam")>0 /doability "Slam"
/if "$char(class)"=="Enchanter" {
/if n $OutRange!=1 {
/call autorun2 0
/face fast nopredict
/delay 10
/varset CastTimer $int($spell(1,casttime)*10+$spell(1,recoverytime)*10)
/call SpellSub 1 CastTimer
}
}
| Check if target is dead or we have lost it
/if n $target(id)==0 /varset TargetDead 1
| If target is still alive keep at it
/if n $TargetDead!=1 /goto :Combat
| Target is dead so stop attacking
/attack off
/return
| Loot mob
sub Loot
/varset TargetLooted 0
:Approach
/mqlog Advancing to corpse
|Process any events
/doevents
| Check we still have a target if not dont try to loot it
/if n $target(id)==0 /goto :Looted
| Turn towards target
/doevents
/face nopredict
| If we are within range loot corpse
/if n $target(distance)<15 {
/call autorun2 0
/loot
/goto :AtTarget
}
| If we are not within range then make sure we are on autorun
/if n $target(distance)>15 /call autorun2 1
| Save our current x,y loc
/varset MyXLoc $char(x)
/varset MyYLoc $char(y)
| Wait and then check loc again if we are on same spot call the obstacle routine to try and get around it
/delay 1
/if n $MyXLoc==$char(x) /if $MyYLoc==$char(y) /call Obstacle
| Check for any obstacles we are supposed to avoid
|/call checkobstacles
/delay 0
/goto :Approach
:AtTarget
|Begin Looting
/mqlog starting to loot
/delay 10
| Cycle through each loot slot
/varset LootSlot 0
:LootLoop
/delay 1
/click left corpse $LootSlot
/delay 3
/if "$cursor()"!="TRUE" /goto :NoLoot
| Scan list of loot to keep and auto drop it if we are keeping it.
/varset CheckLoot 0
:GetLoot
/if "$cursor(name)"~~"$a(1,$CheckLoot)" {
/mqlog Looted $cursor(name)
/click left auto
/goto :Looted
}
/varadd CheckLoot 1
/delay 5
/if n $CheckLoot<$LootTotal /goto :GetLoot
| Checked list of loot to keep with no matches so destroy (must turn on fast destroy)
/mqlog Destroying $cursor(name)
/click left destroy
:Looted
/varadd LootSlot 1
/if "$cursor()"=="TRUE" /left click auto
/call makernum 5
/delay $myrandom
/delay 0
/goto :LootLoop
:NoLoot
/press esc
/doevents
/return
sub HomeBase
/mqlog Heading Home
:RunHome
|Process any events
/doevents
|Work on sense heading skill
/if $char(ability,"Sense Heading")>0 /doability "Sense Heading"
|Check if we have aggroed something and stop running home if we have
/if n $AttackedMe==1 {
/mqlog $v13 Atacked be on the way home
/return
}
| Turn towards target
/face loc $HomeY,$HomeX
| If we are not within melee range then make sure we are on autorun
/if n $distance($HomeY,$HomeX)>15 /call autorun2 1
| Save our current x,y loc
/varset MyXLoc $char(x)
/varset MyYLoc $char(y)
| Wait a then check loc again if we are on same spot call the obstacle routine to try and get around it
/delay 1
/if n $MyXLoc==$char(x) /if $MyYLoc==$char(y) /call Obstacle
| Check foany obstacles we are supposed to avoid
|/call checkobstacles
| If we are within melee range stop running check Target again for other players engaged and attack if all OK.
/if n $distance($HomeY,$HomeX)<15 {
/mqlog Reached Home
/call autorun2 0
/varset BackHome 1
/if n $target(id)==0 /face loc $MyYLoc,$MyXLoc
}
/delay 0
/if n $BackHome!=1 /goto :RunHome
/varset BackHome 0
/return 1
sub Obstacle
| We appear to be stuck so try and backup and strafe sideways
/mqlog Ouch! ran into something
/sendkey up up
/sendkey down down
/call makernum 5
/delay $myrandom
/doevents
/sendkey up down
/sendkey down ctrl
/if n $rand(99)>50 {
/sendkey down right
} else {
/sendkey down left
}
/delay $myrandom
/doevents
/sendkey up right
/sendkey up left
/sendkey up ctrl
/sendkey down up
/return
sub AvoidLoc
| Pass in 3 numbers first two are the Y and X locs of the point to avoid third one is the distance you want to keep from it.
| This sub will check if you are within the distance specified and turn you away from the loc and run you until you are the correct
| distance away. Too many calls to this sub will slow your main loop down badly so keep the areas large and infrequent for best results.
| i.e. if there are a few huts together set a loc and radius that will cover the whole area rather than each individual hut.
/if n $distance($p0,$p1)>$p2 /goto :OK
/mqlog close to $p0 $p1
/if n $calc($heading($p0,$p1)-$char(heading)<0 {
/face heading $calc($heading($p0,$p1)-95)
} else {
/face heading $calc($heading($p0,$p1)+95)
}
:RunAway
/call autorun2 1
/call makernum 5
/delay $myrandom
/if n $distance($p0,$p1)<$p2 /goto :RunAway
:OK
/return
Sub AutoRun2
/if $p0==1 /sendkey down up
/if $p0==0 /sendkey up up
/return
sub Event_TooFar
/varset TooFarAway 1
/return
sub Event_CannotSee
/varset NoLOS 1
/return
sub Event_HitsYou
/attack on
/if "$combat"=="TRUE" /goto :StillEngaged
/varset AttackedMe 1
/varset v10 "$left($calc($instr("YOU","$p0")-1),"$p0")"
/varset v11 $strlen("$v10")
:WalkString
/if "$mid($v11,1,"$v10")"==" " {
/varset v12 $v11
/goto :DoneWalkString
}
/varsub v11 1
/delay 0
/goto :WalkString
:DoneWalkString
/varset Attacker "$left($v12,"$v10")"
/mqlog Being Hit by $Attacker
:StillEngaged
/return
| This Sub sets up the alert lists for the mobs we want to hunt
sub SetAlerts
| Setup Alerts for the most important mobs here (rare)
/alert clear 1
|/alert add 1 npc radius 500 lion
|/alert add 1 npc radius 500 kodiak
|/alert add 1 npc radius 500 puma
|/alert add 1 npc radius 500 orc
|/alert add 1 npc radius 500 aqua
| Setup Alerts for the next most important mobs here (uncommon)
/alert clear 2
|/alert add 2 npc radius 1000 lion
|/alert add 2 npc radius 1000 kodiak
|/alert add 2 npc radius 1000 puma
| Setup Alerts for the next most important mobs here (common)
/alert clear 3
|/alert add 3 npc lion
|/alert add 3 npc kodiak
|/alert add 3 npc puma
|/alert add 3 npc orc
|/alert add 3 npc tizmak
/return
sub makernum
/varset myrandom $calc($rand($int($p0))+1)
/return
sub Event_Bandage50
/varset $bandagedone 1
/delay 5
/return
sub Event_NoBandages
/varset $bandagedone 1
/delay 5
/return
sub Event_Bandageout
/varset $bandagedone 1
/delay 5
/return
sub Event_Bandagefail
/varset $bandagedone 1
/delay 5
/return
sub Event_Bandagedone
/varset $bandagedone 1
/delay 5
/return
sub Event_Zoneing
/endmacro
/return
sub Event_IDied
/endmacro
/return
sub makefearlist
| Setup Alerts for Scary mobs here
/call getstart
/alert clear 4
/varset v1 0
| Loop to find first valid spawn
:ValidLoop
/varset v2 $spawn($v1,next)
/if n $v2==0 {
/varadd v1 1
/goto :ValidLoop
} else {
/varset v1 $v2
}
| Save off the first valid spawn found
/varset v3 $v1
:WalkSpawns
| Loop through all spawns to find a mach
/mqlog $v1
/if n $int($spawn($v1,level))>$int($endlevel) {
/if n $v1!=$char(id) {
/if "$spawn($v1,type)"=="NPC" {
/mqlog id $v1 $spawn($v1,name) is too high for us, avoiding $spawn($v1,level)
/alert add 4 npc radius 400 "$spawn($v1,name)"
/echo adding $spawn($v1,name)
}
}
}
/varset v1 $spawn($v1,next)
/doevents
/if "$spawn($v1,name)"~~"NULL" /goto :donewalkin
/if n $v1!=$v3 /goto :WalkSpawns
:donewalkin
/mqlog finished checking all spawns
/alert add 4 npc radius 500 "merchant"
/alert add 4 npc radius 500 "Eldak Howlingbear"
/alert add 4 npc radius 500 "Zombie"
/alert add 4 npc radius 500 "Hand"
/alert add 4 npc radius 500 "seru"
/return
sub Event_Buffoff
/varset ShieldGone 1
/return
sub Event_OutofRange
/varset OutRange 1
/return
sub Event_CannotSee
/varset NoLOS 1
/return
sub band
:startband
/doevents
/varset $bandagedone 0
/if n $char(hp,pct)>49 /return
/if $char(ability,"Bind Wound")==0 /return
/if $char(ability,"Bind Wound")>0 {
/target myself
/delay 5
/doability "Bind Wound"
/doevents
/if n $char(hp,pct)<49 /goto :startband
}
:skipbandage
/return
sub SetLootList
/varset a(1,0) "pad"
/varset a(1,1) "belt"
/varset a(1,2) "velium"
/varset a(1,3) "silk"
/varset a(1,4) "velium"
/varset a(1,5) "backbone"
/varset a(1,6) "stein"
/varset a(1,7) "blood"
/varset a(1,8) "head"
/varset a(1,9) "arrow"
/varset a(1,10) "oxide"
/varset a(1,11) "diamond"
/varset a(1,12) "ruby"
/varset a(1,13) "saphire"
/varset a(1,14) "pearl"
/varset a(1,15) "emerald"
| Put number of items in list here.
/varset LootTotal 16
/return
sub getstart
/if n $p1==0 /varset startlevel $int($calc($int($char(level))-4))
/if n $p1!=0 /varset startlevel $int($p1)
/varset endlevel $int($calc($int($char(level))-1))
/return




