Find missing Combat Abilities, Spells & Songs then Purchase

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

Moderator: MacroQuest Developers

nod77
orc pawn
orc pawn
Posts: 20
Joined: Thu Jul 03, 2008 7:26 pm

Find missing Combat Abilities, Spells & Songs then Purchase

Post by nod77 » Mon Jun 25, 2012 1:28 am

These macro's are modified and renamed from the ones found in the links below. I'm creating a new combined thread for these to reflect thier changed functionality. This will help the people who use search.

I've also combine the mac from the vendor thread since POK now has the majority of spells in the Library and thus the merchants portion will not be so large.

SpellsToBuy.mac (now SCAPurchase.mac) viewtopic.php?f=43&t=8519&hilit=spellstobuy
http://www.mmobugs.com/forums/everquest ... pells.html
SpellVendors.mac (now SCAmerchants.mac) viewtopic.php?p=64085

Functionality:
This macro (SCAPurchase.mac) searches for missing spells, abilities or songs your character my not have. Then, once you are at the appropriate merchant, will purchase them. It starts by searching for the missing spells, songs or abilities then, after it's searched it waits for commands to be sent to it through /echo.

The commands availiable are:
Log
-writes the missing spells to a log file (/mqlog)

BuySpells
-if you have an open merchant window it will buy the spells you are missing that are in the merchant's inventory

Bazaar
-if you are in the bazaar it searches merchants for the spells you are missing and reports the lowest price

Searchmerchant
-searches for spell merchants in inifiles made SCAMerchants.mac

SearchMerchantDump
-same as SearchMerchant but it writes to logfile instead

SpellsToScribe
-lists the spells you have in your bags that you are high enough to scribe but haven't yet

It will allow you to specify a maxlevel above your current level so you can see what spells you want to buy before you ding.
It will look for the scrolls in your bank and bags if the spell isn't in your spellbook and report that accordingly.

The second macro (SCAMerchants.mac) is a macro to create a SCAMerchant.ini file containing merchant Name and Zone data that is used by teh SearchMerchant function. It's organized by Spell ID, to support SCAPurchase.mac. It will also create a second SCAMerchantList file containing merchant Name and Loc data, organized by Zone, for cross refrence. To use it simply target a spell merchant or open the merchant window and type /mac SCAMerchants. The macro runs a continious loop once you start it and will scan each Merchant window you open, then close the window.

Updates:
SCAPurchase.mac
-Added support for Combat Abilities
-Will now check the list against your combat abilities and will no longer list them as missing if you have them.
-All functionality such as (BuySpells, SpellsToScribe, SearchMerchants etc.) now work for Combat Abilities too.
-Fixed the "Buyspells" functionality

SCAMerchants.mac
-Added support for Tomes that give Combat Abilities
-Modified the code so that it won't pick up Spells or Tomes that players have sold back to Merchants thus, resulting in a erroneous merchant listing for a spell.
-Added a delay before it queries the merchant as it was doing the query too early and not getting all the spells.

SCAPurchase.mac

Code: Select all

|Usage:
| /macro SCAPurchase.mac
|  lists every spell to be bought
| /macro spellstobuy <level>
|  lists every level <level> spell to be bought
| /macro spellstobuy <minlevel> <maxlevel>
|  lists every level <minlevel> to level <maxlevel> spell to be bought
|
| Updated June 23rd, 2012 by nod77
| This macro is updated and renamed from SpellsToBuy.mac Original Thread can be found here;
| http://www.macroquest2.com/phpBB3/viewtopic.php?f=43&t=8519&hilit=spellstobuy
| This macro will now check the list against your combat abilities and won't list it as missing if you already have it.
| All functionality such as (BuySpells, SpellsToScribe, SearchMerchants etc.) now work for combat abilities too.
| Fixed the "Buyspells" functionality
| I've also modified and renamed SpellVendors.mac to SCAMerchants.mac in order to support and reflect this new functionality
| Original Thread for SpellVendors.mac can be found here; http://www.macroquest2.com/phpBB3/viewtopic.php?p=64085
| Bank search is still disabled.

#event Bazaar "[MQ2] Bazaar"
#event Merchant "[MQ2] BuySpells"
#event Log "[MQ2] Log"
#event SearchMerchants "[MQ2] SearchMerchants"
#event SearchMerchantLog "[MQ2] SearchMerchantDump"
#event SpellsToScribe "[MQ2] SpellsToScribe"

Sub Main
/declare Verbose int outer 1
/declare MaxIndex int local 33001
/declare x int local
/declare LevelMin int local
/declare MaxLevel int local
/declare SpellsMissing int outer 0
/declare SpellNames[2000] string outer
/declare SpellIDs[2000] int outer
/declare SpellLevels[2000] int outer

