click

Have a macro idea but not sure where to start? Ask here.

Moderator: MacroQuest Developers

Rassilon
a lesser mummy
a lesser mummy
Posts: 73
Joined: Thu Sep 04, 2003 6:34 pm

click

Post by Rassilon » Sun May 02, 2004 2:55 pm

Can someone convert click.mac to work with new MQ2?

Thanks

SomeEqDude
orc pawn
orc pawn
Posts: 26
Joined: Sun Dec 07, 2003 6:44 am

Post by SomeEqDude » Sun May 02, 2004 8:17 pm

Here's a start...Pre-MQ2Vars
Only tested as afar as it actually worked if you had your epic, and not very complex .INI.

| Click.mac - v2.21 - Resurrect corpses around you - by blueninja
| Resurrects all corpses within a radius using the cleric epic or spell
| Resurrects high priority classes first as defined in the ini file
|
| Usage:
| /macro click [radius] [only] [con/nocon] [racecheck/noracecheck] [useblacklist/noblacklist]
| [usespell/useepic] [sit/stand] [spellname] <nameofspell> [spellslot] <X> [prioritygroup0]
| [prioritygroup1] [prioritygroup2]...
| /macro click buildraces
| [radius] - set radius to look for corpses in, default value is in ini file
| [only] - stop ressing after corpses in priority groups have been ressed
| [con/nocon] - toggle /consider to test if corpse is pc or npc
| [racecheck/noracecheck] - toggle check for race to test if corpse is pc or npc
| (requires ini file)
| [useblacklist/noblacklist] - toggle check for blacklisted corpses
| (requires ini file)
| [usespell/useepic] - use epic or spell to resurrect
| [sit/stand] - toggle sitting while not casting to regen mana
| [spellname] <nameofspell> - name of spell to use if using spell
| [spellslot] <X> - spell gem number to use for spell if using spell
| [prioritygroupX] - names of groups to res before others
|
| [buildraces] - update list of player races in ini file
|
| Example:
| /macro click 200 nocon dps healers
| /macro click 200 only cr
| /macro click usespell 150 only cr spellname resurrection spellslot 5
| /macro click buildraces
|
| Make sure you set CLICKINIFILE a few lines down to a valid filename
| You probably want to run this with '/filter macros enhanced' to avoid targeting spam

#turbo

|Make sure you set this to point to a valid location
#define CLICKINIFILE "click.ini"
#define MEMDELAY 30
#define DEFAULTSPELL Reviviscence

#event interrupt "Your spell is interrupted"
#event notequipped "You cannot use this item unless it is equipped."
#event notmemmed "You do not seem to have that spell memorized."
#event willdecay "This corpse will decay in"
#event restime "This corpse's resurrection time will expire in "
#event corpsetooold "This corpse is too old to be resurrected."
#event clickedoldcorpse "This player cannot be resurrected. The corpse is too old."
#event corpseexpire "This corpse is waiting to expire."
#event couldnotrez "You were unable to restore the corpse to life, but you may have success with a later attempt."
#event youmustbestanding "You must be standing to cast a spell."
#event fizzle "Your spell fizzles!"
#event oom "Insufficient Mana to cast this spell"

Sub Event_restime
|Got a message that the corpse has time left on rez timer
/varset ispccorpse 1
/return

Sub Event_willdecay
|Since the rez time message comes before the expiry time message the
|event should fire now
/doevents restime

|Small pause to be sure
/if (@ispccorpse!=1) {
/delay 5
/doevents restime
}
/varset gotconmsg 1
/return

Sub Event_corpsetooold
|Corpse too old to rez, treat as npc corpse
/varset gotconmsg 0
/return

Sub Event_corpseexpire
|Corpse about to poof, treat as npc corpse
/varset gotconmsg 0
/return

Sub Event_couldnotrez
/varadd couldnot 1
/return

Sub Event_clickedoldcorpse
| Tried to resurrect a corpse that was too old
| Remove from statistics
/varsub clicked 1
/varset status 1
/return

Sub Event_interrupt
/if (${Me.State.Equal["DUCK"]}) {
/varset status 1
/varsub clicked 1
/call output 4 "Ducked, moving to next.."
} else {
/varset status 2
}
/return

Sub Event_fizzle
/varset status 2
/return

Sub Event_oom
/varset status 3
/return

Sub Event_notequipped
/beep
/call output 1 "ERROR: Epic is in an inventory slot, need to equip it in primary"
/endmacro
/return

Sub Event_notmemmed
/call sitdown
/if (@usespell==0) {
/beep
/call output 1 "ERROR: Epic is bagged or banked"
/endmacro
} else {
| Memorize spell
/call output 3 "Spell @spellname not memorized"
/memspell "@spellslot" "@spellname"
/delay MEMDELAY
| Check if it's memmed now, otherwise quit
/if (!${Me.Gem[@spellslot].Name.Equal["@spellname"]}) {
/call output 1 "Couldn't memorize spell @spellname"
/endmacro
}
/varset status 4

}
/return

Sub Event_youmustbestanding
/varset status 2
/call output 4 "Standing up.."
/call standup
/return


Sub Main

/declare status global
/declare ispccorpse global
/declare gotconmsg global
/declare oldtargetid local
/declare radius local
/declare contimer timer
/declare timeouts global
/declare corpses global
/declare skippedrace global
/declare skippedcon global
/declare skippedblacklist global

/declare clicked global
/declare couldnot global
|prios(x,y) - contains name of profile in (x,0) and number of filters in profile in (x,1)
/declare prios array2
/declare priocount global
|priofilters(x,y) - y=0..prios(x,1) contains the values of the filters for prios(x,0)
/declare priofilters array2
/declare only local
/declare argloop local
/declare racecount global
|List of valid player races
/declare races array
/declare curid global

/declare spellmaxrange local

/declare noiselevel global
/declare contimeout global
/declare defaultradius local
/declare showstats local
/declare useraces global
/declare consider global
/declare usespell global
/declare spellname global
/declare spellslot global
/declare useblacklist global
/declare sit global

