swap.mac -- Complete Auto-Inven Mover Utility. Version 2.5.5

Post your completed (working) macros here. Only for macros using MQ2Data syntax!

Moderator: MacroQuest Developers

Chill
Contributing Member
Contributing Member
Posts: 435
Joined: Fri May 07, 2004 5:06 pm
Location: Erie, PA

Post by Chill » Thu May 20, 2004 6:26 pm

k think this gonna work but wanted to double check 2 things:

1) Renamed Sub Main to Sub Swap and saved this as swap.inc - need to do anything more?

2) Is there any better way to do this:

Code: Select all

/call swap "swap:Stonehide Tunic=Chestwraps of Enlightenment|clicky:chest|swap:Chestwraps of Enlightenment=Stonehide Tunic"
Its probably obvious, but I want to swap a piece of gear Im wearing with an item from a bag, click, and swap it back where it was.

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

Post by Preocts » Thu May 20, 2004 7:13 pm

Chill: In a nutshell, that is the easiest way. Also, yes, for the .inc conversion. You don't even need Sub Main at all. The only thing Sub Main is doing is checking the current state of your inventory windows and then reseting them after the macro is finished. Inbetween those two tasks the entire bulk of the macro runs in Sub Parser.
So you could just /call Parser "your commands here" and it will work just as well.
Gabby wrote:What Im trying to do (if its even possible) is to get one master command that checks both Mainhand and Offhand for what is on the cursor and/or slot than put it inside a bag in its appropriate slot.
Hmmm, okay. I think I understand what you are asking here. You want to say "If my Singing Short Sword isn't already in my ofhand then move it there, and equip my whip at the same time". right? ((if I'm wrong just ask again, clearer :wink: ))

Code: Select all

IfIn?Singing Short Sword:MainHand?[color=orange]-1?[/color][color=red]Pickup:Mainhand/Moveto:Singing Short Sword>OffHand/Moveto:Whip of Unending Pain>MainHand/Empty?[/color]
The -1 is what we want the macro to do If the SSS IS in the offhand already, a true statement, which is nothing. The second part is what to do on a false statement.
Saddly you cannot 'nest' if statements for this macro. If you wanted to do something like "If this is true and this is true then do this" you'd have to call an ini'ed commandset that does the second If statement from within the first if statement.

This is actually what my bard uses to make sure her gear stays in the proper bags. This is just one of the many I have. This one clears out her mainhand and puts her horn in the offhand. About as close to nested ifs as you get.
/call swap BardCheckMain@

Code: Select all

BardCheckMain=ifin?Symphonic Saber:Main Hand?Moveto:Symphonic Saber>Pack7/BardCheckOff@?BardCheckMain2@?
BardCheckMain2=ifin?Bloodied Flute:Main Hand?Moveto:Bloodied Flute>Pack8/BardCheckOff@?Moveto:Trueborn Drum of Dark Rites>Pack6/BardCheckOff@?
BardCheckOff=ifin?Battle Drummer's Main Gauche:OffHand?Moveto:Battle Drummer's Main Gauche>Pack4!1/Moveto:Torin's Horn>OffHand/Empty?Swap:MainHand=Torin's Horn?

Gabby
a lesser mummy
a lesser mummy
Posts: 49
Joined: Sat Mar 13, 2004 10:35 am

Post by Gabby » Thu May 20, 2004 9:15 pm

Perfect Preocts ! just link each check in the *.ini. Ya did it again thank ya )

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

Post by Preocts » Fri May 21, 2004 6:21 am

Was writting some really complex changes for my bard today when I realized I'd save time if I could just ask "Is there something on my cursor?" or "Is there anything at all in this slot" .... so I added the functions to the macro. 8)

Code: Select all

IfOn?*?There is something on the cursor?There is nothing?
IfIn?*:MainHand?There is something in MainHand?MainHand is empty?

Phox
orc pawn
orc pawn
Posts: 29
Joined: Fri Mar 19, 2004 6:44 am

Post by Phox » Fri May 21, 2004 2:48 pm

Awesome macro. I had to increase the delay a little bit on the OpenPack sub but otherwise works like a charm.

User avatar
Fuergrissa
a grimling bloodguard
a grimling bloodguard
Posts: 607
Joined: Mon Dec 08, 2003 3:46 pm
Location: UK

Post by Fuergrissa » Sun May 23, 2004 4:48 am

Preocts would it be possible for you to help me out here, im working on a Bard Song Trainer, i have most of it done sing,max song, move to next song etc, i want to add instrument swap from your macro, i just need to incorporate your swap mac but im sure i dont want all the mac you have written as we already know its gonna go into the secondary slot, if you are too busy to help ill just use your whole mac and make it an inc, but i like to have it tidy if i can
here is what ill be passing to your section to do the equip in

Code: Select all

Sub SwapInst

Code: Select all

  /varset brass "McVaxius`Horn of War"
  /varset stringed "Mandolin"
  /varset wind "Flute of Eternal Night"
  /varset perc "Selo`s Drums of the March"
Many Thanks in advance, if your too busy just say and ill work around it.
[quote]"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning."[/quote]

MQ_Wannabe
Custom Builder
Custom Builder
Posts: 27
Joined: Wed Nov 12, 2003 9:51 pm

Post by MQ_Wannabe » Wed May 26, 2004 2:24 am

So here is my ini file...

[SwapCommands]
SeeInvis="Moveto:Bracer of the hidden>LeftWrist|Clicky:LeftWrist|Pickup:LeftWrist|Empty|DainRing@"
DainRing="clicky:RightFinger|JBoot@"
JBoot="clicky:Journeyman's Boots|Patch@"
Patch="Moveto:Eyepatch of Plunder>Face|Clicky:face|Pickup:Face|Empty"

I cant for the life of me get it to click all of them.

Am I doing something wrong? Half the time, the macro wont return the Bracer back to the Left Wrist that the Hidden one is on. So I cant get the Benevolance bracer back on less i do it manually...

It either totally skips the JBoots or does the jboots and not the eyepatch. (but the patch always goes back in the bag and mask is requipped...)

Any advice?

Thanks.

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

Post by Preocts » Wed May 26, 2004 12:24 pm

Hmmm.. might just be moving too fast for the game to respond. Might just be something in my code. I'll take a look at it tomorrow, soonest I'll have a console to use. In the meanwhile, once you can, try turning the #Turbo down or adding a /delay 3 at the very begining of Sub HandleCommand

I actually don't use the clicky command that much, wrote it for my rogue who doesn't see much use, so I'll look into it.

Phox
orc pawn
orc pawn
Posts: 29
Joined: Fri Mar 19, 2004 6:44 am

Post by Phox » Sat Jun 05, 2004 6:35 pm

What happened to the original code?
This macro was very useful, please bring it back!!

StinkyBean
decaying skeleton
decaying skeleton
Posts: 2
Joined: Sun Jun 06, 2004 9:42 pm

Post by StinkyBean » Sun Jun 06, 2004 9:48 pm

Looks like Preocts had some sort of mental breakdown and edited out all his macros. Yay for maturity! Here's the original code. Note that as of a few days ago (it might've been fixed already), you'll have to edit mq2datatypes.cpp per this thread, otherwise the macro will not work.