/if (!${Plugin[MQ2CEcho].Name.Length}) /plugin mq2cecho

/if (!${Defined[STB_BuySpellStatus]}) /declare STB_BuySpellStatus int global

/if (${Defined[Param0]}) {
  /varset LevelMin ${Param0}
} else {
  /varset LevelMin 1
}
/if (${Defined[Param1]}) {
  /varset MaxLevel ${Param1}
} else {
  /varset MaxLevel ${Me.Level}
}

/echo Searching for missing ${Me.Class} spells level ${LevelMin} to ${MaxLevel}...
/for x 1 to ${MaxIndex}
  /if (!${Me.Book[${Spell[${x}]}]} && !${Me.CombatAbility[${Spell[${x}]}]} && !${Spell[${x}].Name.Find[Rk. II]}) {
   /if (${MaxLevel}) {
    /if (${Spell[${x}].Level}<=${MaxLevel}&&${Spell[${x}].Level}>=${LevelMin}) {
     /call SpellInfo ${x}
    }
   } else /if (${LevelMin}) {
    /if (${Spell[${x}].Level}==${LevelMin}) {
     /call SpellInfo ${x}
    }
   } else {
    /call SpellInfo ${x}
   }
  }
/next x

/echo Search done, waiting for commands. Availiable commands are: Bazaar, BuySpells, SearchMerchants, SearchMerchantDump, SpellsToScribe and Log.

:endlessloop
   /doevents
   /delay 1s
/goto :endlessloop

/return

Sub Event_SpellsToScribe
   /declare Counter int local

   /for Counter 1 to ${SpellsMissing}
      /if (!${Me.Book[${Spell[${SpellIDs[${Counter}]}].Name}]} && ${Spell[${SpellIDs[${Counter}]}].Level}<=${Me.Level}) {
         /if (${FindItemCount[${SpellNames[${Counter}]}]}) {
            /echo ${SpellNames[${Counter}]} is in inventory.
         }
         |/if (${FindItemBankCount[=${SpellNames[${Counter}]}]}) {
         |   /echo ${SpellNames[${Counter}]} is in bank.
         |}
      }
   /next Counter
     
   /echo Done looking for spells to scribe.
/return

Sub Event_SearchMerchants
   /call SearchMerchants 0
/return

Sub Event_SearchMerchantLog
   /call SearchMerchants 1
/return

Sub SearchMerchants(bool Logging)
   /declare Counter int local
   /declare KeyList string local
   /declare KeyTemp string local
   /declare KeyCount int local
   /declare ZoneTemp string local
   /declare FoundSpells bool local 0
   
   /if (${Logging}) /mqlog ---------------------- Merchants with missing spells for ${Me.Name} --------------------------   
   /for Counter 1 to ${SpellsMissing}
      /if (!${FindItemCount[=${SpellNames[${Counter}]}]}) {
         /varset KeyList ${Ini[SCAMerchants.ini,${SpellIDs[${Counter}]}]}
         /if (${String[${KeyList}].NotEqual[NULL]}) {
            /varset KeyCount 1
            :MoreKeys
            /varset KeyTemp ${KeyList.Arg[${KeyCount},|]}
            /if (${String[${KeyTemp}].Equal[Null]}) /goto :NoMoreKeys
            /varset ZoneTemp ${Ini[SCAMerchants.ini,${SpellIDs[${Counter}]},${KeyTemp},]}
            /varset FoundSpells 1
            /if (${Logging}) {
               /mqlog ${SpellNames[${Counter}]} available from ${KeyTemp} in ${ZoneTemp} at loc ${Ini[SCAMerchantsList.ini,${ZoneTemp},${KeyTemp}]}
            } else {
               /echo ${SpellNames[${Counter}]} available from ${KeyTemp} in ${ZoneTemp} at loc ${Ini[SCAMerchantsList.ini,${ZoneTemp},${KeyTemp}]}
            }
            /varcalc KeyCount ${KeyCount}+1
            /goto :MoreKeys
            :NoMoreKeys
         }
      }
   /next Counter
   /if (${Logging}) /mqlog ---------------------- End of merchants for ${Me.Name} ---------------------------------------
   /if (${Logging}) /echo Logging of merchants to ${Macro.Name}.log done.
   /echo Merchant search done. ${If[${FoundSpells},,No matches found.]}
/return

Sub Event_Merchant
   /if (!${Merchant.Open}) {
      /echo You need to open a merchant window.
      /return
   }
   /call BuySpells
/return