/varset noiselevel 0

|Read configuration
/call getconfig "noiselevel" 2
/varset noiselevel ${Macro.Return}
/call getconfig "contimeout" 50
/varset contimeout ${Macro.Return}
/call getconfig "defaultradius" 100
/varset defaultradius ${Macro.Return}
/call getconfig "showstats" 1
/varset showstats ${Macro.Return}
/call getconfig "useraces" 0
/varset useraces ${Macro.Return}
/call getconfig "consider" 1
/varset consider ${Macro.Return}
/call getconfig "useblacklist" 0
/varset useblacklist ${Macro.Return}
/call getconfig "usespell" 0
/varset usespell ${Macro.Return}
/call getconfig "spellname" DEFAULTSPELL
/varset spellname ${Macro.Return}
/call getconfig "spellslot" 8
/varset spellslot ${Macro.Return}
/call getconfig "sit" 0
/varset sit ${Macro.Return}

/varset corpses 0
/varset clicked 0
/varset skippedrace 0
/varset skippedcon 0
/varset timeouts 0
/varset skippedblacklist 0
/varset couldnot 0
/varset only 0
/varset radius @defaultradius
/varset priocount -1
/varset spellmaxrange 200


|Check if parameter is passed
/for argloop 0 to 10
/if (${Defined[Param@argloop]}) {
/call IsNumeric "@Param@argloop"

/if ("${Macro.Return}"=="false") {
|non-numeric argument
/if ("@Param@argloop"=="only") {
/varset only 1
} else /if ("@Param@argloop"=="buildraces") {
/call buildini
/endmacro
} else /if ("@Param@argloop"=="noracecheck") {
/varset useraces 0
} else /if ("@Param@argloop"=="racecheck") {
/varset useraces 1
} else /if ("@Param@argloop"=="noblacklist") {
/varset useblacklist 0
} else /if ("@Param@argloop"=="useblacklist") {
/varset useblacklist 1
} else /if ("@Param@argloop"=="usespell") {
/varset usespell 1
} else /if ("@Param@argloop"=="useepic") {
/varset usespell 0
} else /if ("@Param@argloop"=="sit") {
/varset sit 1
} else /if ("@Param@argloop"=="stand") {
/varset sit 0
} else /if ("@Param@argloop"=="nocon") {
/varset consider 0
} else /if ("@Param@argloop"=="con") {
/varset consider 1
} else /if ("@Param@argloop"=="spellname") {
/varadd argloop 1
/varset spellname "@Param$int(@argloop)"
} else /if ("@Param@argloop"=="spellslot") {
/varadd argloop 1
/varset spellslot "@Param$int(@argloop)"
} else {
/varadd priocount 1
/varset prios(@priocount,0) "@Param@argloop"
/call buildprios "@Param@argloop" @priocount
/varset prios(@priocount,1) ${Macro.Return}
}

} else {
|Numeric argument, set radius
/varset radius @Param@argloop
}
} else {
|No argument passed, default
/goto :argsdone
}
/next argloop

:argsdone
/call sitdown
/if (@usespell==1) {
/varset spellmaxrange ${Spell[@spellname].Range}
}
/if (@radius>@spellmaxrange) {
/call output 2 "WARNING: Radius larger than range of spell, setting to @spellmaxrange"
/varset radius @spellmaxrange
}
/varadd priocount 1
|If we havent found any profiles on command line, set first one to default
/if (@priocount==0) {
/varset prios(@priocount,0) "default"
/call buildprios "default" @priocount
/varset prios(@priocount,1) ${Macro.Return}
/varset priocount 1
}

|Build an array of valid player races from ini file
/if (@useraces==1) {
/varset racecount -1

:iniloop
/varadd racecount 1
/varset races($int(@racecount)) "${Ini[@CLICKINIFILE,races,@racecount,NOTFOUND)}"
/if ("@races($int(@racecount))"=="NOTFOUND") /goto :leaveloop
/goto :iniloop
}

:leaveloop
|Read the blacklist after the normal profiles
/varset prios(@priocount,0) "blacklist"
/call buildprios "blacklist" @priocount
/varset prios(@priocount,1) ${Macro.Return}


|First loop through high priority classes..

/varset curid 0
/echo Doing priority corpses
/declare corpsecnt local
/varset corpsecnt 1

/for argloop 0 to ${Math.Calc[@priocount-1].Int}
/varset corpsecnt 0
:loopprio
/varset corpsecnt ${Math.Calc[@corpsecnt+1]}
/doevents
/varset status 0
/varset oldtargetid @curid
/varset curid ${Spawn[corpse radius @radius next id:@oldtargetid].ID}
/varset curid ${NearestSpawn[@corpsecnt,corpse radius @radius].ID}
|If we didn't get a new target move on to low priority
/if (@curid==0) /goto :clicktherest

|Check if this is a high priority corpse
/call HasPriority @prios(@argloop,0) @curid
/if (!${Macro.Return.Equal["true"]}) /goto :loopprio
/echo Rezzing ${Spawn[@curid].Name}
/call clickit @curid
|Gather statistics
/doevents couldnotrez
/goto :loopprio

:clicktherest
/next argloop
/echo Doing low priority corpses

|If parameter 'only' is specified don't move on to low priority corpses
/if (@only==1) /goto :end
/varset curid 0
/varset corpsecnt 0

|.. then everyone else
:restloop
/varset corpsecnt ${Math.Calc[@corpsecnt+1]}
/doevents
/varset status 0
/varset oldtargetid @curid
/varset curid ${NearestSpawn[@corpsecnt,corpse radius @radius].ID}
|If we didn't get a new target quit
/if (@curid==0) /goto :end

|Check that this isn't a priority corpse
/for argloop 0 to ${Math.Calc[@priocount-1]}
/call HasPriority @prios(@argloop,0) @curid
/if (${Macro.Return.Equal["true"]}) /goto :restloop
/next argloop
/echo Rezzing ${Spawn[@curid].Name}
/call clickit @curid
|Gather statistics
/doevents couldnotrez
/goto :restloop