Code: Select all

|** Swap.mac Version 2.5.5 by: Preocts   Updated Last: 05/20/2004

Introduction:
  A much much much evolved version of my old switch.mac that I wrote about
  a month ago. This one is VERY flexible in what you can do. Ini or param
  driven commands. You can also store ini commands in-game. Does not open
  your inventory window but will open packs as needed. Resets your packs
  after macro is done so if you had 'that' one open it will remain open.

  I use this most heavily on my bard, allowing me to swap instruments out
  with a push of a hotkey. Wrote in a clicky command for my rogue who always
  seemed to lose her buff gear in her packs! ((cronic packrat))

  This is written to be modular and expanded. Almost all the subs handle one
  aspect of the 'switch' so adding this to your existing macros as an include
  should be almost painless.

Making an Include File: (or using parts of this macro)
  There are 7 subs below that can be pulled out of this entire macro and
  used inside your own macros for the manipulation of items and slots.
  The two rightclick subs will wait for any casting items to finsih before
  releasing control back to where they were called
     1) Sub LeftClickItem(ItemName) <------ Searches, finds, left clicks
     2) Sub LeftClickSlot(Slot) <---------- Left clicks any slot name or num
     3) Sub LeftClickPackSlot(Pack,Slot) <- Opens bags, then left clicks
     4) Sub RightClickItem(ItemName) <----- For those rightclick items
     5) Sub RightClickSlot(Slot) <--------- Same, but with slotnames
    *6) Sub OpenPack(Pack) <--------------- Needed for 1, and 3
    *7) Sub DisplayError(sInput) <--------- Needed for ALL the above.
  The parameters they need are self explaining. If you want to use them just
  copy them and the following two subs to you macro file or an include.
  *These are standalones but required if you use 1-5