Sub BuySpells
   /if (!${Merchant.Open}) /return
   /squelch /custombind add BUYSPELLYES
   /squelch /custombind set BUYSPELLYES-up /varset STB_BuySpellStatus 1
   /squelch /bind BUYSPELLYES shift+y

   /squelch /custombind add BUYSPELLNO
   /squelch /custombind set BUYSPELLNO-up /varset STB_BuySpellStatus 0
   /squelch /bind BUYSPELLNO shift+n

   /if (!${Defined[STB_BuySpellStatus]}) /declare STB_BuySpellStatus int global

   /declare Counter int local
   /declare ItemCounter int local
   /declare ItemSlotNumber int local
   
   /for Counter 1 to ${SpellsMissing}
      /varset ItemSlotNumber 0
      /varset STB_BuySpellStatus 2
      /if (${Merchant.Item[${SpellNames[${Counter}]}].ID} && !${FindItemCount[${SpellNames[${Counter}]}]} ) {
         /for ItemCounter 1 to ${Window[MerchantWnd].Child[MW_ItemList].Items}
            /if (${Window[MerchantWnd].Child[MW_ItemList].List[${ItemCounter},2].Equal[Tome of ${SpellNames[${Counter}]}]} || ${Window[MerchantWnd].Child[MW_ItemList].List[${ItemCounter},2].Equal[Spell: ${SpellNames[${Counter}]}]} || ${Window[MerchantWnd].Child[MW_ItemList].List[${ItemCounter},2].Equal[Song: ${SpellNames[${Counter}]}]}) /varset ItemSlotNumber ${ItemCounter}
         /next ItemCounter
         /if (${ItemSlotNumber}) {
            /echo Buy ${Window[MerchantWnd].Child[MW_ItemList].List[${ItemSlotNumber},2]}? (Shift-Y / Shift-N)
            /notify MerchantWnd MW_ItemList listselect ${ItemSlotNumber}
            :WaitForSpellBuyResponse
            /if (${STB_BuySpellStatus}==2) {
               /delay 1
               /goto :WaitForSpellBuyResponse
            }
            /if (${STB_BuySpellStatus}==1) {
               /notify MerchantWnd MW_ItemList listselect ${ItemSlotNumber}
               /nomodkey /ctrl /notify MerchantWnd MW_Buy_Button leftmouseup
               /delay 2s
            }
         }
      }
   /next Counter
   /echo Finished buying spells.
   /squelch /custombind delete BUYSPELLYES
   /squelch /custombind delete BUYSPELLNO
   /squelch /bind shift+y clear
   /squelch /bind shift+n clear
   /squelch /deletevar STB_BuySpellStatus
/return

Sub Event_Log
   /declare Counter int local
   /mqlog ------------------------ Missing Spells for ${Me.Name} ------------------------
   /for Counter 1 to ${SpellsMissing}
      /if (!${FindItemCount[=${SpellNames[${Counter}]}]}) /mqlog ${Me.Name} is missing level ${SpellLevels[${Counter}]} ${SpellNames[${Counter}]}
   /next Counter
   /mqlog ------------------------ End of Spells for ${Me.Name} -------------------------
   /echo Logging to ${Macro.Name}.log done.
/return

Sub Event_Bazaar
   /if (${Zone.Name.NotEqual[The Bazaar]}) {
      /echo You need to be in The Bazaar to search.
      /return
   }
   /if (${String[${Plugin[MQ2Bzsrch]}].Equal[NULL]}) {
      /echo You need to load the mq2bzsrch plugin to search.
      /return
   }
   /call BazaarSearch
/return

Sub BazaarSearch
/declare Counter int local
/declare ItemCounter int local
/declare CheapestPrice int local
/declare CheapestMerchant string local
/declare FoundSpells bool local 0
/echo Searching the bazaar for missing spells.

/for Counter 1 to ${SpellsMissing}
   /if (!${FindItemCount[${SpellNames[${Counter}]}]}) {
      /varset CheapestPrice 0
     :KeepSearching
     /bzsrch race any class any stat any slot any type scroll price 0 9999999 "${SpellNames[${Counter}]}"
     /delay 3s ${Bazaar.Done}
     /if (!${Bazaar.Done}) /goto :KeepSearching
      /if (${Bazaar.Count}) {
         /for ItemCounter 1 to ${Bazaar.Count}
            /varset FoundSpells 1
            /if (!${CheapestPrice} || ${CheapestPrice}>${Bazaar.Item[${ItemCounter}].Price} && ${Bazaar.Item[${ItemCounter}].Name.Equal[${SpellNames[${Counter}]}]}) {
               /varset CheapestPrice ${Bazaar.Item[${ItemCounter}].Price}
               /varset CheapestMerchant ${Bazaar.Item[${ItemCounter}].Trader.Name}
            }
         /next ItemCounter
         /echo ${SpellNames[${Counter}]} is sold by ${CheapestMerchant} for ${Math.Calc[${CheapestPrice}\1000].Int}p ${Math.Calc[(${CheapestPrice}\100)%10].Int}g ${Math.Calc[(${CheapestPrice}\10)%10].Int}s ${Math.Calc[${CheapestPrice}%10].Int}c.
      }
   }