:end
|Gather statistics
/call sitdown
/doevents couldnotrez
/if (@showstats==1) /call statsub

/return

Sub getconfig(key,default)
|Read the value of a [config] parameter in ini file
|/call getconfig "paramname" "defaultvalue"
|Returns value
/if (!${Defined[key]}) /return "false"
/if (!${Defined[default]}) /return "false"

/declare inivalue local

/varset inivalue ${Ini[@CLICKINIFILE,config,@key,@default]}
/return "@inivalue"

Sub output
|Echo that uses the noiselevel setting
/if (!${Defined[Param0]}) /return
/if (!${Defined[Param1]}) /return
/if (@Param0<=@noiselevel) {
/echo @Param1
}
/return

Sub IsNumeric
|Returns true if Param0 is numeric, false if not
/if (!${Defined[Param0]}) /return "false"
/if (${String[@Param0].Length}==0) /return "false"
/declare counter local

/for counter 1 to ${String[@Param0].Length}
/if (${String[@Param0].Mid[@counter,1]}<"0" || ${String[@Param0].Mid[@counter,1]}>"9") /return "false"
/next counter
/return "true"

Sub statsub
|Display stats
/declare runtime local
/declare runstring local
/varset runtime ${Macro.RunTime}
/echo Corpses found: ${Int[@corpses]}, ressed: ${Int[@clicked]}, could not restore: ${Int[@couldnot]}
/echo Skipped race: ${Int[@skippedrace]}, Skipped con: ${Int[@skippedcon]}, Skipped blacklist: ${Int[@skippedblacklist]}
/varset runstring "Time taken ${Int[${Math.Calc[@runtime/60]}]} minutes ${Int[${Math.Calc[@runtime%60]}]} seconds"
/if (@timeouts>0) /echo Consider timeouts: @timeouts
/if (@corpses>0) /varset runstring "@runstring (avg time per corpse: ${Math.Calc[@runtime/@corpses]}s)"
/echo @runstring
/return

Sub buildprios(Param0,Param1)
|Builds priority lists from ini file into priofilters(@Param1,y)
|@Param0 is the name of the profile
/declare filters local
/declare temp local
/declare curfilt local
/declare pipeloc local
/declare nextpipe local
/declare filtercount local
/if (!${Defined[Param0]}) /return
/varset filters "${Ini[@CLICKINIFILE,@Param0,-1,NOTFOUND]}"
/if (${String["@filters"].Equal["NOTFOUND"]}) {
/if (${String["@Param0"].Equal["default"]}) {
||If default is empty, set defaults to bards and clerics
/varset priofilters(@Param1,0) "cBard"
/varset priofilters(@Param1,1) "cEnchanter"
/varset priofilters(@Param1,2) "cCleric"
/return 3
} else {
/return -1
}
}

/varset filters $left($calc($strlen(@filters)-2),@filters)

/varset filtercount 0

/varset nextpipe $instr("|",@filters)

/if n @nextpipe<0 {
/varset priofilters(@Param1,0) $left(1,@filters)"$ini("CLICKINIFILE","@Param0","@filters")"
/goto :leavebuildprios
}

:loopfilters
/varset curfilt $mid(0,@nextpipe,@filters)
/varset filters $right($calc($strlen(@filters)-@nextpipe-1),@filters)
/varset temp $ini("CLICKINIFILE","@Param0",curfilt)

/varset priofilters(@Param1,@filtercount) $left(1,@curfilt)"$ini("CLICKINIFILE","@Param0","@curfilt")"
/varset nextpipe $instr("|",@filters)
/varadd filtercount 1

/if n @nextpipe<0 {
/varset priofilters(@Param1,@filtercount) $left(1,@filters)"$ini("CLICKINIFILE","@Param0","@filters")"
/goto :leavebuildprios
}

/goto :loopfilters

:leavebuildprios
/varadd filtercount 1

/return @filtercount

Sub HasPriority(Param0,Param1)
|Test if corpse with id @Param1 has high priority in profile @Param0
/declare test local
/declare hpcount local
/declare filtnum local
/if (!${Defined[Param0]}) {
/varset test default
} else {
/varset test @Param0
}
/echo @Param0
/end
/call findprioinarray "@test"
/echo Checking Priority on ${Spawn[@test].Name} @prios(${Macro.Return},1)
/if (@prios(${Macro.Return},1)<=0) /return "false"

/varset filtnum ${Macro.Return}

/for hpcount 0 to $calc(@prios(@filtnum,1)-1)
/if (${String[@priofilters(@filtnum,@hpcount)].Left[1].Equal["c"]}) {
/if (${Spawn[@Param1].Class.Equal[${String[@priofilters(@filtnum,@hpcount)].Right[-1]}]}) {
/return "true"
}
} else /if (${String[@priofilters(@filtnum,@hpcount)].Left[1].Equal["n"]}) {
/if "$spawn(@Param1,name)"~~"$right($calc($strlen("@priofilters(@filtnum,@hpcount)")-1),"@priofilters(@filtnum,@hpcount)")" {
/return "true"
}
} else /if (${String[@priofilters(@filtnum,@hpcount)].Left[1].Equal["g"]}) {
/if "$spawn(@Param1,guild)"=="$right($calc($strlen("@priofilters(@filtnum,@hpcount)")-1),"@priofilters(@filtnum,@hpcount)")" {
/return "true"
}
}

/next hpcount
/return "false"

Sub findprioinarray
|Search array for @Param0, returns the location or -1 if not found

/declare counter local
/for counter 0 to @priocount
/if (${String[@Param0].Equal[@prios(@counter,0)]}) /return @counter
/next counter
/return -1

Sub IsPCRace
|Test if race of corpse with id @Param0 is in the array of valid races
/declare loopcounter local
/for loopcounter 0 to @racecount
/if "$spawn(@Param0,race)"=="@races($int(@loopcounter))" /return "true"
/next loopcounter

/return "false"

Sub clickit
/declare counter local
/declare giveup local
/declare castwait local