Alternative:
  Just rename Sub Main to Sub SwapMain or something else. Then just call
  the newly named sub from any macro /call SwapMain "command" and viola!
  ((sub main is not actually needed. Sub Parser does _all_ the work))

Some important notes:
+ If the item is stacked the ENTIRE stack is picked up.
+ Be cool. "Enclose your commandline in quotes"
+ Options are explicit. If it tells you [ItemName]>[SlotName/CustomName] then
  that is what you MUST give it. IN THAT ORDER!
+ All commands must be separated by | when entering mulitple actions. The
  expection are IF commands. They use /. Mixing will cause problems.
+ No command will check Cursor Status before executing. Assumed Empty!
  This means you need to think your logic out. If move an item to your neck
  slot and then move an item to your mainhand, be sure you did something with
  the item that 'was' in your neck slot before you began.
+ Clicky Commands for items inside packs are pointless and will do nothing.
+ bouncy bouncy bouncy bouncy boun- damnit
+ HolyShit! Did I just add IF statements? Why yes! Yes I did.
+ Small little updates. Macro now scans bank slots, when the bank is open.
+ IF commands now have a "*" flag. * = anything. (see below)
+ IF commands can not now be, nor will ever be able to be, nested.
+ Should you get confused about all the ?s, >s, |s, =s, and /s don't fret.
  These are simple dividers the macro uses to separate one command from the
  next and one option of a command from another option.

Commands:

+ "Swap:[ItemName/SlotName/CustomName]=[ItemName/SlotName/CustomName]"
   Puts the first item you give it where the second is and puts the second
   where the first was.

+ "MoveTo:[ItemName]>[SlotName/CustomName]"
   Moves Item to Slot

+ "PickUp:[ItemName/SlotName/CustomName]"
   Places Item onto cursor (More literally, preforms a leftmouseup on [])

+ "Clicky:[ItemName/SlotName]"
   Rightclicks Item/Slot. Waits for Cast.

+ "Empty"
   Smart Empty of Cursor. Fails on full Inv.

+ "IfOn?ItemName?TrueAction/?FalseAction/?"
   If ItemName is on the cursor, preform TrueAction. Else, preform FalseAction
   Ending ? is required or you risk errors.
   Actions can contain more than one command. Divider inside Ifs is / not |.
   Neither True or False actions are required. ?-1? will skip that action
   Placing a "*" for the itemname causes a true statement if anything is on
   the cursor, a false if the cursor is empty.

+ "IfIn?ItemName:SlotName?TrueAction/?FalseAction/?"
   If ItemName is in SlotName then do TrueAction, else do FalseAction.
   Ending ? is required or you risk errors. CANNOT CHECK INSIDE PACKS.
   Actions can contain more than one command. Divider inside Ifs is / not |.
   Neither True or False actions are required. ?-1? will skip that action
   Placing a "*" for the itemname causes a true statement if anything is in
   that slot, a false if the slot is empty.
   
