• IS THIS SITE UGLY? Click "RG3" at the very bottom-left of this page to change it. To dismiss this notice, click the X --->
Resource icon

GoTrain.Mac - Send your toons to their trainer!

Joined
Jan 10, 2018
Likes
12
RedCents
1,111¢
#1
gotrain.mac
-Requires: MQ2Nav mesh of POK
-Optionally requires scribe.mac if YOU set buySpells True in the code. (default is false) scribe is a level 2 macro not availble to link.

Description:
This macro will send you to your spell vendor or let you choose what class and level to visit. When there it will target and open the vendor
I built this macro to send my horde to their spell vendors.

If a macro like this already exists please don't tell me. I might hang myself. Typing in all the merchant names was a pain in the Arse.
Please test it and enjoy!

Customizable Variables:
Rich (BB code):
    | ----------------------------------------------------------------------------
    | Customizable Variables
    | ----------------------------------------------------------------------------    
    /declare randomDelayedStart int outer ${Math.Rand[300]}
    /declare debugOn bool outer False
    /declare buySpells bool outer False
Usage: (only works in POK)
/mac gotrain - this will detect your level and class and send you running.
or
/mac gotrain 10 cleric - This was mainly for testing, but can be useful if you want to buy someone else spells etc.
/bcaa //mac gotrain - Send everyone in EQBC to their trainer. Could get you suspended. Not sure. I do it a lot though :D


Updates:
v1.6 - No functionality changed. Added ingorable first line in main. Changed some wording.
v1.5 - Changed Parameter order to "/mac gotrain LEVEL CLASS", now also accepts 1 parameter LEVEL which will override your level so you can buy lower spells. now you can tell your bots to train at each trainer with "/bcaa //mac gotrain 1" "/bcaa //mac gotrain 26" etc...
v1.4 - Added variable randomDelayedStart (default: 30s) and randomized the trainer location by 5 on x and y axis
v1.3 - Added variable buySpells (default: false). Set this to true if you want it to run /mac scribe at the end
v1.2 - Fixed some old variables still left in code causing bad debug data
v1.1 - Fixed SK and RNG being reversed. Added /nav reload at start.
v1.0 - should work for ALL spell vendors and some melee tombs.

Rich (BB code):
| gotrain.mac by Rogue601  v1.6
| 
| Simple macro to send your team to the trainers
| Requires MQ2Nav and Mesh
|    

| TODO - Add stuck logic. Nav gets stuck sometimes. 


