CSORT - Sort items inside bags
Posted: Fri May 20, 2005 10:31 pm
Also see Furiousness' excellent sort routine here:
http://www.macroquest2.com/phpBB2/viewt ... light=sort
I started this one before I noticed his.
http://www.macroquest2.com/phpBB2/viewt ... light=sort
I started this one before I noticed his.
Code: Select all
|* CSORT.MAC - http://www.macroquest2.com/phpBB2/viewtopic.php?t=11404
|*
|* 1.11 - 20060324 Agripa
|* - Changed BigBankWnd to BankWnd. *shakes fist at SOE*
|* - Tested as working now on pre-PoR EQ.
|* 1.10 - 20060315 Agripa
|* - Added PoR bank slots. Set csort_PoR to TRUE to use them.
|* 1.00 - 20050712 Agripa
|* - Removed all ${String[]} functions.
|* 0.40 - 20050522 Agripa
|* - Added the option Dual.
|* 0.31 - 20050521 Agripa
|* - Added the option Stack.
|* - Spell and Stack now handle single digit cases correctly by prefixing them with a 0.
|* 0.20 - 20050521 Agripa
|* - Added the options Begin, Close, End, Reverse, and Spell.
|* - An open inventory window is no longer required to sort packs.
|* 0.10 - 20050520 Agripa
|*
|* /mac csort [<start> <end>] [<options>]
|* /call csort [<start> <end>] [<options>]
|*
|* <options> include:
|*
|* Begin - Move empty slots to the beginning.
|* Close - Close bags after sorting is done.
|* Dual - Sort left and right slots as seperate arrays.
|* End - Move empty slots to the end.
|* Reverse - Sort in reverse order.
|* Spell - Sort spells by level first and name second.
|* Stack - Sort by quantity first and name second.
|*
|* Note that the options Begin and End are exclusive and cause odd
|* behavior when used together. I could check for this but maybe someone
|* will find a use.
|*
|* Valid start and end addresses are bank1 to bank16 (2000 to 2015), pack1
|* to pack8 (22 to 29), or sharedbank1 to sharedbank2 (2500 to 2501). If
|* no addresses are given, then the entire bank is sorted if the bank
|* window is open or the entire inventory is sorted if the inventory window
|* is open. Slots without bags are ignored. Items not in bags are ignored.
|*
|* The bank window must already be open before sorting the bank or sharebank.
|*
|* Installation:
|*
|* Save as CSORT.MAC with the first Sub named main.
|*
|* or
|*
|* Save as CSORT.INC with the first Sub named CSORT and use #include CSORT.INC
|*
|* PoR:
|*
|* Either set csort_PoR to TRUE in line 95 or use the following before calling csort:
|*
|* /declare csort_PoR bool outer TRUE
|*
|* Examples:
|*
|* /mac csort
|* Sort the contents of the bank or inventory as seperate sets of continuous items.
|* /mac csort end
|* Sort the contents of the bank or inventory and place empty slots at the end.
|* /mac csort pack2 pack4 beginreverse
|* Reverse sort the contents of inventory packs 2 through 4 and place blank spots at beginning.
|* Sub csort(string pStart, string pEnd, string pOptions)
Sub main(string pStart, string pEnd, string pOptions)
/declare iStart int local
/declare iEnd int local
|* /declare aStart int local ${InvSlot[${pStart}]}
|* /declare aEnd int local ${InvSlot[${pEnd}]}
/declare bStart int local
/declare bEnd int local
/declare I int local
/declare J int local
/declare K int local
/declare K1 int local
/declare K2 int local
/declare L bool local
/declare M bool local
/declare N bool local
/if ( !${Defined[csort_index]} ) {
/declare csort_index[240] int outer
}
|*
|* Set the following to TRUE if using PoR
|*
/if ( !${Defined[csort_PoR]} ) /declare csort_PoR bool outer FALSE
/if ( !${Defined[csort_bank_max]} ) /declare csort_bank_max int outer
/if ( ${csort_PoR} ) {
/varset csort_bank_max 2023
} else {
/varset csort_bank_max 2015
}
|* ${FindItem[${spellName}].InvSlot.ID}
|*
|* item FindItem[ [=]name]
|*
|* int Container Number of slots, if this is a container
|* int Items Number of items, if this is a container
|* item Item[n] nth contained item, if this is a container
|*
|* invslot InvSlot[name]
|*
|* int ID Number of this item slot (usable directly by /itemnotify)
|* item Item Item contained by this item slot
|* invslot Pack Container that must be opened to access the slot with /itemnotify
|* int Slot Slot number inside the pack which holds the item
|* string Name For inventory slots not inside packs, the slot name
|* To String Same as ID
|*
|* .Item
|*
|* int Container Number of slots, if this is a container
|*
|* bank1 2000 2031-2040 pack1 22 251-260 sharedbank1 2500 2531-2540
|* bank2 2001 2041-2050 pack2 23 261-270 sharedbank2 2501 2541-2550
|* bank3 2002 2051-2060 pack3 24 271-280
|* bank4 2003 2061-2070 pack4 25 281-290
|* bank5 2004 2071-2080 pack5 26 291-300
|* bank6 2005 2081-2090 pack6 27 301-310
|* bank7 2006 2091-2100 pack7 28 311-320
|* bank8 2007 2101-2110 pack8 29 321-330
|* bank9 2008 2111-2120
|* bank10 2009 2121-2130
|* bank11 2010 2131-2140
|* bank12 2011 2141-2150
|* bank13 2012 2151-2160
|* bank14 2013 2161-2170
|* bank15 2014 2171-2180
|* bank16 2015 2181-2190
|* New PoR Bank Slots? 2016-2023 and 2191-2260
|* bank17 2016 2191-2200
|* bank18 2017 2201-2210
|* bank19 2018 2211-2220
|* bank20 2019 2221-2230
|* bank21 2020 2231-2240
|* bank22 2021 2241-2250
|* bank23 2022 2251-2260
|* bank24 2023 2261-2270
/if ( ${Macro.Params}==1 ) {
/declare pOptions string local ${pStart}
/deletevar pStart
}
/echo CSORT: (${pStart},${pEnd},${pOptions})
/if ( !${Defined[pStart]} || !${Defined[pEnd]} ) {
/if ( !${Defined[pStart]} ) /declare pStart string local
/if ( !${Defined[pEnd]} ) /declare pEnd string local
/if ( ${Window[BankWnd].Open} ) {
/if ( ${csort_PoR} ) {
/varset pStart bank1
/varset pEnd bank24
} else {
/varset pStart bank1
/varset pEnd bank16
}
} else /if ( ${Window[InventoryWindow].Open} ) {
/varset pStart pack1
/varset pEnd pack8
}
}
/declare aStart int local ${InvSlot[${pStart}]}
/declare aEnd int local ${InvSlot[${pEnd}]}
/varset L TRUE
/if ( ${aStart}>=22 && ${aStart}<=29 && ${aEnd}>=22 && ${aEnd}<=29 && ${aStart}<=${aEnd} ) {
/varset L FALSE
}
/if ( ${aStart}>=2000 && ${aStart}<=${csort_bank_max} && ${aEnd}>=2000 && ${aEnd}<=${csort_bank_max} && ${aStart}<=${aEnd} && ${Window[BankWnd].Open} ) {
/varset L FALSE
}
/if ( ${aStart}>=2500 && ${aStart}<=2501 && ${aEnd}>=2500 && ${aEnd}<=2501 && ${aStart}<=${aEnd} && ${Window[BankWnd].Open} ) {
/varset L FALSE
}
/if ( ${L} ) {
/echo CSORT: Parameter Error (${pStart},${pEnd},${pOptions}) ${aStart} to ${aEnd}
/return
}
/echo CSORT: (${pStart},${pEnd}) ${aStart} ${aEnd}
/varset J 1
/for I ${aStart} to ${aEnd}
/call CSORT_BagSlot_Start ${I}
/varset K1 ${Macro.Return}
/call CSORT_BagSlot_End ${I}
/varset K2 ${Macro.Return}
| /echo CSORT: ${I} ${InvSlot[${I}].Item} ${InvSlot[${I}].Item.Container} ${K1} ${K2}
/if ( ${InvSlot[${I}].Item.Container}>0 ) {
/for K ${K1} to ${K2}
/varcalc csort_index[${J}] ${K}
/varcalc J ${J}+1
/next K
}
/next I
/varcalc iStart 1
/varcalc iEnd ${J}-1
| /echo CSORT: ${iStart} ${iEnd}
| /for I ${iStart} to ${iEnd}
| /echo CSORT: ${I} ${csort_index[${I}]}
| /next I
/varset I ${iStart}
:findstart
|*
|* Open pack if it is not already open and wait for slot to fill.
|*
/if ( ${InvSlot[${csort_index[${I}]}].Pack} && !${Window[${InvSlot[${csort_index[${I}]}].Pack.Name}].Open} ) {
/nomodkey /itemnotify ${InvSlot[${csort_index[${I}]}].Pack} rightmouseup
/delay 1s ${Window[${InvSlot[${csort_index[${I}]}].Pack.Name}].Open}
/delay 1s ${InvSlot[${csort_index[${I}]}].Item.ID}
}
|*
|* Look for the beginning of an array.
|*
/if ( ${InvSlot[${csort_index[${I}]}].Item.ID} || ${pOptions.Find[Begin]} || ${pOptions.Find[End]} ) {
/varcalc bStart ${I}
} else {
/varcalc I ${I} + 1
/if ( ${I}<${iEnd} ) {
/goto :findstart
} else {
/return
}
}
:findend
|*
|* Open pack if it is not already open and wait for slot to fill.
|*
/if ( ${InvSlot[${csort_index[${I}]}].Pack} && !${Window[${InvSlot[${csort_index[${I}]}].Pack.Name}].Open} ) {
/nomodkey /itemnotify ${InvSlot[${csort_index[${I}]}].Pack} rightmouseup
/delay 1s ${Window[${InvSlot[${csort_index[${I}]}].Pack.Name}].Open}
/delay 1s ${InvSlot[${csort_index[${I}]}].Item.ID}
}
|*
|* Look for the end of an array.
|*
/if ( ( !${InvSlot[${csort_index[${I}]}].Item.ID} && !( ${pOptions.Find[Begin]} || ${pOptions.Find[End]} ) ) || ${I}>${iEnd}) {
/varcalc bEnd ${I} - 1
} else {
/varcalc I ${I} + 1
/goto :findend
}
|*
|* Sort the current array and if we are not done go look for another one.
|*
/echo CSORT: ${InvSlot[${csort_index[${bStart}]}].Item.Name}(${bStart}index) to ${InvSlot[${csort_index[${bEnd}]}].Item.Name}(${bEnd}index) ${pOptions}
/call CSORT_Array ${bStart} ${bEnd} ${pOptions}
/varcalc I ${bEnd} + 1
/if ( ${I}<${iEnd} ) {
/goto :findstart
}
|*
|* Close all containers if needed.
|*
/if ( ${pOptions.Find[Close]} ) {
/for I ${iStart} to ${iEnd}
/if ( ${InvSlot[${csort_index[${I}]}].Pack} && ${Window[${InvSlot[${csort_index[${I}]}].Pack.Name}].Open} ) {
/nomodkey /itemnotify ${InvSlot[${csort_index[${I}]}].Pack} rightmouseup
/delay 1s !${Window[${InvSlot[${csort_index[${I}]}].Pack.Name}].Open}
}
/next I
}
/return
|*
|* Combsort an array of indexed items.
|*
Sub CSORT_Array(int start, int end, string pOptions)
/declare I int local
/declare I1 int local
/declare I2 int local
/declare J int local
/declare K int local
/declare L bool local
/declare L1 bool local
/declare L2 bool local
/declare M bool local
/declare N bool local
/declare gap int local
/declare gap_i int local
/declare swapped bool local
/declare I_ID int local
/declare J_ID int local
/declare I_Forage string local
/declare J_Forage string local
/declare I_Name string local
/declare J_Name string local
/varcalc gap_i ${end}-${start}
/if ( ${pOptions.Find[Dual]} ) {
/varcalc gap_i ${gap_i}/2
}
/if ( ${gap_i}<1 ) {
/return
}
/echo CSORT_Array: ${InvSlot[${csort_index[${start}]}].Item.Name}(${start}index) to ${InvSlot[${csort_index[${end}]}].Item.Name}(${end}index) ${pOptions}
:resort
/varset swapped FALSE
|* 1/e (e-1)/e
/varcalc gap_i (${gap_i}*10)/13
/if ( ${gap_i}==9 || ${gap_i}==10 ) {
/varcalc gap_i 11
}
/if ( ${pOptions.Find[Dual]} ) {
/varcalc gap ${gap_i}*2
} else {
/varcalc gap ${gap_i}
}
/echo CSORT_Array: Gap = ${gap} gap_i = ${gap_i}
/for I ${start} to ${Math.Calc[${end}-${gap}]}
/varcalc J ${I} + ${gap}
/varset I_ID ${InvSlot[${csort_index[${I}]}].Item.ID}
/if ( ${InvSlot[${csort_index[${I}]}].Item.Type.Equal[Scroll]} && ${pOptions.Find[Spell]} ) {
/varset I_Name ${InvSlot[${csort_index[${I}]}].Item.Spell.Level}
/if ( ${I_Name.Length}==1 ) /varset I_Name 0${I_Name}
} else /if ( ${pOptions.Find[Stack]} ) {
/varset I_Name ${InvSlot[${csort_index[${I}]}].Item.Stack}
/if ( ${I_Name.Length}==1 ) /varset I_Name 0${I_Name}
} else {
/varset I_Name
}
/varset I_Name ${I_Name}${InvSlot[${csort_index[${I}]}].Item.Name}
/varset J_ID ${InvSlot[${csort_index[${J}]}].Item.ID}
/if ( ${InvSlot[${csort_index[${J}]}].Item.Type.Equal[Scroll]} && ${pOptions.Find[Spell]} ) {
/varset J_Name ${InvSlot[${csort_index[${J}]}].Item.Spell.Level}
/if ( ${J_Name.Length}==1 ) /varset J_Name 0${J_Name}
} else /if ( ${pOptions.Find[Stack]} ) {
/varset J_Name ${InvSlot[${csort_index[${J}]}].Item.Stack}
/if ( ${J_Name.Length}==1 ) /varset J_Name 0${J_Name}
} else {
/varset J_Name
}
/varset J_Name ${J_Name}${InvSlot[${csort_index[${J}]}].Item.Name}
/varcalc L ${I_ID} && ${J_ID} && ${I_Name.Compare[${J_Name}]}==${If[${pOptions.Find[Reverse]},-1,1]}
/varcalc M ( ${pOptions.Find[Begin]} && ${I_ID} && !${J_ID} ) || ( ${pOptions.Find[End]} && !${I_ID} && ${J_ID} )
/if ( ${L} || ${M} ) {
| /echo CSORT_Array: Exchange ${I_Name}(${I_ID}id)(${csort_index[${I}]}slot) with ${J_Name}(${J_ID}id)(${csort_index[${J}]}slot)
/varset swapped TRUE
/if ( ${I_ID} ) {
/nomodkey /shiftkey /itemnotify ${csort_index[${I}]} leftmouseup
/delay 1s ( ${Cursor.ID}==${I_ID} )
}
/if ( ${I_ID} || ${J_ID} ) {
/nomodkey /shiftkey /itemnotify ${csort_index[${J}]} leftmouseup
/delay 1s ( ${Cursor.ID}==${J_ID} && ${InvSlot[${csort_index[${J}]}].Item.ID}==${I_ID} )
}
/if ( ${J_ID} ) {
/nomodkey /shiftkey /itemnotify ${csort_index[${I}]} leftmouseup
/delay 1s ( ${InvSlot[${csort_index[${I}]}].Item.ID}==${J_ID} )
}
/if ( ${Cursor.ID} ) {
/echo CSORT_Array: Error: ${Cursor.Name}
}
}
/next I
/if ( ${gap_i}>1 || ${swapped} ) /goto :resort
/return
|*
|* Return respectively the first or last address inside a container when
|* when given a bank, sharedbank, or pack address. If the item is not a container,
|* then the original address is returned.
|*
Sub CSORT_BagSlot_Start(int bagslot)
/declare I int local 0
/if ( ${bagslot}>=22 && ${bagslot}<=29 ) {
/if ( ${InvSlot[${bagslot}].Item.Container}>0 ) {
/varcalc I ${bagslot}*10+31
} else {
/varcalc I ${bagslot}
}
/return ${I}
}
/if ( ${bagslot}>=2000 && ${bagslot}<=${csort_bank_max} ) {
/if ( ${InvSlot[${bagslot}].Item.Container}>0 ) {
/varcalc I ${bagslot}*10-17969
} else {
/varcalc I ${bagslot}
}
/return ${I}
}
/if ( ${bagslot}>=2500 && ${bagslot}<=2501 ) {
/if ( ${InvSlot[${bagslot}].Item.Container}>0 ) {
/varcalc I ${bagslot}*10-22469
} else {
/varcalc I ${bagslot}
}
}
/return ${I}
Sub CSORT_BagSlot_End(int bagslot)
/declare I int local 0
/if ( ${bagslot}>=22 && ${bagslot}<=29 ) {
/if ( ${InvSlot[${bagslot}].Item.Container}>0 ) {
/varcalc I ${bagslot}*10+31+(${InvSlot[${bagslot}].Item.Container}-1)
} else {
/varcalc I ${bagslot}
}
/return ${I}
}
/if ( ${bagslot}>=2000 && ${bagslot}<=${csort_bank_max} ) {
/if ( ${InvSlot[${bagslot}].Item.Container}>0 ) {
/varcalc I ${bagslot}*10-17969+(${InvSlot[${bagslot}].Item.Container}-1)
} else {
/varcalc I ${bagslot}
}
/return ${I}
}
/if ( ${bagslot}>=2500 && ${bagslot}<=2501 ) {
/if ( ${InvSlot[${bagslot}].Item.Container}>0 ) {
/varcalc I ${bagslot}*10-22469+(${InvSlot[${bagslot}].Item.Container}-1)
} else {
/varcalc I ${bagslot}
}
}
/return ${I}