+  "KeyName$Commands"
    Writes Commands to KeyName in the INI file. Does not run Commands.

Options:
  [ItemName] are full item names only. No partial names will be found.
  [SlotName] The following list are valid slot names:
    mainhand offhand ranged charm leftear rightear leftwrist rightwrist arms
    head neck face shoulder chest legs waist rightfinger leftfinger feet ammo
    back pack1-8 Bank1-16 Loot1-31 SharedBank1-2 Merchant1-80 Trade1-8
    Enviro1-10 World1-10
    (Slot Numbers will work as long as they are not located inside a pack)
  [CustomName] may be used to identify a slot inside a pack. Format:
    pack1!2     Slot 2 in Pack1
    bank5!4     Slot 4 in Bank5 (only if bank window is open)
    (Forces the macro to make sure that pack is open)

Using Swap.Mac:
  Something to always remember: Swap.Mac does not care what is on the cursor
  when it runs a command. That's why I made Ifs.

  /macro swap "Swap:Foraging Machette=Scimitar of the Emerald Dawn"
    Swaps the two items between their current slots.

  /macro swap "MoveTo:Fisherman's Companion>Pack8!3"
    Moves Companion to pack8, slot three. Note: if anything was there it is
    now on the cursor.

  /macro swap "pickup:arms"
    Leftclicks the arms slot.

  /macro swap "Clicky:LeftEar"
    This rightclicks your left ear piece.

  /macro swap "Moveto:Shrunken Goblin Skull Earring>LeftEar|Clicky:LeftEar|Pickup:LeftEar|Empty"
    Moves your SGSE to your ear slot (whatever was there in on cursor)
    Clicks the slot, casting the self-buff
    Picks up the SGSE(leftear) which places whatever was there back there.
    Empty the Cursor.

  /macro swap "EarBuff$Moveto:Shrunken Goblin Skull Earring>LeftEar|Clicky:LeftEar|Pickup:LeftEar|Empty"
    Writes the command to ini. DOES NOT RUN COMMANDS
    Ini would then contain:
      EarBuff=Moveto:Shrunken Goblin Skull Earring>LeftEar|Clicky:LeftEar|Pickup:LeftEar|Empty

  /macro swap "EarBuff@"   <------- MUST end with @ to pull from ini.
    The same thing as:
  /macro swap "Moveto:Shrunken Goblin Skull Earring>LeftEar|Clicky:LeftEar|Pickup:LeftEar|Empty"

  /macro swap "IfOn?Foraging Machette?pickup:MainHand/Empty?-1?"
    If your foraging Machette is on the cursor, place it in the MainHand
    slot and empty cursor.

  /macro swap "IfIn?Shrunken Goblin Skull Earring:LeftEar?clicky:LeftEar?EarBuff@?
    If the SGKE is in the leftear click it.
    Otherwise, do a bunch of commands to put the earring in the LeftEar
    slot and click it.

Rules about IFs
  1) Thou shalt not ever nest IFs.
  2) Thou shalt not ever use | in IFs. Thou shall use / instead.

Ini File:
  Default Ini Filename: Swapper.ini

  Example:
    [SwapCommands]
    Drums=Swap:OffHand=Mistmoore Battle Drums|
    Lute=Swap:OffHand=Lute|
    Fight=PickUp:OffHand|MoveTo:Symphonic Saber>MainHand|MoveTo:Battle Drummers Main Gauche>OffHand|
    Kite=PickUp:MainHand|MoveTo:Mistmoore Battle Drums>OffHand|Empty|
    EarBuff=Moveto:Shrunken Goblin Skull Earring>LeftEar|Clicky:LeftEar|Pickup:LeftEar|Empty

Examples of things you can now do:
  [SwapCommands]
  Wow=Drums@|Lute@|EarBuff@
  /macro swap "Wow@"
  /macro swap "ifin?Mistmoore Battle Drums:offhand?Lute@?Drums@?"