| -------------------------------------------------------------------------------------
| Sub Main
| -------------------------------------------------------------------------------------
Sub Main
    /declare thislineisignored
    | COMMENT : Check for POK zone or exit.
    /if (!${Zone.ShortName.Equal[PoKnowledge]}) {
        /echo "This macro only works in the Plane of Knowledge"
        /endmac    
    }

    | ----------------------------------------------------------------------------
    | Customizable Variables
    | ----------------------------------------------------------------------------    
    /declare randomDelayedStart int outer ${Math.Rand[300]}
    /declare debugOn bool outer False
    /declare buySpells bool outer False

    | COMMENT : Declare Variables
    /declare myLevel int outer ${Param0}
    /declare myClass string outer ${Param1.Lower}
    /declare myTrainerID int outer 0
    /declare myTrainerName string outer 0
    /declare myTrainerX float outer 0
    /declare myTrainerY float outer 0
    /declare myTrainerZ float outer 0


    | ----------------------------------------------------------------------------
    | Require Parameters - Param1 = Level, Param2 = Class
    | ----------------------------------------------------------------------------    
    /if (${Macro.Params}==0) {
        
        /varset myLevel ${Me.Level}
        /varset myClass ${Me.Class}
        /varset myClass ${myClass.Lower}
        /echo Optional Usage: /mac gotrain level    
        /echo Optional Usage: /mac gotrain level class        
        /echo Example : /mac gotrain 10 cleric
        /echo If no Parameters are given it will use yours
        /echo
        /echo You are a Level: ${myLevel} ${myClass}
        
    } else /if (${Macro.Params}==1) {
        
        /varset myClass ${Me.Class}
        /echo Overriding your level and using ${myLevel} instead!
            
    
    } else /if (${Macro.Params}==2) {
    
        /echo Overriding your level and class and using Level: ${myLevel} Class: ${myClass}
        
    } else {
        
        /echo GOTRAIN ERROR!
        /echo Too many parameters given?
        /echo Example : /mac gotrain 10
        /echo Example : /mac gotrain 10 cleric
        /endmac
        
    }
    
    
    /if (${debugOn}) /echo DEBUG: Main: Starting Mainloop    
    /nav reload
    
    | ----------------------------------------------------------------------------
    | RandonDelayStart - Lets wait here a random time to prevent a swarm
    | ----------------------------------------------------------------------------    
    /if (${randomDelayedStart} > 0) /echo randomStartDelay is active. Waiting ${randomDelayedStart} 
    /delay ${randomDelayedStart}
    
    :mainloop

    
    | ----------------------------------------------------------------------------
    | SetTrainer - If I don't have a trainer set, then find and set it.
    | ----------------------------------------------------------------------------    
    /if (${myTrainerID}==0) {
        /if (${debugOn}) /echo DEBUG: Mainloop: Call SetTrainer
        /call SetTrainer


    | ----------------------------------------------------------------------------
    | navToTrainer - I have a trainer now go there
    | ----------------------------------------------------------------------------    
    } else /if (${Spawn[${myTrainerID}].Distance} > 30) {
        /if (${debugOn}) /echo DEBUG: Mainloop: Call NavToTrainer
        /call NavToTrainer
        
        
    | ----------------------------------------------------------------------------
    | BeginTraining - We have a trainer and we are close to them. What now?
    | ----------------------------------------------------------------------------            
    } else {
        /if (${debugOn}) /echo DEBUG: Mainloop: Call BeginTraining
        /call BeginTraining
    }



    
     
    /delay 10
    /goto :mainloop
    /if (${debugOn}) /echo DEBUG: Main: Ending Mainloop
    
    :mainend
    