|Test if valid race
/if (@useraces==1) {
/call IsPCRace @Param0
/if (${Macro.Return.Equal["false"]}) {
/varadd skippedrace 1
/return
}
}


/if (@useblacklist==0) /goto :skipblacklist
|Check if corpse is blacklisted
/call HasPriority "blacklist" @curid
/if (${Macro.Return.Equal["true"]}) {
/call output 3 "Skipping blacklisted ${Spawn[@curid].Name}"
/varadd skippedblacklist 1
/return
}

:skipblacklist

|Target corpse
/tar id @Param0
/if (!${Target.ID}) /return

/varadd corpses 1

|Doevents to get stats and flush /con messages
/doevents

/if (@consider==1) {
/varset ispccorpse 0
/varset gotconmsg 0

/consider

|Set timer so we don't get stuck waiting for a /con message
/varset contimer @contimeout

:waitcon
/doevents corpseexpire
/doevents willdecay
/delay 1
|After a few seconds give up and assume it's a pc corpse
/if (@contimer==0) {
/call output 3 "Timeout waiting for /con message, assuming pc corpse"
/varadd timeouts 1
/varset gotconmsg 1
/varset ispccorpse 1
}
/if (@gotconmsg==0) /goto :waitcon

/if (@ispccorpse!=1) {
/varadd skippedcon 1
/call output 3 "Skipping $target(name)"
/return
}
}
/varadd clicked 1

|Counter to give up after 4 attempts at rezzing a corpse
|that fail either by interrupt or if we can't cast for 3 seconds
/varset giveup 0

:tryagain
/varadd giveup 1

|Too many tries, move on to next
/if (@giveup>4) /return

/varset status 0
/varset castwait 0

|Wait until we are not casting, if we wait too long, treat as an interrupt
:waitforcast
/if (!${Me.Casting.ID}) /goto :castit
/delay 5
/varadd castwait 1
/if (@castwait>5) /goto :tryagain
/goto :waitforcast

:castit
/call output 3 "Resurrecting $target(name)"
/hail
/if (@usespell==0) {
| Use epic
/call standup
/cast item "water sprinkler of nem ankh"
} else {
| Use spell

:waitspellrefresh
| Check if enough mana, if not med until there is enough
/if (${Me.CurrentMana}<${Spell[@spellname].Mana}) /call medup

| Wait until spell is refreshed
/if (!${Me.SpellReady[@spellname]}) {
/delay 1
/goto :waitspellrefresh
}
/call standup

/cast @spellname
}

|Wait until not casting anymore
:castdelay
/delay 5
/doevents
/if (@status==4) {
/varsub giveup 1
/goto :tryagain
}
/if (@status==3) {
/varsub giveup 1
/call medup
/goto :tryagain
}
/if (@status==2) /goto :tryagain
/if (@status==1) {
/call sitdown
/return
}
/if (${Me.Casting.ID}) /goto :castdelay

/call sitdown

/return

Sub medup
/call sitdown
| Loop until enough mana to cast
:medloop
/delay 1s
/if (${Me.CurrentMana}<${Spell[@spellname].Mana}) /goto :medloop

/call standup
/return

Sub sitdown
| Don't bother sitting if full mana
/if (${Me.PctMana}==100) /return
| Check sit setting
/if (@sit==0) /return
| Don't try to sit if on a mount
/if (${Me.Mount.ID}) /return
| If not sitting, sit down
/if (!${Me.State.Equal["SIT"]}) /sit
/return

Sub standup
| Don't try to stand if on a mount
/if (${Me.Mount.ID}) /return
| If not standing, stand up
/if (!${Me.State.Equal["STAND"]}) /stand
/return

Sub buildini
|Loop through the players in zone and compare their race to the list of valid
|player races in ini file and add new races
/declare currace local
/declare curid local
/varset racecount -1

|Read races from ini file
:buildiniloop
/varadd racecount 1
/varset races($int(@racecount)) "$ini("CLICKINIFILE","races",$int(@racecount))"
/if "@races($int(@racecount))"=="NOTFOUND" /goto :buildleaveloop
/goto :buildiniloop

:buildleaveloop
/declare oldtarget local
/declare added local

/varset added 0
/declare pccount local

/varset pccount 0
|Get first pc
/varset curid $searchspawn(pc)
/varset currace "$spawn(@curid,race)"

:buildloop

/varadd pccount 1
|See if race is in array already
/call buildisinarray "@currace"
/if n ${Macro.Return}==0 {
|New race, add to ini
/if ("$defined(currace)"!="FALSE" && "@currace"!="NULL") {
/ini "CLICKINIFILE" "races" $int(@racecount) "@currace"
/varset races(@racecount) "@currace"
/varadd racecount 1
/varadd added 1
/call output 2 "Added race: @currace"
}
}
/varset curid $searchspawn(pc,next,id:@curid)
/varset currace "$spawn(@curid,race)"
/if n @curid==0 /goto :buildend

/goto :buildloop
:buildend
/call output 2 "Players counted: $int(@pccount) Races in ini: $int(@racecount), added $int(@added)"

/return

Sub buildisinarray
|Search array for @Param0
/declare loopcounter local
/for loopcounter 0 to $calc(@racecount-1)
/if "@Param0"=="@races($int(@loopcounter))" {
/return 1
}
/next loopcounter
/return 0

SomeEqDude
orc pawn
orc pawn
Posts: 26
Joined: Sun Dec 07, 2003 6:44 am

Post by SomeEqDude » Sun May 02, 2004 8:49 pm

Here's a quick stab at a MQ2Vars version, *not tested at all*