Never End Loop: (really simple "duh!" kind of example)
  [SwapCommands]
  Set1=bunchofcommandshere|Swap2@
  Set2=bunchmorecommandshere|Swap1@

  /macro swap Swap1@

  THIS WILL NEVER STOP! Set1 calls Set2 which calls Set1 again, on and on.

A way to nest IF statements: ((using swapcommands))
  While you cannot nest IFs in the same commandline you can call another
  CommandSet that contains an IF statement from an IF statement.
  [SwapCommands]
  MyIF1=ifin?ItemName:MainHand?Do these actions?MyIF2@?
  MyIF2=ifin?*?MainHand?Something is there, do these actions?okay, where did my dagger of dropping go?

  /call swap MyIF1@
    Psudo-Logic:
      If Itemname is in my mainhand do this. Else, is anything in my mainhand
      and if so do these. If not I don't know what's up so do this.

**|

#Turbo 10
#define IniFileName Swapper.ini

Sub Main(sInput)
  /if (!${Defined[sInput]}) /call DisplayError "SwitchMain;No Parameter Defined"
  /if (${sInput.Right[1].NotEqual[|]}) /varset sInput ${sInput}|

|  /declare GlobalTimerOut timer outer 0
  /declare nCount int local
  /declare InvState[8] int local

  /if (${sInput.Find[$]}) {
    /ini "IniFileName" "SwapCommands" "${sInput.Arg[1,$]}" "${sInput.Arg[2,$]}"
    /echo Written to IniFileName:
    /echo ${sInput.Arg[1,$]}=${sInput.Arg[2,$]}
    /return
  }

  /for nCount 1 to 8
    /if (${Window[Pack${nCount}].Open}) {
      /varset InvState[${nCount}] 0
    } else {
      /varset InvState[${nCount}] 1
    }
  /next nCount

  /call Parser "${sInput}"

  /for nCount 1 to 8
    /if (${Window[Pack${nCount}].Open} && ${InvState[${nCount}]}) /itemnotify Pack${nCount} rightmouseup
    /delay 1
  /next nCount

/return

Sub Parser(sInput)
  /if (!${Defined[sInput]}) /call DisplayError "Parser;No Parameter Defined"
  /if (${sInput.Right[1].NotEqual[|]}) /varset sInput ${sInput}|

  /declare CommandSet string local
  /declare nCount int local 1

  :ParserLoop
    /if (${sInput.Arg[${nCount},|].Find[@]} && !${sInput.Arg[${nCount},|].Find[if]}) {
      /varset CommandSet ${Ini[IniFileName,SwapCommands,${sInput.Arg[${nCount},|].Arg[1,@]},NOTFOUND]}
      /if (${CommandSet.Equal[NOTFOUND]}) /call DisplayError "Main;Swapset ${sInput.Arg[${nCount},|].Arg[1,@]} not found"
      /call Parser "${CommandSet}"
    } else {
      /call HandleCommand "${sInput.Arg[${nCount},|]}"
    }
    /varcalc nCount ${nCount}+1
  /if (${sInput.Arg[${nCount},|].Length}) /goto :ParserLoop
/return

Sub IfCommandSet(sInput)
|This does absolutly nothing with the commands given. It only changes
|all the /s to |s for the main parser.
  /if (!${Defined[sInput]}) /call DisplayError "IfCommandSet;No parameter given"
  /if (${sInput.Equal[-1]}) /return
  /declare nStep int local 1
  /declare sStep string local

  /for nStep 1 to ${sInput.Length}
    /if (${sInput.Mid[${nStep},1].Equal[/]}) {
      /varset sStep ${sStep}|
    } else {
      /varset sStep ${sStep}${sInput.Mid[${nStep},1]}
    }
  /next nStep
  /call Parser "${sStep}"
/return

Sub HandleCommand(sInput)
  /if (!${Defined[sInput]}) /call DisplayError "HandleCommand;No Parameter Defined

