Code: Select all
|fight.mac
|Automated fight, hunt, group bot for pure melee
#include routines.mac
#define HateListLen v21
#define NoAttack v42
#define NoLOS v38
#define Attacker v60
#define AttackedMe v56
#chat tell
#event CannotSee "You cannot see your target"
#event HitsYou "YOU for"
sub Main
/zapvars
/if n $p0==0 /if "$target()"=="FALSE" {
/echo No Target and No Controller(s)!
/echo Setting up Hunting Loop!
/varset v20 42
/call Hunt
/return
}
/if n $p0==0 /if "$target(type)"=="PC" {
/echo No controller specified! Trying Current Target!
/varset v1 "$target(name)"
/echo $v1 is the Controller!
/call Follow
}
/if n $p0!=0 {
/varset v1 $p0
/echo $v1 is the Controller!
/call Follow
}
/if "$target(type)"=="NPC" {
/echo Target is NPC! Attacking....
/varset v20 42
/call Attack
}
/if "$target(type)"=="Corpse" {
/echo Target is Corpse! Looting....
/varset v20 42
/call Loot
/return
sub Hunt
:huntloop
/doevents
/if n $char(ability,"Sense Heading")>0 /doability sense
/if "$target(type)"=="Corpse" /call Loot
/if "$target(type)"=="NPC" /call Attack
/if "$target()"=="FALSE" /if n $char(hp,pct)<20 /call Rest
/if "$target()"=="FALSE" /target npc range $calc($char(level)-2) $char(level) radius 1000
/delay 5
/if "$target()"=="FALSE" {
/echo No Targets In Range! Waiting 10 seconds...
/delay 10s
}
/goto :huntloop
/return
sub Follow
/echo Following and Assisting "$target(name)"!
/attack off
:followloop
/doevents
/if n $v20!=42 /if n $t0<=0 /call Assist
/if "$target(type)"=="Corpse" /target $v1
/if "$target(name)"=="$char(name)" /target $v1
/if "$target()"=="FALSE" /target $v1
/if "$target(type)"=="NPC" /call Attack
/if n $target(distance)>25 /sendkey down up
/if n $target(distance)<20 /sendkey up up
/face fast nopredict
/goto :followloop
/return
sub Wait
:idleloop
/doevents
/delay 10
/if n $char(ability,"Sense Heading")>0 /doability sense
/goto :idleloop
/return
sub Assist
/varset t0 3s
/assist $v1
/return
sub Attack
/echo Fighting $target(name,clean). It is level $target(level).
/varset v3 "$target(id)"
/varset v4 "$target(name,clean)"
:attackloop
|Check Events
/doevents
|Check Assist, if necessary
/if n "$v20"!="42" /if n $t0<=0 /call Assist
|Check Health
|/if n $char(hp,pct)<20 /call Run
|Don't Attack Until In Range
/if n $target(distance)<=14 /attack on
/if n $target(distance)>=20 /attack off
|Get Into Range
/if n $target(distance)>15 /sendkey down up
/if n $target(distance)<10 /sendkey up up
/face fast nopredict
|If we're too close back up
/if n $NoLOS==1 {
/echo Cannot see, backing up
/face nopredict
/sendkey down down
/delay 2
/sendkey up down
/varset NoLOS 0
/delay 3
}
|Do Abilities
/if n $char(ability,"mend")>0 /doability mend
/if n $char(ability,"Round Kick")>0 /doability round
/if n $char(ability,"Sense Heading")>0 /doability sense
|Check if target is Dead
/if n $target(id)!="$v3" /goto :EndAttack
/goto :attackloop
:EndAttack
/echo $v4 is dead
/delay 10
/sendkey up up
/attack off
/varset v0 0
/target corpse radius 50
/return
sub Event_CannotSee
/varset NoLOS 1
/return
sub Event_HitsYou
/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")"
/echo Attacked by $Attacker!
/echo "$id("$Attacker")"
| Fippys Old Stuff
|/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")"
|/if "$Attacker"~~"$target(name,clean) {
| /varset AttackedMe 0
| /goto :StillEngaged
|/echo Attacked by $Attacker!
|/target $Attacker
| I need a way to get the new aggro's target(id) and this doesn't seem to work...
|/delay 5
|/call AddToHateList $target(id)
|/target $v4
|:StillEngaged
/return
Sub Loot
/if n $target(distance)>75 /goto :continue
/stand
/echo Looting $target(name,clean) for anything that weighs less then 5 and has value of more then $p1 copper...
/face
/if n $target(distance)<15 /goto :CloseEnough
/call AutoRun 1
/varset t0 3m
:CloserAL
/face
/delay 0
/if n $target(distance)>14 /if n $t0>0 /goto :CloserAL
:CloseEnough
/call AutoRun 0
/loot
/Delay 10
/for v10 0 to 9
/Delay 5
/click left corpse $v10
/Delay 10
/if "$cursor(name)"=="NULL" /goto :continue
/if "$target(name)"~~$char(name) /click left auto
/if n $cursor(weight)>5 /click left destroy
/if n $cursor(value)<100 /click left destroy
/if "$cursor(name)"!="NULL" /echo looting "$cursor(name)". it has a value of "$cursor(value)"cp.
/if n $cursor(value)>9 /click left auto
/delay 4
/delay $rand(5)
/next v10
:continue
/delay 5
/delay $rand(5)
/press esc
/return
sub Event_Chat
/echo Recieved Tell from $p1!
/varset v2 "$p1"
/varset v3 "$p2"
/call Commands
/if "$p1"=="$v1" /call Commands
/if "$p1"!="$v1" {
/mqlog $p0 from $p1: $p2
/beep
}
/return
sub Commands
/echo Got to Commands sub!
/if "$v3"~~"attack" {
/call Assist
/r Attacking your target!
/echo $v2 ordered me to attack his target!
/call Attack
/return
}
/if "$v3"~~"follow" {
/target $v2
/r Following You!
/echo $v2 ordered me to follow him!
/call Follow
/return
}
/if "$v3"~~"wait" {
/r I'll wait here...
/echo $v2 ordered me to wait!
/call Wait
/return
}
/if "$v3"~~"rest" {
/echo $v2 ordered me to rest!
/delay 1s
/r Ok, resting...
/call Rest
/return
sub Run
/echo We're in trouble, lets split...
/attack off
/press esc
/target npc guard
/call GotoTarg "$target(name)"
/call Rest
/return
sub Rest
/echo Resting...
/delay 1s
/sit on
:Rest
| Check if something has aggroed and attack it if it has.
/doevents
/if n $AttackedMe==1 {
/echo Aggro While Resting!
/sit off
/goto :NoRest
}
/delay 5
/if n $char(ability,"Sense Heading")>0 /doability sense
/if $char(ability,"Mend")>0 /doability "Mend"
/if n $char(hp,pct)<50 /goto :Rest
/echo Hps at $char(hp,pct) Off hunting again
}
:NoRest
/stand
/return
Sub DisplayHateList
| Spit out your hate list to the screen
/echo
/echo ListLen: $HateListLen
/echo ---------------------
/for v95 1 to $HateListLen
/target id $a(0,$v95)
/echo $v95 ID: $a(0,$v95)
/echo $v95 LV: $target(level)
/echo $v95 NM: $target(name)
/echo ---------------------
/next v95
/echo
/return
Sub AddToHateList
| v90 - Hold ID
| v91 - Hold Lvl
| v92 - Current HateList Level
| v93 - Swap ID
| v95 - For Loop Var
| Set the new ID into the hold var
/varset v90 $p0
/echo Adding $v90 to HateList
| Get his level into v91
/target id $v90
/varset v91 $target(level)
| If he's not the first, make sure he's put into the right place.
| We want to order out hate list in order of strongest mob
/if $HateListLen>1 {
/for v95 1 to $HateListLen
| Check the level of the current mob
/target id $a(0,$HateListLen)
/varset v92 $target(level)
/if $v92<$v91 { | New guy is stronger, time to reorder
/varset v93 $a(0,$v95) | Store old one to Swap ID
/varset a(0,$v95) $v90 | Put stronger guy in list
/varset v90 $v93 | Put old one into Hold ID
/varset v91 $v92 | Old level into Hold Lvl
}
/next v95
| Add whats left in Hold ID to the list
/varcalc HateListLen $HateListLen+1
/varset a(0,$HateListLen) $v90
} else {
/varcalc HateListLen $HateListLen+1
/varset a(0,$HateListLen) $p0
}
/return
Sub CleanUpScreen
/sendkey up ctrl
/sendkey up shift
/sendkey up alt
/press esc
/press esc
/press esc
/sit off
/delay 2
/return
Zertful Newbiecoder
PS: Thanks for all the ideas and code: L1ZARD, Fippy, Nerfy

