Beta release of the converted macro, please report any bugs you find.
Uses an ini file (uses a default set of values if it can't find the ini), change CLICKINIFILE so it points to your ini. This ini file contains a few default options, a list of profiles that define the priority in which to click corpses and a list of valid player races.
Version 2.24b:
Added an option to hail corpses before they are resurrected
Added an option to face the corpse before resurrecting in case it is out of view (more than 30 degrees away from your heading). It can also use GD's turn.inc to turn more naturally. In order to use that feature you need to get turn.inc and uncomment the line that says "#include turn.inc". Turn.inc is availiable from the snippets forum
Added an option to skip corpses in case they are too far away above or below you, useful in places with several floors.
Code: Select all
| Click.mac - v2.24b - Resurrect corpses around you - by blueninja
| BETA RELEASE
| MQ2Data port of v2.22
| 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> [face/noface]
| [turn/noturn] [hail/nohail] [maxz] <Z> [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
| [face/noface] - face the corpse before ressing if it's out of view
| [turn/noturn] - turn towards the corpse before ressing if it's out of view using GD's turn.inc
| [hail/nohail] - hail the corpse before ressing it
| [maxz] <Z> - maximum distance to the corpse in the Z plane
| [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
| Uncomment the following line if you want to use GD's turn.inc
|#include turn.inc
#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."
#event skip "[MQ2] skip"
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
/varcalc couldnot ${couldnot}+1
/return
Sub Event_clickedoldcorpse
| Tried to resurrect a corpse that was too old
| Remove from statistics
/varcalc clicked ${clicked}-1
/varset status 1
/return
Sub Event_skip
/varset status 1
/varcalc clicked ${clicked}-1
/call output 4 "Skipping.."
/return
Sub Event_interrupt
/if (${Me.State.Equal[DUCK]}) {
/varset status 1
/varcalc clicked ${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 int outer
/declare ispccorpse bool outer
/declare gotconmsg bool outer
/declare spawncount int local
/declare radius int local
/declare contimer timer outer
/declare timeouts int outer
/declare corpses int outer
/declare skippedrace int outer
/declare skippedcon int outer
/declare skippedblacklist int outer
/declare clicked int outer
/declare couldnot int outer
|prios(x,y) - contains name of profile in (x,1) and number of filters in profile in (x,2)
/declare prios[100,2] outer
/declare priocount int outer
|priofilters(x,y) - y=0..prios(x,2) contains the values of the filters for prios(x,1)
/declare priofilters[100,100] outer
/declare only bool local
/declare argloop int local
/declare racecount int outer
|List of valid player races
/declare races[100] outer
/declare curid int outer
/declare spellmaxrange int local
/declare noiselevel int outer
/declare contimeout int outer
/declare defaultradius int local
/declare showstats bool local
/declare useraces bool outer
/declare consider bool outer
/declare usespell bool outer
/declare spellname string outer
/declare spellslot int outer
/declare useblacklist bool outer
/declare sit bool outer
/declare hail bool outer
/declare face bool outer
/declare turn bool outer
/declare maxz int 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" 0
/varset showstats ${Bool[${Macro.Return}]}
/call getconfig "useraces" 0
/varset useraces ${Bool[${Macro.Return}]}
/call getconfig "consider" 1
/varset consider ${Bool[${Macro.Return}]}
/call getconfig "useblacklist" 0
/varset useblacklist ${Bool[${Macro.Return}]}
/call getconfig "usespell" 0
/varset usespell ${Bool[${Macro.Return}]}
/call getconfig "spellname" DEFAULTSPELL
/varset spellname ${Macro.Return}
/call getconfig "spellslot" 8
/varset spellslot ${Macro.Return}
/call getconfig "sit" 0
/varset sit ${Bool[${Macro.Return}]}
/call getconfig "hail" 0
/varset hail ${Bool[${Macro.Return}]}
/call getconfig "face" 0
/varset face ${Bool[${Macro.Return}]}
/call getconfig "turn" 0
/varset turn ${Bool[${Macro.Return}]}
/call getconfig "maxz" 0
/varset maxz ${Bool[${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 0
/varset spellmaxrange 200
|Check if parameter is passed
/for argloop 0 to 10
/if (${Defined[Param${argloop}]}) {
/call IsNumeric "${Param${argloop}}"
/if (${Macro.Return}==0) {
|non-numeric argument
/if (${String[${Param${argloop}}].Equal[only]}) {
/varset only 1
} else /if (${String[${Param${argloop}}].Equal[buildraces]}) {
/call buildini
/endmacro
} else /if (${String[${Param${argloop}}].Equal[noracecheck]}) {
/varset useraces FALSE
} else /if (${String[${Param${argloop}}].Equal[racecheck]}) {
/varset useraces TRUE
} else /if (${String[${Param${argloop}}].Equal[noblacklist]}) {
/varset useblacklist FALSE
} else /if (${String[${Param${argloop}}].Equal[useblacklist]}) {
/varset useblacklist TRUE
} else /if (${String[${Param${argloop}}].Equal[usespell]}) {
/varset usespell TRUE
} else /if (${String[${Param${argloop}}].Equal[useepic]}) {
/varset usespell FALSE
} else /if (${String[${Param${argloop}}].Equal[sit]}) {
/varset sit TRUE
} else /if (${String[${Param${argloop}}].Equal[stand]}) {
/varset sit FALSE
} else /if (${String[${Param${argloop}}].Equal[nocon]}) {
/varset consider FALSE
} else /if (${String[${Param${argloop}}].Equal[con]}) {
/varset consider TRUE
} else /if (${String[${Param${argloop}}].Equal[hail]}) {
/varset hail TRUE
} else /if (${String[${Param${argloop}}].Equal[nohail]}) {
/varset hail FALSE
} else /if (${String[${Param${argloop}}].Equal[face]}) {
/varset face TRUE
} else /if (${String[${Param${argloop}}].Equal[noface]}) {
/varset face FALSE
} else /if (${String[${Param${argloop}}].Equal[turn]}) {
/varset turn TRUE
} else /if (${String[${Param${argloop}}].Equal[noturn]}) {
/varset turn FALSE
} else /if (${String[${Param${argloop}}].Equal[spellname]}) {
/varcalc argloop ${argloop}+1
/varset spellname "${Param${argloop}}"
} else /if (${String[${Param${argloop}}].Equal[spellslot]}) {
/varcalc argloop ${argloop}+1
/varset spellslot "${Param${argloop}}"
} else /if (${String[${Param${argloop}}].Equal[maxz]}) {
/varcalc argloop ${argloop}+1
/varset maxz ${Param${argloop}}
} else {
/varcalc priocount ${priocount}+1
/varset prios[${priocount},1] "${Param${argloop}}"
/call buildprios "${Param${argloop}}" ${priocount}
/varset prios[${priocount},2] ${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}
}
|If we havent found any profiles on command line, set first one to default
/if (${priocount}==0) {
/varset priocount 1
/varset prios[${priocount},1] "default"
/call buildprios "default" ${priocount}
/varset prios[${priocount},2] ${Macro.Return}
}
|Build an array of valid player races from ini file
/if (${useraces}==1) {
/varset racecount 0
:iniloop
/varcalc racecount ${racecount}+1
/varset races[${racecount}] ${Ini["CLICKINIFILE",races,${String[${Int[${Math.Calc[${racecount}-1]}]}]}]}
/if (!${Bool[${races[${racecount}]}]}) /goto :leaveloop
/goto :iniloop
}
:leaveloop
|Read the blacklist after the normal profiles
/varcalc priocount ${priocount}+1
/varset prios[${priocount},1] "blacklist"
/call buildprios "blacklist" ${priocount}
/varset prios[${priocount},2] ${Macro.Return}
|First loop through high priority classes..
/varset curid 0
/for argloop 1 to ${Math.Calc[${priocount}-1]}
/varset spawncount 1
:loopprio
/doevents
/varset status 0
/varset curid ${Me.NearestSpawn[${spawncount},corpse range 1 70 radius ${radius}].ID}
|If we didn't get a new target move on to low priority
/if (${curid}==NULL) /goto :clicktherest
/varcalc spawncount ${spawncount}+1
|Check if this is a high priority corpse
/call HasPriority ${prios[${argloop},1]} ${curid}
/if (!${Macro.Return}==1) /goto :loopprio
/call clickit ${curid}
|Gather statistics
/doevents couldnotrez
/goto :loopprio
:clicktherest
/next argloop
|If parameter 'only' is specified don't move on to low priority corpses
/if (${only==1}) /goto :end
/varset curid 0
/varset spawncount 1
|.. then everyone else
:restloop
/doevents
/varset status 0
/varset curid ${Me.NearestSpawn[${spawncount},corpse range 1 70 radius ${radius}].ID}
|If we didn't get a new target quit
/if (${curid}==0) /goto :end
/varcalc spawncount ${spawncount}+1
|Check that this isn't a priority corpse
/for argloop 1 to ${Math.Calc[${priocount}-1]}
/call HasPriority ${prios[${argloop},1]} ${curid}
/if (${Macro.Return}==1) /goto :restloop
/next argloop
/call clickit ${curid}
|Gather statistics
/doevents couldnotrez
/goto :restloop
:end
|Gather statistics
/call sitdown
/doevents couldnotrez
/if (${showstats}==1) /call statsub
/return
Sub getconfig
|Read the value of a [config] parameter in ini file
|/call getconfig "paramname" "defaultvalue"
|Returns value
/if (!${Defined[Param0]}) /return "false"
/if (!${Defined[Param1]}) /return "false"
/declare inivalue local
/varset inivalue ${Ini["CLICKINIFILE","config","${Param0}"]}
|Not set in ini file, return default value
/if (${String[${inivalue}].Equal[NULL]}) /varset inivalue ${Param1}
/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 1 if Param0 is numeric, 0 if not
/if (!${Defined[Param0]}) /return 0
/if (${Param0.Length}==0) /return 0
/declare counter int local
/for counter 1 to ${Param0.Length}
/if (${String[0123456789].Find[${Param0.Mid[${counter},1]}]}==NULL) /return 0
/next counter
/return 1
Sub statsub
|Display stats
/declare runtime float local
/declare runstring local
/varset runtime ${Macro.RunTime}
/echo Corpses found: ${corpses}, ressed: ${clicked}, could not restore: ${couldnot}
/echo Skipped race: ${skippedrace}, Skipped con: ${skippedcon}, Skipped blacklist: ${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 corse: ${Math.Calc[${runtime}/${corpses}]}s)
/echo ${runstring}
/return
Sub buildprios
|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 int local
/declare nextpipe int local
/declare filtercount int local
/if (!${Defined[Param0]}) /return
/varset filters ${Ini["CLICKINIFILE",${Param0}]}
/if (${String[${filters}].Equal[||]} || ${String[${filters}].Equal[NOTFOUND||]}) {
/if (${Param0.Equal[default]}) {
||If default is empty, set defaults to bards and clerics
/varset priofilters[${Param1},1] cBard
/varset priofilters[${Param1},2] cCleric
/return 2
} else {
/return -1
}
}
/varset filters ${filters.Left[${Math.Calc[${filters.Length}-2]}]}
/varset filtercount 1
/varset nextpipe ${filters.Find[|]}
/if (${nextpipe}==NULL) {
/varset priofilters[${Param1},1] ${filters.Left[1]}${Ini["CLICKINIFILE",${Param0},${filters}]}
/goto :leavebuildprios
}
:loopfilters
/varset curfilt ${filters.Mid[1,${Math.Calc[${nextpipe}-1]}]}
/varset filters ${filters.Right[${Math.Calc[${filters.Length}-${nextpipe}]}]}
/varset temp ${Ini["CLICKINIFILE",${Param0},${curfilt}]}
/varset priofilters[${Param1},${filtercount}] ${curfilt.Left[1]}${Ini["CLICKINIFILE",${Param0},${curfilt}]}
/varset nextpipe ${filters.Find[|]}
/varcalc filtercount ${filtercount}+1
/if (${nextpipe}==NULL) {
/varset priofilters[${Param1},${filtercount}] ${filters.Left[1]}${Ini["CLICKINIFILE",${Param0},${filters}]}
/goto :leavebuildprios
}
/goto :loopfilters
:leavebuildprios
/varcalc filtercount ${filtercount}+1
/return ${filtercount}
Sub HasPriority
|Test if corpse with id @Param1 has high priority in profile @Param0
/declare test local
/declare hpcount int local
/declare filtnum int local
/if (!${Defined[Param0]}) {
/varset test default
} else {
/varset test ${Param0}
}
/call findprioinarray ${test}
/if (${prios[${Macro.Return},2]}<=0) /return 0
/varset filtnum ${Macro.Return}
/for hpcount 1 to ${Math.Calc[${prios[${filtnum},2]}-1]}
/if (${priofilters[${filtnum},${hpcount}].Left[1].Equal[c]}) {
/if (${Spawn[${Param1}].Class.Name.Equal[${priofilters[${filtnum},${hpcount}].Right[${Math.Calc[${priofilters[${filtnum},${hpcount}].Length}-1]}]}]}) {
/return 1
}
} else /if (${priofilters[${filtnum},${hpcount}].Left[1].Equal[n]}) {
/if (${Spawn[${Param1}].Name.Find[${priofilters[${filtnum},${hpcount}].Right[${Math.Calc[${priofilters[${filtnum},${hpcount}].Length}-1]}]}]}!=NULL) {
/return 1
}
} else /if (${priofilters[${filtnum},${hpcount}].Left[1].Equal[g]}) {
/if (${Spawn[${Param1}].Guild.Find[${priofilters[${filtnum},${hpcount}].Right[${Math.Calc[${priofilters[${filtnum},${hpcount}].Length}-1]}]}]}!=NULL) {
/return 1
}
}
/next hpcount
/return 0
Sub findprioinarray
|Search array for @Param0, returns the location or -1 if not found
/declare counter int local
/for counter 1 to ${priocount}
/if (${Param0.Equal[${prios[${counter},1]}]}) /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.Name.Equal[${races[${loopcounter}]}]}) /return 1
/next loopcounter
/return 0
Sub clickit
/declare counter local
/declare giveup local
/declare castwait local
|Test Z distance
/if (${maxz}>0 && ${Spawn[${curid}].DistanceZ}>${maxz}) {
/call output 3 "Skipping ${Spawn[${curid}].Name} because Z distance too large"
/return
}
|Test if valid race
/if (${useraces}) {
/call IsPCRace ${Param0}
/if (${Macro.Return}==0) {
/varcalc skippedrace ${skippedrace}+1
/return
}
}
/if (!${useblacklist}) /goto :skipblacklist
|Check if corpse is blacklisted
/call HasPriority blacklist ${curid}
/if (${Macro.Return}==1) {
/call output 3 "Skipping blacklisted ${Spawn[${curid}].Name}"
/varcalc skippedblacklist ${skippedblacklist}+1
/return
}
:skipblacklist
|Target corpse
/tar id ${curid}
/if (${Target.ID}==NULL) /return
/varcalc corpses ${corpses}+1
|Doevents to get stats and flush /con messages
/doevents
/if (${consider}) {
/varset ispccorpse FALSE
/varset gotconmsg FALSE
/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"
/varcalc timeouts ${timeouts}+1
/varset gotconmsg TRUE
/varset ispccorpse TRUE
}
/if (!${gotconmsg}) /goto :waitcon
/if (!${ispccorpse}) {
/varcalc skippedcon ${skippedcon}+1
/call output 3 "Skipping ${Target.Name}"
/return
}
}
/varcalc clicked ${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
/varcalc giveup ${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 (!${Bool[${Me.Casting}]}) /goto :castit
/delay 5
/varcalc castwait ${castwait}+1
/if (${castwait}>5) /goto :tryagain
/goto :waitforcast
:castit
/if (${Math.Abs[${Math.Calc[${Target.HeadingTo.Degrees}-${Me.Heading.Degrees}]}]}>30) {
/if (${turn}) /call Turn
/if (${face}) {
/face
:waitforface
/if (${Math.Abs[${Math.Calc[${Target.HeadingTo.Degrees}-${Me.Heading.Degrees}]}]}>5) /goto :waitforface
}
}
/call output 3 "Resurrecting ${Target.Name}"
/if (${hail}) /keypress HAIL
/if (!${usespell}) {
| Use epic
/call standup
/cast item "water sprinkler of nem ankh"
} else {
| Use spell
/if (${Me.Gem[${spellname}]}==NULL) {
/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
}
}
: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) {
/varcalc giveup ${giveup}-1
/goto :tryagain
}
/if (${status}==3) {
/varcalc giveup ${giveup}-1
/call medup
/goto :tryagain
}
/if (${status}==2) /goto :tryagain
/if (${status}==1) {
/call sitdown
/return
}
/if (${Bool[${Me.Casting}]}) /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}) /return
| Don't try to sit if on a mount
/if (${Me.Mount.ID}!=NULL) /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}!=NULL) /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
/varset racecount 0
|Read races from ini file
:buildiniloop
/varcalc racecount ${racecount}+1
/varset races[${racecount}] ${Ini["CLICKINIFILE",races,${String[${Int[${Math.Calc[${racecount}-1]}]}]}]}
/if (!${Bool[${races[${racecount}]}]}) /goto :buildleaveloop
/goto :buildiniloop
:buildleaveloop
/declare added int local
/varset added 0
/declare pccount int local
/varset pccount 0
/declare counter local
/varset counter 1
|Get first pc
/varset curid ${Me.ID}
/varset currace ${Spawn[${curid}].Race}
:buildloop
/varcalc pccount ${pccount}+1
|See if race is in array already
/call buildisinarray "${String[${currace}]}"
/if (${Macro.Return}==0) {
|New race, add to ini
/if (${Defined[currace]} && !${currace.Equal[NULL]}) {
/ini "CLICKINIFILE" races ${String[${Int[${Math.Calc[${racecount}-1]}]}]} "${currace}"
/varset races[${racecount}] ${currace}
/varcalc racecount ${racecount}+1
/varcalc added ${added}+1
/call output 2 "Added race: ${currace}"
}
}
/varset curid ${Me.NearestSpawn[${counter},pc].ID}
/varset currace "${Spawn[${curid}].Race}"
/varcalc counter ${counter}+1
/if (${curid}==NULL) /goto :buildend
/goto :buildloop
:buildend
/varcalc racecount ${racecount-1}
/call output 2 "Players counted: ${pccount} Races in ini: ${racecount}, added ${added}"
/return
Sub buildisinarray(String Searchstring)
|Search array for @Param0
/declare counter int local
/for counter 1 to ${racecount}
/if (${Searchstring.Equal[${races[${counter}]}]}) /return 1
/next counter
/return 0
Code: Select all
# Sample config file for click.mac v2.23 by blueninja
# Script configuration
[config]
# Control how much text the script outputs, 0=silent
noiselevel=3
# How long to wait for /con messages before assuming it's a pc corpse and moving on
contimeout=50
# Default radius to look for corpses in, used if nothing else is passed on the command line
defaultradius=200
# Give statistics output after each run, bypasses noiselevel
showstats=1
# Check corpses against the table of valid player races? Can save some time but
# could also result in missing player corpses if they are of a race not specified
# in the [races] section of this file
useraces=1
# /consider corpses to see if they are pc corpses or not
consider=1
# Use the blacklist to skip corpses
useblacklist=1
# Use spell or epic
usespell=0
spellname=Reviviscence
spellslot=6
# Sit down to med between casts
sit=0
# Hail corpses before resurrecting them
hail=0
# Face corpse before resurrecting it
face=1
# Face corpse before resurrecting it using GD's turn.inc
turn=0
# Maximum distance to the corpse in the Z plane, 0 to disable
maxz=50
# Profiles used to decide the priority of corpses, click the ones in the profiles first
# the name in brackets is the name of the profile (what you would specify on the command line)
# c1,c2,n1 etc are the actual filters to match against. If they are prefixed with c,
# as in c1=Monk, it is matched against the class of the corpse. If prefixed with n, as in
# n1=buddy1 it will match against the name of the corpse. Class makes an exact match, name
# just needs to contain the string.
# Sample profile, zerg those dps melees back in
[dps]
c1=Monk
c2=Bard
c3=Rogue
c4=Ranger
# Sample profile, wipe inc, get those rezzers a box
[rez]
c1=Cleric
c2=Paladin
c3=Necromancer
# Sample profile
[healers]
c1=Cleric
c2=Druid
# Sample profile, names of people that get priority
[friends]
n1=joe
n2=burt
# Sample profile, click certain guilds first
[guild]
g1=myguild
g2=friendsguild
# Sample profile, default is the one used if no others specified on command line
[default]
c1=Cleric
c2=Bard
# Sample blacklist, these corpses will not be rezzed
[blacklist]
c1=stupidclass
n1=idiotguy
g1=evil guild
g2=stupidguild
# List of races that player characters can be
# used to avoid waiting for /con messages from npc corpses
[races]
0=Barbarian
1=Human
2=Half Elf
3=Dark Elf
4=Wood Elf
5=Iksar
6=Halfling
7=Dwarf
8=Ogre
9=Gnome
10=Vah Shir
11=Froglok
12=Imp
13=Troll
14=Erudite
15=Wolf
16=UNKNOWN RACE
17=Fire Elemental
18=Bear
19=Water Elemental
20=Earth Elemental
21=Air Elemental
22=Skeleton New
23=High Elf