|IfOn: IF statement directly checks the cursor.name and compares. Pulls the
|resulting command out of sInput and parses them separetly.
  /if (${sInput.Arg[1,?].Equal[IfOn]}) {
    /if (${Cursor.Name.Equal[${sInput.Arg[2,?]}]}) {
      /call IfCommandSet "${sInput.Arg[3,?]}"
    } else {
      /if (${sInput.Arg[2,?].Equal[*]} && ${Cursor.ID}) {
        /call IfCommandSet "${sInput.Arg[3,?]}"
      } else {
        /call IfCommandSet "${sInput.Arg[4,?]}"
      }
    }
  }

|IfIn: If statement checks for the presents of an item in a slot. Pulls the
|resulting command out of sInput and parses them separetly. ITEM BEFORE SLOT
  /if (${sInput.Arg[1,?].Equal[IfIn]}) {
    /if (${sInput.Arg[2,?].Arg[2,:].Find[!]}) /varset ${sInput}
    /if (${InvSlot[${sInput.Arg[2,?].Arg[2,:]}].Item.Name.Equal[${sInput.Arg[2,?].Arg[1,:]}]}) {
      /call IfCommandSet "${sInput.Arg[3,?]}"
    } else {
      /if (${sInput.Arg[2,?].Arg[1,:].Equal[*]} && ${InvSlot[${sInput.Arg[2,?].Arg[2,:]}].Item.ID}) {
        /call IfCommandSet "${sInput.Arg[3,?]}"
      } else {
        /call IfCommandSet "${sInput.Arg[4,?]}"
      }
    }
  }

|Swap: Most complex since both params can be any of the three types. Determine
|what type the param is, send a leftclick command, then do the same for the
|next param. In the end send a leftclick command to the slot used in the first
|param. Follow?
  /if (${sInput.Arg[1,:].Equal[Swap]}) {
    /varset sInput ${sInput.Arg[2,:]}
    /declare Param1 string local ${sInput.Arg[1,=]}
    /declare Param2 string local ${sInput.Arg[2,=]}
    /declare SlotUsed int local
    /if (${Param1.Find[!]}) {
      /call LeftClickPackSlot ${Param1.Arg[1,!]} ${Param1.Arg[2,!]}
    } else {
      /call ValidSlot ${Param1}
      /if (${Macro.Return.Equal[true]}) {
        /call LeftClickSlot "${Param1}"
        /varset SlotUsed ${InvSlot[${Param1}].ID}
      } else {
        /call LeftClickItem "${Param1}"
        /varset SlotUsed ${Macro.Return}
      }
    }
    /if (${Param2.Find[!]}) {
      /call LeftClickPackSlot ${Param2.Arg[1,!]} ${Param2.Arg[2,!]}
    } else {
      /call ValidSlot ${Param2}
      /if (${Macro.Return.Equal[true]}) {
        /call LeftClickSlot "${Param2}"
      } else {
        /call LeftClickItem "${Param2}"
      }
    }
    /call LeftClickSlot ${SlotUsed}
  }

|MoveTo: Pickup the item and move it to the slot. Nothing is done to the
|cursor after this point. i.e. If the slot had an item in it that item is now
|on the cursor.
  /if (${sInput.Arg[1,:].Equal[Moveto]}) {
    /varset sInput ${sInput.Arg[2,:]}
    /call LeftClickItem "${sInput.Arg[1,>]}"
    /varset sInput ${sInput.Arg[2,>]}
    /if (${sInput.Find[!]}) {
      /call LeftClickPackSlot ${sInput.Arg[1,!]} ${sInput.Arg[2,!]}
    } else {
      /call LeftClickSlot "${sInput}"
    }
  }

|PickUp: Determine whether the param given is a slot/packslot/or item then
|send the proper leftclick command. Does not concider any items already on
|the cursor.
  /if (${sInput.Arg[1,:].Equal[PickUp]}) {
    /varset sInput ${sInput.Arg[2,:]}
    /if (${sInput.Find[!]}) {
      /call LeftClickPackSlot ${sInput.Arg[1,!]} ${sInput.Arg[2,!]}
    } else {
      /call ValidSlot ${sInput}
      /if (${Macro.Return.Equal[true]}) {
        /call LeftClickSlot "${sInput}"
      } else {
        /call LeftClickItem "${sInput}"
      }
    }
  }