| Click.mac - v2.21 - Resurrect corpses around you - by blueninja
| Resurrects all corpses within a radius using the cleric epic or spell
| Resurrects high priority classes first as defined in the ini file
|
| Usage:
| /macro click [radius] [only] [con/nocon] [racecheck/noracecheck] [useblacklist/noblacklist]
| [usespell/useepic] [sit/stand] [spellname] <nameofspell> [spellslot] <X> [prioritygroup0]
| [prioritygroup1] [prioritygroup2]...
| /macro click buildraces
| [radius] - set radius to look for corpses in, default value is in ini file
| [only] - stop ressing after corpses in priority groups have been ressed
| [con/nocon] - toggle /consider to test if corpse is pc or npc
| [racecheck/noracecheck] - toggle check for race to test if corpse is pc or npc
| (requires ini file)
| [useblacklist/noblacklist] - toggle check for blacklisted corpses
| (requires ini file)
| [usespell/useepic] - use epic or spell to resurrect
| [sit/stand] - toggle sitting while not casting to regen mana
| [spellname] <nameofspell> - name of spell to use if using spell
| [spellslot] <X> - spell gem number to use for spell if using spell
| [prioritygroupX] - names of groups to res before others
|
| [buildraces] - update list of player races in ini file
|
| Example:
| /macro click 200 nocon dps healers
| /macro click 200 only cr
| /macro click usespell 150 only cr spellname resurrection spellslot 5
| /macro click buildraces
|
| Make sure you set CLICKINIFILE a few lines down to a valid filename
| You probably want to run this with '/filter macros enhanced' to avoid targeting spam

#turbo

|Make sure you set this to point to a valid location
#define CLICKINIFILE "click.ini"
#define MEMDELAY 30
#define DEFAULTSPELL Reviviscence

#event interrupt "Your spell is interrupted"
#event notequipped "You cannot use this item unless it is equipped."
#event notmemmed "You do not seem to have that spell memorized."
#event willdecay "This corpse will decay in"
#event restime "This corpse's resurrection time will expire in "
#event corpsetooold "This corpse is too old to be resurrected."
#event clickedoldcorpse "This player cannot be resurrected. The corpse is too old."
#event corpseexpire "This corpse is waiting to expire."
#event couldnotrez "You were unable to restore the corpse to life, but you may have success with a later attempt."
#event youmustbestanding "You must be standing to cast a spell."
#event fizzle "Your spell fizzles!"
#event oom "Insufficient Mana to cast this spell"

Sub Event_restime
|Got a message that the corpse has time left on rez timer
/varset ispccorpse 1
/return

Sub Event_willdecay
|Since the rez time message comes before the expiry time message the
|event should fire now
/doevents restime

|Small pause to be sure
/if (${ispccorpse}!=1) {
/delay 5
/doevents restime
}
/varset gotconmsg 1
/return

Sub Event_corpsetooold
|Corpse too old to rez, treat as npc corpse
/varset gotconmsg 0
/return

Sub Event_corpseexpire
|Corpse about to poof, treat as npc corpse
/varset gotconmsg 0
/return

Sub Event_couldnotrez
/varadd couldnot 1
/return

Sub Event_clickedoldcorpse
| Tried to resurrect a corpse that was too old
| Remove from statistics
/varsub clicked 1
/varset status 1
/return

Sub Event_interrupt
/if (${Me.State.Equal["DUCK"]}) {
/varset status 1
/varsub clicked 1
/call output 4 "Ducked, moving to next.."
} else {
/varset status 2
}
/return

Sub Event_fizzle
/varset status 2
/return

Sub Event_oom
/varset status 3
/return

Sub Event_notequipped
/beep
/call output 1 "ERROR: Epic is in an inventory slot, need to equip it in primary"
/endmacro
/return

Sub Event_notmemmed
/call sitdown
/if (${usespell}==0) {
/beep
/call output 1 "ERROR: Epic is bagged or banked"
/endmacro
} else {
| Memorize spell
/call output 3 "Spell ${spellname} not memorized"
/memspell "${spellslot}" "${spellname}"
/delay MEMDELAY
| Check if it's memmed now, otherwise quit
/if (!${Me.Gem[${spellslot}].Name.Equal["${spellname}"]}) {
/call output 1 "Couldn't memorize spell ${spellname}"
/endmacro
}
/varset status 4

}
/return

Sub Event_youmustbestanding
/varset status 2
/call output 4 "Standing up.."
/call standup
/return


Sub Main

/declare status outer
/declare ispccorpse outer
/declare gotconmsg outer
/declare oldtargetid local
/declare radius local
/declare contimer timer
/declare timeouts outer
/declare corpses outer
/declare skippedrace outer
/declare skippedcon outer
/declare skippedblacklist outer

/declare clicked outer
/declare couldnot outer
|prios(x,y) - contains name of profile in (x,0) and number of filters in profile in (x,1)
/declare prios array2
/declare priocount outer
|priofilters(x,y) - y=0..prios(x,1) contains the values of the filters for prios(x,0)
/declare priofilters array2
/declare only local
/declare argloop int local
/declare racecount int outer
|List of valid player races
/declare races array
/declare curid outer

/declare spellmaxrange local

/declare noiselevel outer
/declare contimeout outer
/declare defaultradius local
/declare showstats local
/declare useraces outer
/declare consider outer
/declare usespell outer
/declare spellname outer
/declare spellslot outer
/declare useblacklist outer
/declare sit outer

/varset noiselevel 0

|Read configuration
/call getconfig "noiselevel" 2
/varset noiselevel ${Macro.Return}
/call getconfig "contimeout" 50
/varset contimeout ${Macro.Return}
/call getconfig "defaultradius" 100
/varset defaultradius ${Macro.Return}
/call getconfig "showstats" 1
/varset showstats ${Macro.Return}
/call getconfig "useraces" 0
/varset useraces ${Macro.Return}
/call getconfig "consider" 1
/varset consider ${Macro.Return}
/call getconfig "useblacklist" 0
/varset useblacklist ${Macro.Return}
/call getconfig "usespell" 0
/varset usespell ${Macro.Return}
/call getconfig "spellname" DEFAULTSPELL
/varset spellname ${Macro.Return}
/call getconfig "spellslot" 8
/varset spellslot ${Macro.Return}
/call getconfig "sit" 0
/varset sit ${Macro.Return}

/varset corpses 0
/varset clicked 0
/varset skippedrace 0
/varset skippedcon 0
/varset timeouts 0
/varset skippedblacklist 0
/varset couldnot 0
/varset only 0
/varset radius ${defaultradius}
/varset priocount -1
/varset spellmaxrange 200


