Loot Filter And Forage Macro with ini support version 3.1
Posted: Wed May 26, 2004 9:40 pm
Ok, Here is a macro I have modified from a very good forage macro with Ini support to a MQData, MQDataVars full out loot filter.
Upcoming enhancements create the ini file if it doesn't exist.
Move the configuration settings to a settings section of the ini file. that way you don't have to use parameter unless you need/want to overide your preferences.
Thanks to all that have suffered my questions over the last month as I ported this one from pre-MQData pre /notify code.
I added the loot methods and converted it to be suitable to use as an include.
Usage:
In your initialization code call LootFilterSetup
After a corpse is targetted call LootMob i.e.
Though, I included sample macro implementations I posted this in snipets because, I feel the real power of this macro is being able to be included in hunter macros , etc. Enjoy, please comment. If we can make these better I welcome the input. And again The orginal macro was not mine. However unfortunately there name isn't in the code.
Sample ini
Upcoming enhancements create the ini file if it doesn't exist.
Move the configuration settings to a settings section of the ini file. that way you don't have to use parameter unless you need/want to overide your preferences.
Thanks to all that have suffered my questions over the last month as I ported this one from pre-MQData pre /notify code.
I added the loot methods and converted it to be suitable to use as an include.
Code: Select all
|----------------------------
| Maintained by Draco
| Version 3.1
| To Be a general Purpose LootFilter
|
|Version 3.1 incorporated suggestions from forum.
| Added check in Sub Forage for ability checks so when
| included in larger loops just checks and return in order
| Provide for cleaner calling code.
|
|Version 3.0 -Draco
| Seperated Load from ini made it a more generic array loader
| Ported to MQData/MQDataVar/Updated Events
| Fixed a Bug in Array indexing
|
|Version 2.3 -Draco
| Added a debug flag to assist in Debuging
| Added Loot Events
|
|Version 2.2 -Draco
| Added Loot routine and made it generic for all looting
|
|
|
| Forager with ini file support and
| statistic gathering and reporting
| version 2.1
| Set this define to the desired .ini file
| Requires a blank .ini file to start. The marco will
| populate the .ini file automatically for any zone
| and default to keeping the item. Then just change
| the values in the .ini file to 0 for an item to be
| automatically destroyed (requires FastItemDestroy
| be turned on in the options window)
#Event ZoneChange "Loading please wait#*#"
#Event NoCorpse "You must first target a corpse to loot!"
#Event CorpseTooFar "You are too far away to loot that corpse."
#Event NotYourKill "You may not loot this Corpse at this time."
||**
[lootFilter]
version=3.1
**||
#turbo
#define ITEM_NAME 1
#define KEEP_DESTROY 2
#define LOOT_COUNT 3
Sub LootFilterSetup
/declare LootINIFile string outer "forager.ini"
/declare debugLoot int outer 0
/declare EnableShowStats int outer 0 | Set to 1 to show foraging statistics
/declare EnableWriteLog int outer 0 | Set to 1 to write statistics to MQLog
/declare EnableClear int outer 0 | Set to 1 to clear before writing stats
/declare LootAttempts int outer 0
/declare LootSuccess int outer 0
/declare LootFailure int outer 0
/declare LootKeeps int outer 0
/declare LootDestroys int outer 0
/declare NumItem int outer 0
/declare LootIndex int outer 0
/declare ItemArray[3,60] string outer
/declare DefaultKeepItem int outer 1
/declare LootTooFar int outer 0
/declare NoCorpseToTarget int outer 0
/declare UnableToLoot int outer 0
| ##### User set variables #####
| /alias /showstats /call ShowStats
/call LoadFromIni ${LootINIFile} global ItemArray ${NumItem}
/varset NumItem ${Macro.Return}
/call LoadFromIni ${LootINIFile} "${Zone}" ItemArray ${NumItem}
/varset NumItem ${Macro.Return}
/return
| ########## Subroutines ##########
Sub Forage
/if (${Me.Ability[Forage]} && ${Me.AbilityReady[Forage]}) {
/doability Forage
/varadd LootAttempts ${LootAttempts}+1
}
/return
sub LootMob
/declare LootSlot int local 1
/lootn never
/delay 1s
/varset LootTooFar 0
/loot
/delay 10
/doevents NotYourKill
/doevents CorpseTooFar
:lootloop
/if (${LootTooFar}==1) /goto :doneloot
/if (${Corpse.Items}==0) {
/if (${debugLoot}>0) /echo Corpse Empty
/goto :doneloot
}
/if (${LootSlot}>=32) /goto :doneloot
/itemnotify Loot${LootSlot} leftmouseup
/delay 2s
/if (${debugLoot}>0) /echo Cursor has: ${Cursor}
| Use LootFilter Check here initially building the LootINIFile then file will be edited
| to Adjust for preference on Keep Destroy
/call CheckItem
/call HandleItem
/if (${Bool[${Cursor.Name}]}) {
/delay 1s
/if (${debugLoot}>0) /echo Destroying: ${Cursor.Name}
/destroy
/delay 1s
}
/varcalc LootSlot ${LootSlot}+1
/goto :lootloop
:doneloot
/notify LootWnd DoneButton leftmouseup
/lootn always
/varset LootSlot 0
/return
Sub LogStats
/declare xy int local
/if (${EnableClear}==1) /mqlog clear
/mqlog #############################################
/mqlog For Zone: ${Zone}
/mqlog Attempts = (${LootAttempts})
/mqlog Success = (${LootSuccess}) [(${Math.Calc[${LootSuccess}/${LootAttempts}*100]})%]
/mqlog Failures = (${LootFailure}) [(${Math.Calc[${LootFailure}/${LootAttempts}*100]})%]
/mqlog Keeps = (${LootKeeps}) [(${Math.Calc[${LootKeeps}/${LootAttempts}*100]})%]
/mqlog Destroys = (${LootDestroys}) [(${Math.Calc[${LootDestroys}/${LootAttempts}*100]})%]
/mqlog [Idx] [Item] [Keep] [Qty] [%]
/mqlog -------------------------------------------
/if (${NumItem}>0) {
/for xy 1 to ${NumItem}
/if (${ItemArray[LOOT_COUNT,${xy}]}>0) {
/mqlog "[${xy}] [${ItemArray[ITEM_NAME,${xy}]}] [${ItemArray[KEEP_DESTROY,${xy}]}] [${ItemArray[LOOT_COUNT,${xy}]}] [${Math.Calc[${ItemArray[LOOT_COUNT,${xy}]}/${LootAttempts}*100]}%]"
}
/next xy
}
/return
Sub ShowStats
/declare xy int local
/if (${EnableClear}==1) /clear
/echo #############################################
/echo For Zone: ${Zone}
/echo Attempts = (${LootAttempts})
/echo Success = (${LootSuccess}) [(${Math.Calc[${LootSuccess}/${LootAttempts}*100]})%]
/echo Failures = (${LootFailure}) [(${Math.Calc[${LootFailure}/${LootAttempts}*100]})%]
/echo Keeps = (${LootKeeps}) [(${Math.Calc[${LootKeeps}/${LootAttempts}*100]})%]
/echo Destroys = (${LootDestroys}) [(${Math.Calc[${LootDestroys}/${LootAttempts}*100]})%]
/echo [Idx] [Item] [Keep] [Qty] [%]
/echo -------------------------------------------
/if (${NumItem}>0) {
/for xy 1 to ${NumItem}
/if (${ItemArray[LOOT_COUNT,${xy}]}>0) {
/echo "[${xy}] [${ItemArray[ITEM_NAME,${xy}]}] [${ItemArray[KEEP_DESTROY,${xy}]}] [${ItemArray[LOOT_COUNT,${xy}]}] [${Math.Calc[${ItemArray[LOOT_COUNT,${xy}]}/${LootAttempts}*100]}%]"
}
/next xy
}
/return
Sub CheckItem
/declare iter int local
/varcalc LootAttempts ${LootAttempts}+1
/if (${NumItem}==0) {
/varset NumItem 1
/call AddToArray ${NumItem)
/varset LootIndex 0
} else {
/for iter 1 to ${NumItem}
/if ( ${Cursor.Name.Equal[${ItemArray[ITEM_NAME,${iter}]}]} ) {
/varset LootIndex ${iter}
/if (${debugLoot}>0) /echo "${ItemArray[ITEM_NAME,${iter}]} : ${ItemArray[KEEP_DESTROY,${iter}]}: ${ItemArray{LOOT_COUNT,${iter}]}"
}
/next iter
/if (${LootIndex}==0) {
/varcalc NumItem ${NumItem}+1
/if (${debugLoot}>0) /echo "${Cursor.Name} not found!"
/call AddToArray ${NumItem)
} else {
/varcalc ItemArray[LOOT_COUNT,${LootIndex}] ${ItemArray[LOOT_COUNT,${LootIndex}]}+1
}
}
/return
Sub AddToArray(int endPos)
/if (${debugLoot}>0) /echo "Adding ${Cursor} to Item Array"
/varset ItemArray[ITEM_NAME,${NumItem}] ${Cursor}
/varset ItemArray[KEEP_DESTROY,${NumItem}] ${Ini["${LootINIFile}","${Zone}","${Cursor}" NOTFOUND]}
/if (${ItemArray[KEEP_DESTROY,${NumItem}].Equal[NOTFOUND]} ) {
/if (${debugLoot}>0) /echo "${Cursor} Not Found in ${LootINIFile}"
/varset ItemArray[KEEP_DESTROY,${NumItem}] ${DefaultKeepItem}
/ini "${LootINIFile}" "${Zone}" "${Cursor}" ${DefaultKeepItem}
/if (${debugLoot}>0) /echo "Added [${Zone}] ${Cursor}=${DefaultKeepItem} to ${LootINIFile}"
/mqlog "Added [${Zone}] ${Cursor}=${DefaultKeepItem} to ${LootINIFile}"
}
/varset ItemArray[LOOT_COUNT,${NumItem}] 1
/return
Sub HandleItem
/if ( ${ItemArray[KEEP_DESTROY,${LootIndex}].NotEqual[1]} ) {
/varcalc LootDestroys ${LootDestroys}+1
/if (${debugLoot}>0) /echo Destroying: ${Cursor.Name}
/destroy
} else {
/varcalc LootKeeps ${LootKeeps}+1
/if (${debugLoot}>0) /echo Keeping: ${Cursor.Name}
/autoinv
}
/return
| ########## Subroutines ##########
Sub LoadFromIni(string iniFileName, string zoneName, ArrayName, startIndex )
/declare IniPosition int local 0
/declare IniList string local
/declare finishIndex int local ${startIndex}
/if (${debugLoot}>0) /echo "Loading Loot Table for ${zoneName}: ${Ini[${iniFileName},${zoneName}]}"
/varset IniList ${Ini[${iniFileName},${zoneName}]}
/if (${Bool[${IniList}]}) {
/if (${debugLoot}>0) /echo "KeySet[${zoneName}]=${IniList}"
:CheckZoneLoot
/varcalc IniPosition ${IniPosition}+1
/varcalc finishIndex ${finishIndex}+1
/if (${debugLoot}>0) /echo Item(${IniPosition}): ${IniList.Arg[${IniPosition},|]}
/varset ${ArrayName}[1,${finishIndex}] ${IniList.Arg[${IniPosition},|]}
/varset ${ArrayName}[2,${finishIndex}] ${Ini[${iniFileName},${zoneName},${${ArrayName}[1,${finishIndex}]}]}
/if (${debugLoot}>0) /echo "ZONE LOAD ${${ArrayName}[1,${finishIndex}]}=${${ArrayName}[2,${finishIndex}]}"
/if (${Bool[${IniList.Arg[${Math.Calc[${IniPosition}+1]},|]}]}) /goto :CheckZoneLoot
}
/return ${finishIndex}
Sub Event_ZoneChange
/delay 1m
/call LoadFromIni ${LootINIFile} global ItemArray 0
/varset NumItem ${Macro.Return}
/call LoadFromIni ${LootINIFile} "${Zone}" ItemArray ${NumItem}
/varset NumItem ${Macro.Return}
/return
Sub Event_CorpseTooFar
/varset LootTooFar 1
/return
Sub Event_NoCorpse
/varset NoCorpseToTarget 1
/return
Sub Event_NotYourKill
/varset UnableToLoot 1
/return
Usage:
In your initialization code call LootFilterSetup
After a corpse is targetted call LootMob i.e.
Code: Select all
|Loot.mac
#include lootFilter.inc
Sub Main
/call lootFilterSetup
/call LootMob
/return
Code: Select all
|----------------------------
| Forager with ini file support and
| statistic gathering and reporting
| version 3.0 By Draco
| Move the guts to forager.inc left this as a place to call the main loop
| I have used to /call CheckItem and /call HandleItem in my lootMob code
| sample Here:
| sub LootMob
| /lootn never
| /delay 1s
| /loot
| /delay 1s
| /varset LootTooFar 0
| :lootloop
| /if (${LootTooFar}==1) /goto :doneloot
| /if (${LootSlot}>=32) /goto :doneloot
| /click left corpse ${LootSlot}
| /delay 1s
| /if (${Bool[${Cursor.Name}]}) /goto :doneloot
| | Use Forager Check here initially building the LootINIFile then file will be edited
| | to Adjust for preference on Keep Destroy
| /call CheckItem
| /call HandleItem
|
| /if "$cursor()"}=="TRUE" {
| /delay 1s
| /click left destroy
| /delay 1s
| }
| /varadd LootSlot 1
| /varset CheckLoot 0
| /goto :lootloop
| :doneloot
| /lootn always
| /varset LootSlot 0
|/return
|
| This loot loop was orignally found in Grimkjacks hunter.mac I removed his
| loot filter arrays and use calls to the included forager.inc. I also
| implemented several of the sugestion found in this forum to include a outer
| section, etc.
|
| version 2.1
| Set this define to the desired .ini file
| Requires a blank .ini file to start. The marco will
| populate the .ini file automatically for any zone
| and default to keeping the item. Then just change
| the values in the .ini file to 0 for an item to be
| automatically destroyed (requires FastItemDestroy
| be turned on in the options window)
|
| TODO
| Add a combat check to forage to turn off attack forage them turn it back on.
#turbo
#include "lootFilter.inc"
Sub Main
/call ForageSetup
:Continue
/varset ForageIndex 0
/if (${Me.Ability[Forage]} && ${Me.AbilityReady[Forage]}) {
/call Forage
/if( ${Bool[${Cursor.Name}]} ){
/varcalc ForageFailure ${ForageFailure}+1
} else {
/varcalc ForageSuccess ${ForageSuccess}+1
/call CheckItem
/call HandleItem
}
/if (${EnableShowStats}==1 ) /call ShowStats
/if (${EnableWriteLog}==1 ) /call LogStats
}
|/delay ${ForageDelay}
/goto :Continue
/return
Though, I included sample macro implementations I posted this in snipets because, I feel the real power of this macro is being able to be included in hunter macros , etc. Enjoy, please comment. If we can make these better I welcome the input. And again The orginal macro was not mine. However unfortunately there name isn't in the code.
Sample ini
Code: Select all
[Global]
Spider Silk=1
Roots=1
Fishing Grubs=0