|Clicky: Determine whether the param given is a slot or item. Send a click
|command to that slot/item. Very simple.
  /if (${sInput.Arg[1,:].Equal[Clicky]}) {
    /varset sInput ${sInput.Arg[2,:]}
    /call ValidSlot ${sInput}
    /if (${Macro.Return.Equal[true]}) {
      /call RightClickSlot "${sInput}"
    } else {
      /call RightClickItem "${sInput}"
    }
  }

|Empty: Easiest of all. Empty the cursor of any contents as long as there is
|room for them in the inventory. Will error exit if there is not room.
  /if (${sInput.Arg[1,:].Equal[EMPTY]}) {
    /call Command_Empty
  }

| /delay 1
/return

| BEGIN THE GUTS OF THE MACRO ------------------------

Sub LeftClickItem(ItemName)
  /if (!${Defined[ItemName]}) /call DisplayError "LeftClickItem;No Parameter"
  /declare CC int local ${Cursor.ID}
  /if (${Window[BigBankWnd]}) {
    /declare ItemLoc int local ${FindItem[=${ItemName}].InvSlot.ID}
    /if (!${ItemLoc}) {
      /varset ItemLoc ${FindItemBank[=${ItemName}].InvSlot.ID}
      /if (!${ItemLoc}) /call DisplayError "LeftClickItem;${ItemName} not found in inventory or bank."
    }
  } else {
   /declare ItemLoc int local ${FindItem[=${ItemName}].InvSlot.ID}
   /if (!${ItemLoc}) /call DisplayError "LeftClickItem;${ItemName} not found in inventory."
  }
  /if (${InvSlot[${ItemLoc}].Pack.ID}) /call OpenPack ${InvSlot[${ItemLoc}].Pack.ID}
|Inventory Window doesn't need to be open but Packs do for /itemnotify to work
  /shift /itemnotify ${ItemLoc} leftmouseup
  /declare TimerOut timer local 2s
  :LCIWait
    /if (!${TimerOut}) /call DisplayError "LeftClickItem;Operation Timed Out"
    /if (${Cursor.ID}==${CC}) /goto :LCIWait
|Stay in loop until timeout or cursor change. Error exit on timeout because
|something has gone wrong at that point. The item WAS reported in the slot
|we DID just click. If we don't get a change in the cursor....
|Return ItemLoc so we can use it in a Swap call.
|ItemLoc==SlotNumber of where we just got this item.
/return ${ItemLoc}

Sub LeftClickSlot(Slot)
  /if (!${Defined[Slot]}) /call DisplayError "LeftClickSlot;No Parameter"
  /declare CC int local ${Cursor.ID}
  /shift /itemnotify ${Slot} leftmouseup
  /declare TimerOut timer local 2s
  :LCSWait
    /if (${Cursor.ID}==${CC} && ${TimerOut}) /goto :LCSWait
|Keep in loop until cursor changes or timeout. Don't error on timeout since
|we can assume no cursor change meant that slot was empty or the item can't
|go into that slot.
/return

Sub LeftClickPackSlot(Pack,Slot)
  /if (!${Defined[Pack]} || !${Defined[Slot]}) /call DisplayError "LeftClickPackSlot;No Parameter"
  /declare CC int local ${Cursor.ID}
  /call OpenPack ${Pack}
  /shift /itemnotify in ${Pack} ${Slot} leftmouseup
  /declare TimerOut timer local 2s
  :LCPSWait
    /if (${Cursor.ID}==${CC} && ${TimerOut}) /goto :LCPSWait
|Keep in loop until cursor changes or timeout. Don't error on timeout since
|we can assume no cursor change meant that slot was empty or the item can't
|go into that slot.
/return