/return 


        
| -------------------------------------------------------------------------------------
| Sub SetTrainer - Define myTrainer based on class and level
| -------------------------------------------------------------------------------------
Sub SetTrainer
    
    /if (${myClass.Equal["bard"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Minstrel Franchot"
        } else /if (${myLevel} > 80) {
            /varset myTrainerName "Minstrel Franchot"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Minstrel Cirsaelle"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Minstrel Silnon"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Minstrel Gwiar"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Minstrel Joet"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Minstrel Eoweril"
        }
    } else /if (${myClass.Equal["beastlord"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Primalist Beal"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Primalist Uliag"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Primalist Loerith"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Primalist Nydalith"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Primalist Worenon"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Primalist Saosith"
        }
    } else /if (${myClass.Equal["berserker"]}) {
        /varset myTrainerName "Kurlond Axebringer"
    } else /if (${myClass.Equal["cleric"]}) {    
        /if (${myLevel} > 80) {
            /varset myTrainerName "Vicar Feyl"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Vicar Glaunn"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Vicar Diarin"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Vicar Delin"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Vicar Thiran"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Vicar Ceraen"
        }
    } else /if (${myClass.Equal["druid"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Wanderer Abel"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Wanderer Thermon"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Wanderer Kedrisan"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Wanderer Frardok"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Wanderer Qenda"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Wanderer Astobin"
        }
    } else /if (${myClass.Equal["enchanter"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Illusionist Phili"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Illusionist Warek"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Illusionist Acored"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Illusionist Lobaen"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Illusionist Sevat"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Illusionist Jerup"
        }
    } else /if (${myClass.Equal["magician"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Elementalist Bartbur"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Elementalist Onaec"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Elementalist Siewth"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Elementalist Padan"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Elementalist Kaeob"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Elementalist Somat"
        }
    } else /if (${myClass.Lower.Equal["monk"]}) {
         /varset myTrainerName "Beorobin Amondson"
    } else /if (${myClass.Equal["necromancer"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Heretic Lartman"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Heretic Niraf"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Heretic Ceikon"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Heretic Edalith"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Heretic Elirev"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Heretic Drahur"
        }
    } else /if (${myClass.Equal["warrior"]}) {
         /varset myTrainerName "Heldin Swordbreaker"
    } else /if (${myClass.Equal["paladin"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Cavalier Tummings"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Cavalier Ethigom"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Cavalier Cerakor"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Cavalier Preradus"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Cavalier Aodus"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Cavalier Waut"
        }
    } else /if (${myClass.Equal["ranger"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Pathfinder Sweeneph"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Pathfinder Arelat"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Pathfinder Naend"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Pathfinder Thoajin"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Pathfinder Vaered"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Pathfinder Viliken"
        }
    } else /if (${myClass.Equal["rogue"]}) {        
         /echo Sorry rogue isn't setup yet : Exiting 
        /endmac
    } else /if (${myClass.Equal["shadow knight"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Reaver Enold"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Reaver Praden"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Reaver Muron"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Reaver Thirlan"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Reaver Uledrith"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Reaver Nydlil"
        }
    } else /if (${myClass.Equal["shaman"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Mystic Voskovek"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Mystic Somas"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Mystic Pikor"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Mystic Ryrin"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Mystic Goharkor"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Mystic Abomin"
        }
    } else /if (${myClass.Equal["wizard"]}) {
        /if (${myLevel} > 80) {
            /varset myTrainerName "Channeler Larkord"
        } else /if (${myLevel} > 70) {
            /varset myTrainerName "Channeler Keatrem"
        } else /if (${myLevel} > 60) {
            /varset myTrainerName "Channeler Alyrianne"
        } else /if (${myLevel} > 50) {
            /varset myTrainerName "Channeler Cerakoth"
        } else /if (${myLevel} > 25) {
            /varset myTrainerName "Channeler Lariland"
        } else /if (${myLevel} > 0) {
            /varset myTrainerName "Channeler Olaemos"
        }
    } else {
        /echo Unrecognized Class Name: ${myClass} : Exiting 
        /endmac
    }
     
     /varset myTrainerID ${NearestSpawn[npc targetable radius 10000 "${myTrainerName}"].ID}
    /if (${debugOn}) /echo DEBUG: SetTrainer: ${myTrainerName} ID:${myTrainerID}
    /echo ${myLevel} ${myClass} Trainer is ${myTrainerName} ID:${myTrainerID}
    /varset myTrainerX ${Math.Calc[${Spawn[${myTrainerID}].X}+${Math.Rand[5]}]}
    /varset myTrainerY ${Math.Calc[${Spawn[${myTrainerID}].Y}+${Math.Rand[5]}]}
    /varset myTrainerZ ${Spawn[${myTrainerID}].Z}
     
/return

| -------------------------------------------------------------------------------------
| Sub NavToTrainer - Navigate using MQ2Nav 
| -------------------------------------------------------------------------------------
Sub NavToTrainer
    /if (${debugOn}) /echo DEBUG: NavToTrainer: Tracking ${myTrainerName} " ID: ${myTrainerID} Distance: ${Spawn[${myTrainerID}].Distance}
    /setchattitle Heading towards ${myTrainerName}
    /squelch /nav locxyz ${myTrainerX} ${myTrainerY} ${myTrainerZ}
    
/return    


| -------------------------------------------------------------------------------------
| Sub BeginTraining - At the Trainer setup position and open merchant
| -------------------------------------------------------------------------------------
Sub BeginTraining

    /if (${debugOn}) /echo DEBUG: BeginTraining: Start
    /setchattitle MQ2
    /target id ${myTrainerID}
    /if (${Target.ID} && ${Target.Type.Equal[NPC]}) {
        /delay 10
        /stick id ${myTrainerID} 15 moveback 
        /delay 10
        /stick off
        /delay 10
        /nomodkey /click right target
        
        /if (${buySpells}) {
            /if (${debugOn}) /echo DEBUG: BeginTraining: Buying Spells with Scribe.mac
            /delay 30
            /mac scribe
        }
        /endmac
    }
    /if (${debugOn}) /echo DEBUG: BeginTraining: END

    
/return    


| -------------------------------------------------------------------------------------
| OnExit - Things it does when you type /endmac
| -------------------------------------------------------------------------------------
:OnExit
    /setchattitle MQ2
    /squelch /nav stop
    /end
To fix the VOA error in scribe.mac add the "/declare thislineignored" in Sub Main
Rich (BB code):
Sub Main
    /declare thislineisignored
    /declare HasVoA int outer 0
 
Last edited:
Joined
Dec 8, 2014
Likes
23
RedCents
1,350¢
#3
I do not know if I am violating some coder etiquette but....

If you place:

/mac scribe

just before the third or fourth from the last line:

/endmac

it will chain to that marvelous macro and buy and memorize spells to your specifications.

I am probably going to coder prison for even bringing this up.

I will try to,
Playbetter
 
Joined
Nov 7, 2005
Likes
66
RedCents
601¢
#4
playbetter, I've run into weird scoping bugs when starting another macro from a macro. Some globals start breaking and some commands just stop working that were working fine when started normally.

Maybe eqmule can explain why that happens and how to properly start a macro from a macro. ;)

Even a simple macro that only does
Rich (BB code):
/mac secondmacro
will trigger these bugs.

One workaround has been to make a regular EQ macro /mac foo and assign it to key and then
Rich (BB code):
/keypress thatkey
triggers 2nd macro and does not have these strange bugs.

Alternative has been to simply incorporate 2nd macro as a callable function.
 
Joined
Jan 10, 2018
Likes
12
RedCents
1,111¢
#5
I do not know if I am violating some coder etiquette but....

If you place:

/mac scribe

just before the third or fourth from the last line:

/endmac

it will chain to that marvelous macro and buy and memorize spells to your specifications.

I am probably going to coder prison for even bringing this up.

I will try to,
Playbetter
Yeah that was the plan all along. It's in the TODO section of the code.
maybe /mac gotrain scribe

I'll add the code in and have it remarked out. so people can remove the remark.

I added a buySpells variable. Just set it to true and it will /call scribe. I've tested it and now my wizard bot is broke again :D
 
Joined
Feb 22, 2014
Likes
61
RedCents
923¢
#6
This is AMAZING! Great work....

Now, is there a mac that will ONLY buy teleport spells for wiz and druid?
 
Joined
Dec 29, 2017
Likes
982
RedCents
4,200¢
#7
playbetter, I've run into weird scoping bugs when starting another macro from a macro. Some globals start breaking and some commands just stop working that were working fine when started normally.

Maybe eqmule can explain why that happens and how to properly start a macro from a macro. ;)

Even a simple macro that only does
Rich (BB code):
/mac secondmacro
will trigger these bugs.

One workaround has been to make a regular EQ macro /mac foo and assign it to key and then
Rich (BB code):
/keypress thatkey
triggers 2nd macro and does not have these strange bugs.

Alternative has been to simply incorporate 2nd macro as a callable function.

Calling a macro from another macro causes it to skip the first line of the following macro. So whatever the first line of code is in Sub Main will be skipped. An alteration to scribe.mac would be needed adding a dummy line of code. IE: /delay 1
 
Joined
Nov 7, 2005
Likes
66
RedCents
601¢
#8
Calling a macro from another macro causes it to skip the first line of the following macro. So whatever the first line of code is in Sub Main will be skipped. An alteration to scribe.mac would be needed adding a dummy line of code. IE: /delay 1
Great find!

You saved me from so much aggravation. I had an important
Rich (BB code):
 /declare Var
in the first line of code in Sub Main. No wonder things were breaking. :)
 

rhb

Active member
Joined
Jun 2, 2016
Likes
38
RedCents
163¢
#9
I read this Mac title and thought something much more devious
 
Joined
Jun 30, 2013
Likes
38
RedCents
4,710¢
#15
I like it because I can run it on all toons and they don't all rush out at the same time. Plus it runs to vendor, buys and mems spells without added input.
 

Redbot

lvl 69 Rouge
Moderator
Joined
Oct 15, 2004
Likes
713
RedCents
41,010¢
#16
hrm I don't think you need any added input with pokscribe, not last I checked.
 

Sicprofundus

#Can'tStop #Won'tStop
Moderator
Joined
May 5, 2016
Likes
1,114
RedCents
5,236¢
#17
hrm I don't think you need any added input with pokscribe, not last I checked.
nope, I plan on doing a ton of stuff with it, but currently it just runs to your own class persons and grabs all your spells/tomes.
 
Joined
Mar 24, 2018
Likes
117
RedCents
834¢
#18
This mac would have saved me many hours playing on PEQ! Running 18 characters to their trainers was such a hassle!
 
Top