|Check if parameter is passed
/for argloop 0 to 10
/if (${Defined[Param${argloop}]}) {
/call IsNumeric "${Param}${argloop}"

/if ("${Macro.Return}"=="false") {
|non-numeric argument
/if ("${Param}${argloop}"=="only") {
/varset only 1
} else /if ("${Param}${argloop}"=="buildraces") {
/call buildini
/endmacro
} else /if ("${Param}${argloop}"=="noracecheck") {
/varset useraces 0
} else /if ("${Param}${argloop}"=="racecheck") {
/varset useraces 1
} else /if ("${Param}${argloop}"=="noblacklist") {
/varset useblacklist 0
} else /if ("${Param}${argloop}"=="useblacklist") {
/varset useblacklist 1
} else /if ("${Param}${argloop}"=="usespell") {
/varset usespell 1
} else /if ("${Param}${argloop}"=="useepic") {
/varset usespell 0
} else /if ("${Param}${argloop}"=="sit") {
/varset sit 1
} else /if ("${Param}${argloop}"=="stand") {
/varset sit 0
} else /if ("${Param}${argloop}"=="nocon") {
/varset consider 0
} else /if ("${Param}${argloop}"=="con") {
/varset consider 1
} else /if ("${Param}${argloop}"=="spellname") {
/varadd argloop 1
/varset spellname "${Param}${argloop}"
} else /if ("${Param}${argloop}"=="spellslot") {
/varadd argloop 1
/varset spellslot "${Param}${argloop}"
} else {
/varadd priocount 1
/varset prios(${priocount},0) "${Param}${argloop}"
/call buildprios "${Param}${argloop}" ${priocount}
/varset prios(${priocount},1) ${Macro.Return}
}

} else {
|Numeric argument, set radius
/varset radius ${Param}${argloop}
}
} else {
|No argument passed, default
/goto :argsdone
}
/next argloop

:argsdone
/call sitdown
/if (${usespell}==1) {
/varset spellmaxrange ${Spell[${spellname}].Range}
}
/if (${radius}>${spellmaxrange}) {
/call output 2 "WARNING: Radius larger than range of spell, setting to ${spellmaxrange}"
/varset radius ${spellmaxrange}
}
/varadd priocount 1
|If we havent found any profiles on command line, set first one to default
/if (${priocount}==0) {
/varset prios(${priocount},0) "default"
/call buildprios "default" ${priocount}
/varset prios(${priocount},1) ${Macro.Return}
/varset priocount 1
}

|Build an array of valid player races from ini file
/if (${useraces}==1) {
/varset racecount -1

:iniloop
/varadd racecount 1
/varset races(${racecount}) "${Ini[${CLICKINIFILE},races,${racecount},NOTFOUND)}"
/if ("${races}(${racecount})"=="NOTFOUND") /goto :leaveloop
/goto :iniloop
}

:leaveloop
|Read the blacklist after the normal profiles
/varset prios(${priocount},0) "blacklist"
/call buildprios "blacklist" ${priocount}
/varset prios(${priocount},1) ${Macro.Return}


|First loop through high priority classes..

/varset curid 0
/echo Doing priority corpses
/declare corpsecnt local
/varset corpsecnt 1

/for argloop 0 to ${Math.Calc[${priocount}-1].Int}
/varset corpsecnt 0
:loopprio
/varset corpsecnt ${Math.Calc[${corpsecnt}+1]}
/doevents
/varset status 0
/varset oldtargetid ${curid}
/varset curid ${Spawn[corpse radius ${radius} next id:${oldtargetid}].ID}
/varset curid ${NearestSpawn[${corpsecnt},corpse radius ${radius}].ID}
|If we didn't get a new target move on to low priority
/if (${curid}==0) /goto :clicktherest

|Check if this is a high priority corpse
/call HasPriority ${prios}(${argloop},0) ${curid}
/if (!${Macro.Return.Equal["true"]}) /goto :loopprio
/echo Rezzing ${Spawn[${curid}].Name}
/call clickit ${curid}
|Gather statistics
/doevents couldnotrez
/goto :loopprio

:clicktherest
/next argloop
/echo Doing low priority corpses

|If parameter 'only' is specified don't move on to low priority corpses
/if (${only}==1) /goto :end
/varset curid 0
/varset corpsecnt 0

|.. then everyone else
:restloop
/varset corpsecnt ${Math.Calc[${corpsecnt}+1]}
/doevents
/varset status 0
/varset oldtargetid ${curid}
/varset curid ${NearestSpawn[${corpsecnt},corpse radius ${radius}].ID}
|If we didn't get a new target quit
/if (${curid}==0) /goto :end

|Check that this isn't a priority corpse
/for argloop 0 to ${Math.Calc[${priocount}-1]}
/call HasPriority ${prios}(${argloop},0) ${curid}
/if (${Macro.Return.Equal["true"]}) /goto :restloop
/next argloop
/echo Rezzing ${Spawn[${curid}].Name}
/call clickit ${curid}
|Gather statistics
/doevents couldnotrez
/goto :restloop

:end
|Gather statistics
/call sitdown
/doevents couldnotrez
/if (${showstats}==1) /call statsub

/return

Sub getconfig(key,default)
|Read the value of a [config] parameter in ini file
|/call getconfig "paramname" "defaultvalue"
|Returns value
/if (!${Defined[key]}) /return "false"
/if (!${Defined[default]}) /return "false"

/declare inivalue local

/varset inivalue ${Ini[${CLICKINIFILE},config,${key},${default}]}
/return "${inivalue}"

Sub output
|Echo that uses the noiselevel setting
/if (!${Defined[Param0]}) /return
/if (!${Defined[Param1]}) /return
/if (${Param0}<=${noiselevel}) {
/echo ${Param1}
}
/return

Sub IsNumeric
|Returns true if Param0 is numeric, false if not
/if (!${Defined[Param0]}) /return "false"
/if (${String[${Param0}].Length}==0) /return "false"
/declare counter int local