Sub RightClickItem(ItemName)
  /if (!${Defined[ItemName]}) /call DisplayError "RightClickItem;No Parameter"
  /declare ItemLoc int local ${FindItem[=${ItemName}].InvSlot.ID}
  /if (!${ItemLoc}) /call DisplayError "RightClickItem;Error, ${ItemName} not found in inventory."

  /if (${InvSlot[${ItemLoc}].Pack.ID}) /return
|If the item is inside a pack just exit. Nothing happens if you click them.
  /itemnotify ${ItemLoc} rightmouseup
  /delay 2
  :WaitForCast
    /if (${Me.Casting.ID}) /goto :WaitForCast
|Really nothing to check beyond waiting for a spell to cast. Either something
|happens or something doesn't. Items don't fizzle and one should hope this
|isn't being used to cast a Crusiable of Escape where interuppts matter.
/return

Sub RightClickSlot(Slot)
  /if (!${Defined[Slot]}) /call DisplayError "RightClickSlot;No Parameter"
  /itemnotify ${Slot} rightmouseup
  /delay 2
  :WaitForCast
    /if (${Me.Casting.ID}) /goto :WaitForCast 
|Yay, so easy. Slot name->Click->WaitForCast->DONE!
/return

Sub OpenPack(Pack)
|Input can be string or int.
  /if (!${Defined[Pack]}) /call DisplayError "OpenPack;No Parameter Defined"
|Looks reduntant but makes sense. This allows either a slotname or number to be evaluated.
  /if (!${Window[${InvSlot[${Pack}].Name}].Open}) {
    /itemnotify ${Pack} rightmouseup
    /declare TimerOut timer local 4s
    :Wait1
    /if (!${TimerOut}) /call DisplayError "OpenPack;Error Could Not open ${InvSlot[${Pack}].Name}"
    /if (!${Window[${InvSlot[${Pack}].Name}].Open}) /goto :Wait1
    /delay 3
|Bags seem to take a few extra cycles to register 'open' with both MQ and EQ, hence the /delay
  }
/return

Sub DisplayError(sInput)
  /echo Warning, Error. Macro Ended in Sub ${sInput.Arg[1,;]}
  /if (${sInput.Arg[2,;].Length}) /echo Error Message: ${sInput.Arg[2,;]}
  /endmacro
/return

| END THE GUTS OF THE MACRO ------------------------


Sub Command_Empty
|Rather basic. Exception is now we can make sure there is room for the item.
  :EmptyLoop
    /if (!${Cursor.ID}) /return
|Better to end the macro than drop something really important.
    /if (!${Me.FreeInventory[${Cursor.Size}]}) /call DisplayError "Command_Empty:No Inventory Space for ${Cursor.Name}."
    /autoinventory
  /goto :EmptyLoop
/return 

Sub ValidSlot(SlotName)
|Input can be string or int.
  /if (!${Defined[SlotName]}) /call DisplayError "ValidSlot;No Parameter Defined"
|If the slotname or number has an ID then it exists.
  /if (${InvSlot[${SlotName}].ID}) {
    /return TRUE
  } else {
    /return FALSE
  }
/return FALSE 

Drumstix42
a grimling bloodguard
a grimling bloodguard
Posts: 808
Joined: Mon May 03, 2004 4:25 pm

Post by Drumstix42 » Sun Jun 06, 2004 10:55 pm

In that topic it also says it's fixed in latest zip ^.^

StinkyBean
decaying skeleton
decaying skeleton
Posts: 2
Joined: Sun Jun 06, 2004 9:42 pm

Post by StinkyBean » Mon Jun 07, 2004 10:51 am

Drumstix42 wrote:In that topic it also says it's fixed in latest zip ^.^
The zip as of "June 04 2004 15:25:36" does not have the change in MQ2DataTypes.cpp :shock:

Maybe it was checked in but never put into the zip? I don't know how they handle that.

Drumstix42
a grimling bloodguard
a grimling bloodguard
Posts: 808
Joined: Mon May 03, 2004 4:25 pm

Post by Drumstix42 » Mon Jun 07, 2004 3:23 pm

maybe they fixed it somewhere else, so that it wasn't causing an error there any more <shrug>