/next Counter
/echo Bazaar search done. ${If[${FoundSpells},,No matches found.]}
/return


Sub SpellInfo(int SpellNum)
/if (${SpellNum}<1) /return
/declare InBank bool local 0
|${FindItemBankCount[${Spell[${SpellNum}].Name}]}
/declare InBag bool local ${FindItemCount[${Spell[${SpellNum}].Name}]}

| /if (!${InBank} && !${InBag}) {
    /varcalc SpellsMissing ${SpellsMissing}+1
    /varset SpellNames[${SpellsMissing}] ${Spell[${SpellNum}].Name}
    /varset SpellLevels[${SpellsMissing}] ${Spell[${SpellNum}].Level}
    /varset SpellIDs[${SpellsMissing}] ${Spell[${SpellNum}].ID}
| }
/cecho \aw${SpellsMissing}: \at[${SpellNum}] - ${Spell[${SpellNum}]} ${If[${Spell[${SpellNum}].Level}>${Me.Level},\ar(Above level) ,]}${If[${InBag},\ay(In Bag) ,]}${If[${InBank},\ao(In Bank) ,]}\agLevel:\am${Spell[${SpellNum}].Level}  \agType:\am${Spell[${SpellNum}].SpellType}  \agTarget:\am${Spell[${SpellNum}].TargetType}

/return
SCAMerchants.mac

Code: Select all

| SCAMerchants.mac
| Will add Merchants and their zones to the SCAMerchants File. 
| Will add Merchants with their locs, organized by Zone, to the Specified SCAMerchantsList.ini File
| To Start the macro then, go open a merchant window.  The macro will scan the inventory
| and create or populate the ini files.
|
| Updated June 23rd,2012 by nod77
| This macro was modified from SpellVendors.mac.  Original thread can be found here;
| http://www.macroquest2.com/phpBB3/viewtopic.php?p=64085
| Added support for Tomes that give combat abilities.
| Modified the code so that it won't pick up spells that players have sold back to merchants thus,
| resulting in a erroneous merchant listing for a spell. 


#define dly 100 
#define INIFile SCAMerchants.ini 
#define INIListFile SCAMerchantsList.ini 

Sub Main 

/declare c int outer 0 
/declare spellcount int outer 0 
/echo Beginning Spell & Abilities Merchant Inventory Macro
:Main
 /if (${Merchant.Open}) {
   /target LOS ${NearestSpawn[npc merchant].Name}
   /delay 5s

   /for c 1 to 80 
      /if ((${Merchant.Item[${c}].Name.Find[Spell:]} || ${Merchant.Item[${c}].Name.Find[Song:]} || ${Merchant.Item[${c}].Name.Find[Tome of]}) && ) { 
         /if (${Merchant.Item[${c}].MerchQuantity}<0) {
            /cecho \awAdding \at${Merchant.Item[${c}].Spell}  \awMerchant:\am  ${Target.CleanName} \ao(${Zone}) 
            /ini "INIFile" "${Merchant.Item[${c}].Spell.ID}" "${Target.CleanName}" "${Zone}" 
            /varcalc spellcount ${spellcount}+1 
         }
      }
   /next c 

   /if (${spellcount}) { 
      /ini "INIListFile" "${Zone}" "${Target.CleanName}" "(${Int[${Target.X}]},${Int[${Target.Y}]})" 
      /echo (${spellcount}) spells added for ${Target.CleanName} (${Zone}) on ${Time.Date} 
      /mqlog (${spellcount}) spells added for ${Target.CleanName} (${Zone}) 
   } else {
   /echo No Spells or Tomes on ${Target.CleanName}
   }
   /call Closewin 
   /varset spellcount 0
 }
 /goto :Main
/endmacro 

Sub CloseWin
   /echo Inventory done.
   /notify MerchantWnd MW_Done_Button leftmouseup 
   /delay 1 
/return

User avatar
Imperfect
Macro Author
Macro Author
Posts: 319
Joined: Fri Jun 14, 2002 1:52 am

Re: Find missing Combat Abilities, Spells & Songs then Purch

Post by Imperfect » Sat Jul 28, 2012 11:53 pm

Nice work!