/for counter 1 to ${String[${Param0}].Length}
/if (${String[${Param0}].Mid[${counter},1]}<"0" || ${String[${Param0}].Mid[${counter},1]}>"9") /return "false"
/next counter
/return "true"

Sub statsub
|Display stats
/declare runtime local
/declare runstring local
/varset runtime ${Macro.RunTime}
/echo Corpses found: ${Int[${corpses}]}, ressed: ${Int[${clicked}]}, could not restore: ${Int[${couldnot}]}
/echo Skipped race: ${Int[${skippedrace}]}, Skipped con: ${Int[${skippedcon}]}, Skipped blacklist: ${Int[${skippedblacklist}]}
/varset runstring "Time taken ${Int[${Math.Calc[${runtime}/60]}]} minutes ${Int[${Math.Calc[${runtime}%60]}]} seconds"
/if (${timeouts}>0) /echo Consider timeouts: ${timeouts}
/if (${corpses}>0) /varset runstring "${runstring} (avg time per corpse: ${Math.Calc[${runtime}/${corpses}]}s)"
/echo ${runstring}
/return

Sub buildprios(Param0,Param1)
|Builds priority lists from ini file into priofilters(${Param1},y)
|${Param0} is the name of the profile
/declare filters local
/declare temp local
/declare curfilt local
/declare pipeloc local
/declare nextpipe local
/declare filtercount local
/if (!${Defined[Param0]}) /return
/varset filters "${Ini[${CLICKINIFILE},${Param0},-1,NOTFOUND]}"
/if (${String["${filters}"].Equal["NOTFOUND"]}) {
/if (${String["${Param0}"].Equal["default"]}) {
||If default is empty, set defaults to bards and clerics
/varset priofilters(${Param1},0) "cBard"
/varset priofilters(${Param1},1) "cEnchanter"
/varset priofilters(${Param1},2) "cCleric"
/return 3
} else {
/return -1
}
}

/varset filters $left($calc($strlen(${filters})-2),${filters})

/varset filtercount 0

/varset nextpipe $instr("|",${filters})

/if n ${nextpipe}<0 {
/varset priofilters(${Param1},0) $left(1,${filters})"$ini("CLICKINIFILE","${Param0}","${filters}")"
/goto :leavebuildprios
}

:loopfilters
/varset curfilt $mid(0,${nextpipe},${filters})
/varset filters $right($calc($strlen(${filters})-${nextpipe}-1),${filters})
/varset temp $ini("CLICKINIFILE","${Param0}",curfilt)

/varset priofilters(${Param1},${filtercount}) $left(1,${curfilt})"$ini("CLICKINIFILE","${Param0}","${curfilt}")"
/varset nextpipe $instr("|",${filters})
/varadd filtercount 1

/if n ${nextpipe}<0 {
/varset priofilters(${Param1},${filtercount}) $left(1,${filters})"$ini("CLICKINIFILE","${Param0}","${filters}")"
/goto :leavebuildprios
}

/goto :loopfilters

:leavebuildprios
/varadd filtercount 1

/return ${filtercount}

Sub HasPriority(Param0,Param1)
|Test if corpse with id ${Param1} has high priority in profile ${Param0}
/declare test local
/declare hpcount int local
/declare filtnum local
/if (!${Defined[Param0]}) {
/varset test default
} else {
/varset test ${Param0}
}
/echo ${Param0}
/end
/call findprioinarray "${test}"
/echo Checking Priority on ${Spawn[${test}].Name} ${prios}(${Macro.Return},1)
/if (${prios}(${Macro.Return},1)<=0) /return "false"

/varset filtnum ${Macro.Return}

/for hpcount 0 to $calc(${prios}(${filtnum},1)-1)
/if (${String[${priofilters}(${filtnum},${hpcount})].Left[1].Equal["c"]}) {
/if (${Spawn[${Param1}].Class.Equal[${String[${priofilters}(${filtnum},${hpcount})].Right[-1]}]}) {
/return "true"
}
} else /if (${String[${priofilters}(${filtnum},${hpcount})].Left[1].Equal["n"]}) {
/if "$spawn(${Param1},name)"~~"$right($calc($strlen("${priofilters}(${filtnum},${hpcount})")-1),"${priofilters}(${filtnum},${hpcount})")" {
/return "true"
}
} else /if (${String[${priofilters}(${filtnum},${hpcount})].Left[1].Equal["g"]}) {
/if "$spawn(${Param1},guild)"=="$right($calc($strlen("${priofilters}(${filtnum},${hpcount})")-1),"${priofilters}(${filtnum},${hpcount})")" {
/return "true"
}
}

/next hpcount
/return "false"

Sub findprioinarray
|Search array for ${Param0}, returns the location or -1 if not found

/declare counter int local
/for counter 0 to ${priocount}
/if (${String[${Param0}].Equal[${prios}(${counter},0)]}) /return ${counter}
/next counter
/return -1

Sub IsPCRace
|Test if race of corpse with id ${Param0} is in the array of valid races
/declare loopcounter int local
/for loopcounter 0 to ${racecount}
/if "$spawn(${Param0},race)"=="${races}(${loopcounter})" /return "true"
/next loopcounter

/return "false"

Sub clickit
/declare counter local
/declare giveup local
/declare castwait local

|Test if valid race
/if (${useraces}==1) {
/call IsPCRace ${Param0}
/if (${Macro.Return.Equal["false"]}) {
/varadd skippedrace 1
/return
}
}


/if (${useblacklist}==0) /goto :skipblacklist
|Check if corpse is blacklisted
/call HasPriority "blacklist" ${curid}
/if (${Macro.Return.Equal["true"]}) {
/call output 3 "Skipping blacklisted ${Spawn[${curid}].Name}"
/varadd skippedblacklist 1
/return
}

:skipblacklist

|Target corpse
/tar id ${Param0}
/if (!${Target.ID}) /return

/varadd corpses 1

|Doevents to get stats and flush /con messages
/doevents

