----------------------------------------
INTRODUCTION
A macro is a user-defined automated task, simply put. They've been around forever. I remember
using them 9-10 years ago in my BBS days with the Procommm Plus terminal dialer. Somewhere along
the lines, the term was stupified, most likely by the Microsoft empire, and what was known as the
Macro became the Hotkey. Hotkeys in EverQuest are limited macros that can only do certain things.
What our beloved Developers have done for us was create a program called MacroQuest, in which we
can use to do things that Sony doesn't wish us to do, automated style.
We can use the functions in MacroQuest by making EverQuest hotkeys to call them for us, but what's
the fun in that? We can write scripts that utilize many functions at the exact same time for us.
Enter, the wonderful world of Macro Scripting.
It may sound intimidating at first but generally, basic scripting is easy and painless. Since
MacroQuest script is an interpreter language, we don't even have to compile them. It's easier
than BASIC. There are a few things you need to know, though.
THE BASIC STRUCTURE OF SCRIPTS
The basic structure of scripts are its routines. A routine is exactly what it sounds like.
It's a sequence of events. Think of yourself as a code conductor. You place all of the
functions in their places, you tell them what to do, and you sit back and enjoy the show. Each
routine is labeled as a SUB ROUTINE, including the Main one. That's not nearly as confusing
as it may seem at first. It's just a label, really. A sub routine, in the context of a symphony,
would be the next sequence of events that you, the code conductor, would direct.
Each script starts with a MAIN Routine. This is the routine where your first functions will
be placed in every script. It looks like this:
Code: Select all
Sub Main
MAIN FUNCTION(S) GO HERE
/return
various functions call (with /call) different sub routines, which can be named however you want
them to be named. Your added sub routines will look like this:
Code: Select all
Sub SomeSubRoutineName
SEPERATE FUNCTION(S) GO HERE
/return
/return basically tells the script to return to the routine in which it was called from. All
sub routines will end with /return. It's an easier way of saying, "Ok, I'm done with this crap, I'll
move back to the original routine now."
There you have it. You now know the wonderfully simple structure of the script's outer shell. Now
we'll go into filling those routines in with useful stuff.
VARIABLES
Variables are also exactly what they sound like. There is one confusing part though; that being
that there are two kinds of variables. The variable you will most likely find the most useful
is the one that is unchangeable and set in the programming code of MacroQuest, which begin with a
dollar sign ($). The second type of variable is a user-defined variable, which begins with an at (@)
symbol.
A listing of MacroQuest variables can be found in the MacroQuest manual at http://macroquest2.com/?p=manual.
(If you're just starting out in scripting, you should never close the manual window because it really
is a life saver.)
An example you can use to test a MacroQuest variable is to go inside of EQ with MacroQuest open
and use /echo followed by some MacroQuest variables. Like this:
Code: Select all
/echo $target(name)
must first /DECLARE them to be variables so MacroQuest knows to look for them when you try to use
them. This is done in the MAIN routine. In most cases, and for the sake of simplicity, in this case,
we'll /declare them as global variables, which means any sub routine may use them. Here is a sample:
Code: Select all
Sub Main
/declare MYVARIABLE global
/declare MYVARIABLE2 global
/declare MYVARIABLE3 global
/return
command. /varset allows us to define these variables any way we wish, and also flags them with
the ever-important at (@) symbol so that we may use them in our script. Also remember that when
you try to set a variable with multiple words, you'll want to enclose the phrase in quotation marks.
This way MacroQuest knows that the variable string is indeed a phrase of more than one word.
For example:
Code: Select all
Sub Main
/declare MYVARIABLE global
/declare MYVARIABLE2 global
/declare MYVARIABLE3 global
[b] /varset MYVARIABLE "This scripting stuff is easy as pie."
/varset MYVARIABLE2 "Yep, it sure is."
/varset MYVARIABLE3 123456[/b]
/return
you're catching on, you'll know that's because it's a single word phrase. MacroQuest will take it
as it is.
Now that we've declared and set our variables, we can use other commands to call those variables
from the script. For the sake of of the retarded, such as myself, we'll make it as easy to
understand as possible and once again go back to our old friend, the /echo command. We'll
place the /echo in the script its self this time instead of using it manually from EverQuest, like
so:
Code: Select all
Sub Main
/declare MYVARIABLE global
/declare MYVARIABLE2 global
/declare MYVARIABLE3 global
/varset MYVARIABLE "This scripting stuff is easy as pie."
/varset MYVARIABLE2 "Yep, it sure is."
/varset MYVARIABLE3 123456
[b] /echo @MYVARIABLE
/echo @MYVARIABLE2
/echo @MYVARIABLE3[/b]
/return
Once you've got it saved, go into EverQuest with MacroQuest open, and type /macro testecho.mac
You will see something that looks like this:
[MacroQuest] This scripting stuff is easy as pie.
[MacroQuest] Yep, it sure is.
[MacroQuest] 123456
With that, I congradulate you on your first simple script.
IF this tutorial sucks tell me or ELSE
Now that you've got your first simple script, we'll get into some more advanced stuff. All in all,
it's not really all that advanced but it can and will give you a headache at some point. That
headache is called the /if command. Again, it's exactly what it sounds like. The /if command
is the basic artificial intelligence of your script. IF something occurs, do something, basically.
Both the action and reaction are defined by you in your script. For example:
Code: Select all
/if $target(name)==elretardo /echo This guy is retarded.
guy is retarded.
You probably noticed the == immediately. This is also not hard to understand. It means equals. So
/If your target equals elretardo blah blah, you get the picture. You can use the equals sign or some
of its counterparts like the greater than symbol, less than symbol, and so on. All of them can
be found in the manual, which you should still
have open.
Now, /IF your target is elretardo, you will go through the schpiel. However, because elretardo isn't
my actual EverQuest name, chances are that your target will be something different. If that is the
case, then our /IF needs to have a different action to take should the target be different. This is
called an ELSE.
An ELSE is usually defined by the next line in your routine automatically. /IF your target isn't
elretardo, MacroQuest will know to go to the next line and do its preprogrammed thing. Sometimes,
though this may be a viable option, you may need to define an ELSE that is exclusive to the /IF.
This is where we get into some more structure and are introduced to brackets ({}). Brackets are
used within sub routines to define a smaller sub routine. This is confusing, I know. But stick with
me. An opening bracket ({) will tell MacroQuest that a new routine is about to begin. Every opening
bracket naturally has a closing bracket (}) to be placed at the end of the routine. When using an ELSE,
you will have two sets of opening and closing brackets. One set for the /IF, and the other for the
ELSE.
I know you're confused as hell now so here's an example:
Code: Select all
Sub Main
/if $target(name)==elretardo {
/echo This guy is retarded.
/rude
} else {
/echo This guy is not retarded.
/bow
}
/return
This guy is retarded. Otherwise, I will bow to him and say to myself this guy is not retarded. It's
pretty simple once you get the hang of it, really.
I bet you're wondering if you can use variables in place of elretardo in the /IF statement. You can.
It is also as simple as it sounds. Let's say you want to use MYVARIABLE3 which we've defined as
123456. You would do it like this:
Code: Select all
Sub Main
/declare MYVARIABLE global
/declare MYVARIABLE2 global
/declare MYVARIABLE3 global
/varset MYVARIABLE "This scripting stuff is easy as pie."
/varset MYVARIABLE2 "Yep, it sure is."
/varset MYVARIABLE3 123456
/if $target(name)==[b]@MYVARIABLE3[/b] {
/echo This guy is retarded.
/rude
} else {
/echo This guy is not retarded.
/bow
}
/return
numbers in your name. Prepare to do lots of bowing.
Not only can you use user-defined variables, you can use the MacroQuest variables as well. Since
I think you've got a grasp of it, I won't insult your intelligence and add another example.
Congradulations on your first script using an /IF and an ELSE.
Calling Sub Routines, Loops, and Commands commonly used in them
Now that we've got the basics of the Main routine down, I think it's time we venture into the much
chartered waters of the Sub routine. As stated before, sub routines are just routines that you
define to do a specific set of functions. They're most commonly used for loops. A loop is a set
of functions that you want to repeat. Let's say you want your script to keep checking for a spawn.
You'd need a loop to do that. To make a loop, you need to define a new sub routine. We'll name
it Sub Loop for the sheer dummy-friendly nature of it. Example:
Code: Select all
Sub Loop
/return
to the /goto command, and its counterpart, the colon (:). No, not as in I get cancer, I kill jack.
As in the two little dots stacked on top of eachother. The colon (:) is used to define the beginning
of the loop. A bookmark, if you will. The very useful /goto command is used to tell the script
to begin the loop, or go to the bookmark. Example:
Code: Select all
Sub Main
/call Loop
/return
Sub Loop
/goto :loopstart
:loopstart
/target Stormfeather
/goto :loopstart
/return
it out already, I'll explain. The first /goto command is issued to begin the loop and the second /goto
command is issued to sustain the loop. So the first says START THE LOOP, and goes to the :loopstart
bookmark. Then it attempts to target Stormfeather and issues another /goto command to retry the /target.
You'll also notice we've used the /call command for the first time. This one is also not cleverly
named. It's like calling someone on a phone but instead of their phone number, you enter the Sub Routine
you wish to call. No area code, no number. Just pure unadultered Sub Routine goodness. So, you call
the Loop sub routine and it immediately picks up the action and begins to loop the targeting process.
If you've already saved this script and used it, you'll know it causes a hell of a lot of spam. You can
easily twart this problem with a very useful command called /delay. Again, not hard to figure out
what it does. You can have the script delay it's next command in increments of either seconds (s) or minutes (m).
The manual says that without a S or a M to define whether you want seconds or minutes, MacroQuest will automatically
assume you mean 10ths of a second. Don't listen to it. It defaults to seconds.
So now that we want to kill the spam of the targeting process, I'll throw up another example:
Code: Select all
Sub Main
/call Loop
/return
Sub Loop
/goto :loopstart
:loopstart
/delay 1s
/target Stormfeather
/goto :loopstart
/return
can save so many headaches. If only I had that in real life to use in conjunction with my tendancies
to procrastinate.
Code: Select all
Sub Main
/delay 120m
/say Yes, dear.
/return
Using what you've learned to make an adaptable spawn checker
Now you've got all the basic knowledge to make a simple spawn checker script but can you make it
adaptable using user-defined variables? I think so. If not, I'll do it for you because this tutorial
would be lame if I didn't add examples.
Here it is!
Code: Select all
Sub Main
|**
Spawn Checker v1.0 by [Your Name Here]
It's Shake n Script and elretardo helped!
**|
| Declare and set Spawn Name to Stormfeather
/declare SpawnName global
/varset SpawnName Stormfeather
| Call Sub CheckIt
/call CheckIt
/return
Sub CheckIt
| Start the first loop..
/goto :isitup
:isitup
| Check if Stormfeather is up
/if $target(name)==@SpawnName {
/echo @SpawnName is up!
| Do a dance of joy since the bastard never spawns and you're the luckiest man/woman alive.
/dance
| End the spamfest.
/endmacro
} else {
| Go to the actual spawn checking loop (Again?).
/goto :checkloop
}
:checkloop
/delay 1s
/target @SpawnName
| Let's go back and see if he's spawned yet..
/goto :isitup
/return
under one sub routine!? It's because I'm a curveball throwin mofo, my friend. First off, the crap
at the top there that begins with |** and ends with **| is used to define a multi-line comment.
It's basically a bracket that MacroQuest completely ignores so you can add various comments throughout
your code to usually give yourself recognition or to point out certain pieces of code to yourself.
You can also use a pipe (|) if you only want to comment on a single line. Just think of them as
post-it notes.
A new command has also been introduced which is /endmacro. You can issue this command from a script
to end your macro automatically after the objective of the script is met or you can use it while you're
testing a script if something isn't right and you want to start it again after making some changes.
Two loops are used in the CheckIt sub routine. One is an /IF ELSE loop that will check to see if you've
got Stormfeather targeted. If you do, it will echo that he's up, do a dance of joy, and end the macro.
If you don't, the script will go to the second loop which is the loop we used in the previous example
to actually check the spawn.
We've also got a brand new variable in there which can be set at the will of the person who uses
the script. If you noticed, the /IF command issued uses it as well. This is how you make adapatable
scripts.
You've just completed my tutorial on Macro Scripting for Dummies. If you listened, you're on your
way to making scripts that you can post to the Macro Depot so myself and those
like me can rape your intellectual work to either make it better or make it annoyingly worse. If you
didn't listen, I guess you'll need to reread the tutorial and until you listen, just use us scripting
folk for our sweet sweet macro love.
Oh yeah -- If I haven't said it enough, RTFM.
Postscript Notes
From DekeFentle, FlashG, and Macrofiend--
You can use ~~ in place of == if you're unsure of the exact string in which you want to compare, or if the string changes within EverQuest. Example:
Code: Select all
/if $target(name)~~"tardo" /echo I think it's that moron, elretardo.
Quotation marks should be used in any multi-word phrase, be it a /varset or an /if.
Also, if you're trying to compare a number, you'll want to use the n flag before /if to tell the script that you want to compare a number instead of a phrase. Example:
Code: Select all
/if n $target(hp,pct)==100 /echo I just used a number in my /if statement.
From Mckorr (Developer)--
It is a good practice to end your main sub routine with /endmacro instead of /return. The reason for this is that we should tell our script that even though it's the first listed routine, it is also the last. Although /return does work in all sub routines, /endmacro is the proper way to end your Main sub routine from the standpoint of the experienced coder/scripter. Example:
Code: Select all
Sub Main
/dance
/bow
/dance
/echo Doing the Roboto dance..
/endmacro