/if (${consider}==1) {
/varset ispccorpse 0
/varset gotconmsg 0

/consider

|Set timer so we don't get stuck waiting for a /con message
/varset contimer ${contimeout}

:waitcon
/doevents corpseexpire
/doevents willdecay
/delay 1
|After a few seconds give up and assume it's a pc corpse
/if (${contimer}==0) {
/call output 3 "Timeout waiting for /con message, assuming pc corpse"
/varadd timeouts 1
/varset gotconmsg 1
/varset ispccorpse 1
}
/if (${gotconmsg}==0) /goto :waitcon

/if (${ispccorpse}!=1) {
/varadd skippedcon 1
/call output 3 "Skipping $target(name)"
/return
}
}
/varadd clicked 1

|Counter to give up after 4 attempts at rezzing a corpse
|that fail either by interrupt or if we can't cast for 3 seconds
/varset giveup 0

:tryagain
/varadd giveup 1

|Too many tries, move on to next
/if (${giveup}>4) /return

/varset status 0
/varset castwait 0

|Wait until we are not casting, if we wait too long, treat as an interrupt
:waitforcast
/if (!${Me.Casting.ID}) /goto :castit
/delay 5
/varadd castwait 1
/if (${castwait}>5) /goto :tryagain
/goto :waitforcast

:castit
/call output 3 "Resurrecting $target(name)"
/hail
/if (${usespell}==0) {
| Use epic
/call standup
/cast item "water sprinkler of nem ankh"
} else {
| Use spell

:waitspellrefresh
| Check if enough mana, if not med until there is enough
/if (${Me.CurrentMana}<${Spell[${spellname}].Mana}) /call medup

| Wait until spell is refreshed
/if (!${Me.SpellReady[${spellname}]}) {
/delay 1
/goto :waitspellrefresh
}
/call standup

/cast ${spellname}
}

|Wait until not casting anymore
:castdelay
/delay 5
/doevents
/if (${status}==4) {
/varsub giveup 1
/goto :tryagain
}
/if (${status}==3) {
/varsub giveup 1
/call medup
/goto :tryagain
}
/if (${status}==2) /goto :tryagain
/if (${status}==1) {
/call sitdown
/return
}
/if (${Me.Casting.ID}) /goto :castdelay

/call sitdown

/return

Sub medup
/call sitdown
| Loop until enough mana to cast
:medloop
/delay 1s
/if (${Me.CurrentMana}<${Spell[${spellname}].Mana}) /goto :medloop

/call standup
/return

Sub sitdown
| Don't bother sitting if full mana
/if (${Me.PctMana}==100) /return
| Check sit setting
/if (${sit}==0) /return
| Don't try to sit if on a mount
/if (${Me.Mount.ID}) /return
| If not sitting, sit down
/if (!${Me.State.Equal["SIT"]}) /sit
/return

Sub standup
| Don't try to stand if on a mount
/if (${Me.Mount.ID}) /return
| If not standing, stand up
/if (!${Me.State.Equal["STAND"]}) /stand
/return

Sub buildini
|Loop through the players in zone and compare their race to the list of valid
|player races in ini file and add new races
/declare currace local
/declare curid local
/varset racecount -1

|Read races from ini file
:buildiniloop
/varadd racecount 1
/varset races(${racecount}) "$ini("CLICKINIFILE","races",${racecount})"
/if ("${races}(${racecount})"=="NOTFOUND") /goto :buildleaveloop
/goto :buildiniloop

:buildleaveloop
/declare oldtarget local
/declare added int local

/varset added 0
/declare pccount int local

/varset pccount int 0
|Get first pc
/varset curid $searchspawn(pc)
/varset currace "$spawn(${curid},race)"

:buildloop

/varadd pccount 1
|See if race is in array already
/call buildisinarray "${currace}"
/if (${Macro.Return}==0) {
|New race, add to ini
/if ("$defined(currace)"!="FALSE" && "${currace}"!="NULL") {
/ini "CLICKINIFILE" "races" ${racecount} "${currace}"
/varset races(${racecount}) "${currace}"
/varadd racecount 1
/varadd added 1
/call output 2 "Added race: ${currace}"
}
}
/varset curid $searchspawn(pc,next,id:${curid})
/varset currace "$spawn(${curid},race)"
/if (${curid}==0) /goto :buildend

/goto :buildloop
:buildend
/call output 2 "Players counted: ${pccount} Races in ini: ${racecount}, added ${added}"

/return

Sub buildisinarray
|Search array for ${Param0}
/declare loopcounter int local
/for loopcounter 0 to $Math.Calc[${racecount}-1]
/if ("${Param0}"=="${races}(${loopcounter})") {
/return 1
}
/next loopcounter
/return 0

Rassilon
a lesser mummy
a lesser mummy
Posts: 73
Joined: Thu Sep 04, 2003 6:34 pm

Post by Rassilon » Mon May 03, 2004 10:54 pm

Crashes with loads of errors :(

Thanks

User avatar
blueninja
a grimling bloodguard
a grimling bloodguard
Posts: 541
Joined: Thu Aug 28, 2003 7:03 am
Location: Göteborg, Sweden

Post by blueninja » Tue May 04, 2004 6:23 pm

I'm working on it as we speak.. Been a bit tied up lately but I'm going to have it ready soon..

Preocts
a snow griffon
a snow griffon
Posts: 312
Joined: Thu Jan 29, 2004 1:02 pm

Post by Preocts » Tue May 04, 2004 7:02 pm

Code: Select all

&#91;code&#93; :shock: &#91;/code&#93;

Rassilon
a lesser mummy
a lesser mummy
Posts: 73
Joined: Thu Sep 04, 2003 6:34 pm

Post by Rassilon » Thu May 06, 2004 7:26 pm

Any update on this?

Thanks

User avatar
blueninja
a grimling bloodguard
a grimling bloodguard
Posts: 541
Joined: Thu Aug 28, 2003 7:03 am
Location: Göteborg, Sweden

Post by blueninja » Fri May 07, 2004 2:23 pm