TRIBES Script Programming PDF
TRIBES Script Programming PDF
I. Foreword
II. Introduction
- The Tools
- The Files
- The IDE
- The Language
- First Modification
III. Variables and Operators
- General Variable Information
- Numerical Variables
- Boolean Variables
- String Variables
- Object, Player, and Client Variables
IV. Decision and Looping Statements
- If-Else
- While Loop
- For Loop
V. Functions and Datablocks
- Functions
- Datablocks
VI. Arrays
- Arrays / Subscripted Variables
VII. Sorting and Searching
- Linear Search
- Numeric Sort
- Alphabetical / Lexicographic Sort
VIII. Bitwise
- Theory
- Bitwise Operators
- Uses for Bitwise
IX. Last Words
X. Appendices
- Function Reference
2
3
4
1.1 Intro
TRIBES Script has been shrouded in mystery for a while
now; the general public knows it exists, however only the
elite few are extremely good at it. I’ve written this book
on basically every subject that will help you become one of
those elite few. I assume that you’ve got a basic working
knowledge of a PC and the Windows operating system, you’ve
at least played TRIBES before, and you have access to the
internet. I use Windows XP, but any version beyond Windows
98 should work fine.
If you want to fiddle with server scripts or make the
next ‘Annihilation’, this book is for you. This is the
first edition, and there will be revisions if I find I made
a mistake somewhere. If you find any, email me at:
‘[email protected]’.
5
6
2.1 The Tools
I can help you with the first three, but the others you
have to work on by
yourself. To get a
VOL Extraction
program, you can
search for several
different ones, such
as Volumer or WinVOL.
I personally use
WinVOL for its simple
interface. When you
open WinVOL you’ll
first be presented
with a splash screen
giving credit where it is rightfully deserved. Once at the
next screen you’ll see something similar to the picture to
the right. There are three different boxes here, from left
to right: The Browser Box, The Directory Box, and the
Volume Contents Box. The Browser Box allows you to browse
trough your drives and folders to wherever you’d like to be.
The Directory Box shows all VOL files within the current
directory, and the
Volume Contents well…
displays the current
volume’s contents. You
can then select the
files you’d like to
extract and secondary-
click on them. Voila,
instant extraction!
You’ll also need a VOL
Complication program to
make your own VOLs
however. There are many
out there, but I use
VisualVT myself. On my
7
bigger projects I use a batch file and the original VT
program, but for
learning purposes
VisualVT should
work just fine. If
you care to have
your own batch file,
it’s in the ‘Code
Snippets’ section.
This is a rather
self-explanatory
interface, so I
won’t go into
detail on how to
use it. Well,
that’s 2 out of 5!
Let’s go on. Next,
you’ll need a Text
Editor of some sort. Now, Notepad will work just fine, but
you’ll find it will grind on your nerves after a while. I
personally recommend Tribal IDE. It was originally make for
Tribes 2, but it works just fine for TRIBES. The syntax
coloring will give you a great advantage over Notepad
because you’ll be able to distinguish similar parts of code
from one another. The above picture gives you a preview of
what it looks like. Well, that’s all I can help you with.
The last two are out of my hands. I recommend a self-help
book or some thing similar. Once you have all the tools,
you are ready to begin modding.
Once you have all the tools you need, and are familiar
with them, we can proceed. To start, CS files are Script
files. They are the most common of file types and will hold
all the code that you create. VOL files are basically like
a container for the CS files: They hold everything together,
instead of having lots of CS files floating around. To
start modifying the ‘base’ mod, we’re going to need to gain
access to the CS files from the ‘scripts.vol’ file. The
original script files should never be replaced, unless you
have a recent backup. You need to open the VOL extractor
you downloaded, and select the ‘scripts.vol’ file from your
TRIBES directory. Don’t see it? Well, first let’s find your
TRIBES directory. If you have a shortcut on your desktop or
start menu to TRIBES, right-click on it and look at the
target text box on the ‘Shortcut’ tab. That’s your TRIBES
8
directory. It will look something like this: ‘X:\Program
Files\Dynamix\TRIBES\’. The ‘scripts.vol’ is in the ‘base’
folder. Another alternative is to use Windows’ Search
feature. You need to now make a folder within the TRIBES
directory with your Mod Name. For learning purposes, I’m
going to use the folder name ‘test’; I recommend you do the
same. Now, go back to your extractor. Open up the
‘scripts.vol’ you copied with it, and extract everything
from the file to your newly created folder. Once the VOL
file is extracted, rename it to ‘scripts.vol.bak’. This way,
you can always restore from a messed-up mod or TRIBES. If
you leave the file as-is, any changes will be overridden.
Congratulations, you have a mod! Of course, it’s nothing
special, but we’re going to change that, right? Next up is
to create a shortcut to your mod. First, copy the existing
one from your start menu or desktop onto the desktop (Or
create a new one, depending on your circumstances). Rename
this to something along the lines of ‘TRIBES test mod’ or
whatever your mod name might be. Right-click on this
shortcut and go to the ‘Shortcut’ tab. We are going to
change the ‘target’ textbox. Because we don’t want to run
‘base’ we want to run our mod, ‘test’, we need to change
this from something like ‘X:\Program
Files\Dynamix\TRIBES\Tribes.exe’ to ‘X:\Program
Files\Dynamix\TRIBES\Tribes.exe –mod test’; Where ‘test’ is,
of course, your mod name. If you were to run TRIBES from
this shortcut, your server type would be the mod name
‘test’ with ‘base’ at the end, and it would run your mod
‘test’. If you didn’t do it correctly, you might get a
‘Game::EndFrame: Unknown command.’ Error.
9
2.4 The Language
function Sample::Function(%msg)
{
echo(%msg);
}
10
$spawnBuyList[0] = LightArmor;
$spawnBuyList[1] = Blaster;
$spawnBuyList[2] = Chaingun;
$spawnBuyList[3] = Disclauncher;
$spawnBuyList[4] = RepairKit;
$spawnBuyList[5] = "";
$spawnBuyList[1] = PlasmaGun;
Did you do it right? If not, don’t fret, just fix it. Once
you have that done. Save the modified file and run TRIBES
from your mod shortcut. You should spawn with a Plasma Gun
instead of a Blaster. Cool, eh? Well, it’s not exactly a
remote mine or Particle Beam Cannon, but it is a start.
11
12
3.1 General Variable Information
Variables are a basic concept of
Algebraic Mathematics, and Computer
Science. You can think of variables as
a container that can hold different
things. This is illustrated in the
image. As you can see, the variable has
an identifier and a value, or constant.
In TRIBES Script, a variable can be
anything, and changes according to what
it’s storing. This is different from
most languages where variables can only
be certain types, such as numbers or a
string of letters. Variables, in TRIBES Script, look like
this:
%variableName
%numberVariable = 1234;
%stringVariable = “Hello”;
%numberVariable = 1234;
%stringVariable = %numberVariable;
$globaVariable = 0;
13
The scope of a variable depends on when TRIBES deletes it.
A local variable is only available for use in the function
it was created in, whereas a global variable, or global,
can be used anywhere.
%x = 10;
%y = 10;
Echo(%x + %y);
%x = 10;
%y = 10;
%z = %x + %y * %y;
14
Modifiers’. These are parentheses, ‘()’. An example would
be:
%x = 10;
%y = 10;
%z = (%x + %y) * %y;
Z will equal 200, not 110. These operators above are called
‘Binary Operators’, Binary means that it takes two ‘things’,
or operands for it to work, whether they are constants or
variables. There is another type of operators called ‘Unary
Operators’. These are Unary because they only take one
operand to work. Here’s a list of some basic ones, assume X
is equal to 10:
15
AND A B Result
TRUE TRUE TRUE
TRUE FALSE FALSE
FALSE TRUE FALSE
FALSE FALSE FALSE
OR A B Result
TRUE TRUE TRUE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE
XOR A B Result
TRUE TRUE FALSE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE
NOT A Result
TRUE FALSE
FALSE TRUE
%x = “Hello”;
%x1 = “con”;
%x2 = “catenate”;
16
%x3 = %x1 @ %x2;
%clientId.isAdmin = true;
17
datablocks, you’ll see that they also have property
variables.
18
19
4.1 If-Else
Do you remember the boolean variable type earlier in
the book? Well, you’ll be using them all the time when you
use statements that alter program flow. ‘What’s program
flow?’ You may be asking. Well, programs ‘flow’ or execute
top-to-bottom, unless something alters its set course. The
simplest of the statements to alter program flow is the If-
Else statement. This is used like this:
if(%bool)
{
//Do Some Stuff…
}
else
{
//Do Other Stuff…
}
if(%bool)
{
//Do Some Stuff…
}
else if(!%bool)
{
//Do Some Stuff…
}
This is exactly the same thing as the first code block. You
can even omit the else altogether. Example:
if(%bool)
{
//Do Some Stuff…
}
20
if(%bool)
{
//Do Some Stuff..
} else {}
if(%bool)
//Do One Thing…
Or…
if(%bool)
//Do One Thing…
else
//Do Another Thing…
Ok, now that you know the syntax, let’s get into some more
difficult things. So far, you’ve heard the term expression
used quite a bit. The example was %bool, which is a really
easy expression, it depends entirely upon the value
of %bool. So, the expression evaluate to true if %bool is
equal to true and vice-versa. It’s not always that clear-
cut. You can use several conditional operators to construct
an expression. Here is a list, assume %x = 10 and %y = 20:
%x == %y returns false
%x == %z returns true
!(%x == %y) returns true
(%x != %y) returns true
(%x > %y) returns false
21
Here are some more complicated ones:
Let’s examine this last expression ‘(%x > %y) && (%x > (%z
+ %y))’. We know that when you AND two expressions, they
both have to be true for the result to be true. So, if the
first expression is false, couldn’t we just stop there? We
do, and so does the computer. This is called Short-
Circuiting and makes it so if the first expression is false,
then the second is never executed or evaluated. Well, now
that we’ve got all that through, let’s go on.
while(%bool)
{
//Do Something…
}
%i = 1;
while(%i < 5)
%i++;
22
and Incremental parts. Any of these can be omitted, but if
you use none of them, you end up with an infinite loop and
you need to use the ‘break’ statement inside the loop. Here
are two examples:
%i = 1;
for(;;)
{
if(%i < 5)
break;
%i++;
}
23
24
5.1 Functions
Functions are the ‘bread-and-butter’ of TRIBES Script.
Functions can call themselves, other functions, or built-in
functions. A CS file itself can hold program statements, or
call a function, but typically you only run a CS file once,
and that’s it. A function is denoted by the ‘function’
keyword, an identifier, an argument list, and a body. Here
is an example function:
function test(%var)
{
%var++;
echo(%var);
}
As you can see, this code block has the function keyword,
an identifier, an argument list, and a body that is
surrounded with brackets. Functions can return a value with
the ‘return’ keyword. An example a return function would
be:
function addOne(%var)
{
return %var + 1;
}
function recursive(%var)
{
if(%var <= 0)
return;
return %var + recursive(%var – 1);
}
25
function addAllFrom(%var)
{
for(%i = %var; %i <= 0; %i--)
{
%tmp += %i;
}
return %tmp;
}
function addOne(%var)
{
%var++;
}
//On Server…
function remoteFunction(%clientId, %msg)
{
echo(%msg);
}
26
eval(“function();”);
schedule(“function();”, 1);
5.2 Datablocks
Datablocks are basically Object Descriptions, or Items,
Weapons, Armors, etc. You can find various examples of
datablocks inside the base mod scripts. A sample datablock
for a plant object might look like this:
StaticShapeData Plant
{
shapeFile = "plant1";
debrisId = defaultDebrisSmall;
maxDamage = 0.4;
description = "Plant";
};
There are many properties and such that I can’t list them
all here, but if you look at existing objects, items, and
such you should get a pretty good idea on how to construct
your own.
27
28
6.1 Arrays / Subscripted Variables
Arrays and Subscripted Variables are essentially the
same. However, one is shorter than the other so I’ll be
using ‘Arrays’. An Array in TRIBES is a bit different then
a conventional programming language’s idea of an array. In
TRIBES, an array is basically just an add-on to the
variable’s identifier. Here is an example:
$Array[0] = “Hello”;
$Array0 = “World”;
You may say, ‘The first variable is “Hello” and the second
is “World”.’ In a different language this would be true,
but in TRIBES, this isn’t the case; they both equal “World”.
You aren’t restricted to only using numerical values, you
can also use Booleans, Strings, or Datablock names. Here is
another few examples:
$Array[true] = 0;
$Arraytrue = 1;
//Both equal to 1
$Array[“Hey”] = 0;
$ArrayHey = 1;
//Both equal to 1
$Array[Blaster] = 0;
$ArrayBlaster = 1;
//Both equal to 1
%var = 0;
$Array[%var] = 1;
$Array0 = 0;
//Both equal to 0
Now, I should also mention that these ‘arrays’ are not true
arrays. The obvious difference is that you can use
subscripts other then integers and they aren’t sequential.
The less-than obvious reason is that they don’t share
sequential memory addresses.
29
To loop though an array correctly, you need to use numbers,
as these are the easiest to work with. Here is an example:
This will loop though the entire Array variable and echo
every element to the server. As a little tip, when ever a
variable is not initialized, but used in an expression, it
is either 0, “”, or false, depending on the expression. As
an improvement to the above code, you could do:
30
31
7.1 Linear Search
The linear search is probably the easiest of searches
to perform. Here is the code for a linear search:
function linearSearch(%search)
{
%found = -1;
for(%i = 0; (%current = $Array[%i]) != “”; %i++)
{
if(%current == %search)
%found = %i;
}
return %found;
}
function linearSearch(%search)
{
for(%i = 0; (%current = $Array[%i]) != “”; %i++)
{
if(%current == %search)
return %i;
}
return -1;
}
32
Simple, right? Ok, now that we have our swap function, we
need to make the sort function. Here is an example:
function numberSort()
{
for(%i = 0; $Array[%i] != “”; %i++)
{
%swap = %i;
for(%j = 0; (%compare = $Array[%j]) != “”; %j++)
{
if ($Array[%swap] > %compare)
{
%swap = %j;
}
}
swap(%i, %swap);
}
}
Now, this may look unwieldy, but its actually quite simple!
This type of sort is called a ‘Bubble Sort’. What it does
is run though the entire array once, and then each time
checking if the current value of the array element ‘%swap’
is greater than the ‘%compare’ element. If it is, set it to
be swapped, otherwise continue on. When the second for loop
has finished, it swaps the values and goes on. This can
become very CPU intensive as you might have guessed, so
there are better ways to sort. But, I’m not going to go
into them, if you want some further study, you can look up
some Java tutorials or join a class.
function alphaSort()
{
for(%i = 0; $Array[%i] != “”; %i++)
{
%swap = %i;
for(%j = 0; (%compare = $Array[%j]) != “”; %j++)
{
33
if(String::IsGreaterThan($Array[%swap], %compare))
{
%swap = %j;
}
}
swap(%i, %swap);
}
}
34
35
8.1 Bitwise Theory
I’ve gained a lot of this information from experience
and some very good tutorials over at www.gamedev.net. If
there are similarities it is because I used these to help
me write this section, as I’m not a teacher. A number is a
very abstract thing. Unlike physical objects, which are
easily recognizable, a number can be represented in any
number of ways. The representation we are use is called
decimal, or base 10. The first term is pretty familiar, but
if you're reading this theory, the second term may be new
to you. To see why we use the term "base 10", let's take a
look at a number, say 4232. Read aloud, this is ‘four
thousand, two hundred, thirty-two’. We hear numbers like
that so often that it's not immediately obvious, but this
sounds a lot like a formula:
Do you now see why the term "base 10" is used to describe
the way we usually write numbers? The obvious question to
ask now is, "Why do we have to use 10 as the base?" We
don't! Any positive integer greater than two can be used as
the base. Of course, if we tried to use a "base 1" number
system, the only thing we could write would be strings of
zeroes. So to analyze further, if we take our last formula,
and replace the 10 with a generic base B, then we have the
representation for a number in any base. Now, computers
deal with binary, or base 2. This is because of the nature
of CPUs, the transistors inside them are either ‘On’ or
‘Off’, ‘0’ or ‘1’. For example, consider the binary number
100101. The value of this number is:
36
3FC = (3 * 162) + (F * 161) + (C * 160) = (3 * 162) + (15 *
161) + (12 * 160) = 768 + 240 + 12 = 1020
%hexValue = 0x3FC;
Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F
Binary 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
37
AND A B Result
0 0 0
0 1 1
1 0 1
1 1 1
OR A B Result
0 0 0
0 1 0
1 0 0
1 1 1
XOR A B Result
0 0 1
0 1 0
1 0 0
1 1 1
Operation Operator
Bitwise AND &
Bitwise OR |
Bitwise XOR ^
Bitwise Complement ~
Bitwise AND Assignment &=
Bitwise OR Assignment |=
%x = %y * 8;
%x = %y << 3;
%x = %y * 64;
%x = %y << 6;
%x = %y * 32768;
%x = %y << 15;
38
Pretty cool, isn't it? This is a fast way to accomplish
multiplication by powers of two, using only a bitwise shift.
For reference, here is a list of all shift operators:
Operation Operator
Shift Left <<
Shift Right >>
Shift Left Assignment <<=
Shift Right Assignment >>=
Well, now that all that is out of the way, let’s look at
what we can use this for!
function isPlayer(%property)
{
return (($PlayerProp & %property) > 0);
}
function addProperty(%property)
{
$PlayerProp |= %property;
}
function removeProperty(%property)
{
$PlayerProp ^= %property;
}
addProperty($Expert | $Coder);
addProperty($Admin);
if(isPlayer($Coder))
echo(“Player is a coder.”);
else
echo(“Player is not a coder.”);
39
Really cool, eh? ModX uses this system to store info about
it’s player’s profiles, and I’m sure you can think of other
uses for this.
40
41
9.1 Last Words
Well, I hope I have enlightened you to the ways of the
TRIBES Script Coder. However, don’t consider this the only
thing you should ever read. Computer Science books and
tutorials are great. Should you need more help, you can
always go to great sites like http://www.annihilation.info/,
http://modx.ath.cx:1337/, or even http://www.gamedev.net/.
Remember, if you ask questions on a forum, make the post
intelligible and list what you’ve done, and what you need.
42
43
Appendix
The following pages contain various functions that I
encourage you to use in your own modifications. Of course,
remember to put a side-note mentioning who you learned to
code from ;)
44
function String::IsWhiteSpace(%string)
{
%slen = String::Len(%string);
%IsWhiteSpace = true;
return %IsWhiteSpace;
}
%string = String::MakeCaps(%string);
%compare = String::MakeCaps(%compare);
function String::Reverse(%string)
{
%slen = String::Len(%string);
%outString = "";
for(%i = %slen + 1; %i >= 0; %i--)
{
%outString = %outString @ String::CharAt(%string, %i);
}
return %outString;
}
function String::MakeCaps(%string)
{
%norm = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
45
%capp = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(%i = 0; %i < 52; %i++)
{
%rem = String::getSubStr(%norm, %i, 1);
%new = String::getSubStr(%capp, %i, 1);
%string = String::Replace(%string, %rem, %new);
}
return %string;
}
function String::MakeLower(%string)
{
%norm = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
%low = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
for(%i = 0; %i < 52; %i++)
{
%rem = String::getSubStr(%norm, %i, 1);
%new = String::getSubStr(%low, %i, 1);
%string = String::Replace(%string, %rem, %new);
}
return %string;
}
function String::IsAlpha(%string)
{
%norm = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
%slen = String::Len(%string);
for(%i = 0; %i < %slen; %i++)
{
%ch = String::CharAt(%i);
for(%f = 0; %f < 52; %f++)
{
if(%ch == String::CharAt(%f))
{
%out = %out @ %ch;
}
}
}
return (%string == %out);
}
function String::Len(%string)
{
while(String::getSubStr(%string, %len, 1) != "")
%len++;
return %len;
}
46
function String::Contains(%string, %search)
{
%len = String::Len(%search);
for (%i = 0; (%char = String::getSubStr(%string, %i, %len)) != "";
%i++)
{
if (%char @ "s" == %search @ "s")
return true;
}
return false;
}
if(%stringFinal != "")
return %stringFinal;
return -1;
}
if(%stringFinal != "")
return %stringFinal;
return -1;
}
47
function String::ParseIP(%address)
{
if(String::getSubStr(%address,0,8) == "LOOPBACK")
return "LOOPBACK";
%ipCut = String::getSubStr(%address,3,20);
while(String::getSubStr(%ipCut,%len,1) != ":" && %len < 20)
%len++;
%sub = String::getSubStr(%ipCut,0,%len);
return %sub;
}
$OmitList[0] = "a";
$OmitList[1] = "b";
$OmitList[2] = "c";
$OmitList[3] = "d";
$OmitList[4] = "e";
$OmitList[5] = "f";
$OmitList[6] = "g";
$OmitList[7] = "h";
$OmitList[8] = "i";
$OmitList[9] = "j";
$OmitList[10] = "k";
$OmitList[11] = "l";
$OmitList[12] = "m";
$OmitList[13] = "n";
$OmitList[14] = "o";
$OmitList[15] = "p";
$OmitList[16] = "q";
$OmitList[17] = "r";
$OmitList[18] = "s";
$OmitList[19] = "t";
$OmitList[20] = "u";
$OmitList[21] = "v";
$OmitList[22] = "w";
$OmitList[23] = "x";
$OmitList[24] = "y";
$OmitList[25] = "z";
$OmitList[26] = "A";
$OmitList[27] = "B";
$OmitList[28] = "C";
$OmitList[29] = "D";
$OmitList[30] = "E";
$OmitList[31] = "F";
$OmitList[32] = "G";
$OmitList[33] = "H";
$OmitList[34] = "I";
$OmitList[35] = "J";
$OmitList[36] = "K";
$OmitList[37] = "L";
$OmitList[38] = "M";
$OmitList[39] = "N";
$OmitList[40] = "O";
$OmitList[41] = "P";
$OmitList[42] = "Q";
$OmitList[43] = "R";
$OmitList[44] = "S";
$OmitList[45] = "T";
$OmitList[46] = "U";
$OmitList[47] = "V";
48
$OmitList[48] = "W";
$OmitList[49] = "X";
$OmitList[50] = "Y";
$OmitList[51] = "Z";
$OmitList[52] = "~";
$OmitList[53] = "`";
$OmitList[54] = "!";
$OmitList[55] = "@";
$OmitList[56] = "#";
$OmitList[57] = "$";
$OmitList[58] = "%";
$OmitList[59] = "^";
$OmitList[60] = "&";
$OmitList[61] = "*";
$OmitList[62] = "(";
$OmitList[63] = ")";
$OmitList[64] = " "; // -
$OmitList[65] = "_";
$OmitList[66] = "=";
$OmitList[67] = "+";
$OmitList[68] = "[";
$OmitList[69] = "{";
$OmitList[70] = "]";
$OmitList[71] = "}";
$OmitList[72] = "\\";
$OmitList[73] = "|";
$OmitList[74] = "/";
$OmitList[75] = "?";
$OmitList[76] = " "; // .
$OmitList[77] = ">";
$OmitList[78] = ",";
$OmitList[79] = "<";
$OmitList[80] = " ";
function String::NumericParse(%string)
{
%replace = "";
%len = 1;
for (%j = 0; (%search = $OmitList[%j]) != "" && %j < 100; %j++)
{
for (%i = 0; (%char = String::getSubStr(%string, %i, %len)) != ""
&& %i < 300; %i++)
{
if (%search @ "s" == %char @ "s")
%string = String::getSubStr(%string, 0, %i) @ %replace
@ String::getSubStr(%string, %i + %len, 255);
}
}
return %string;
}
49
}
return %o;
}
%slen = String::Len(%string);
%xoc = String::Occurances(escapeString(%string), "\\x");
%toc = String::Occurances(%string, "\n");
%noc = String::Occurances(%string, "\t");
$CharacterList[0] = "\x00";
$CharacterList[1] = "\x01";
$CharacterList[2] = "\x02";
$CharacterList[3] = "\x03";
$CharacterList[4] = "\x04";
$CharacterList[5] = "\x05";
$CharacterList[6] = "\x06";
$CharacterList[7] = "\x07";
$CharacterList[8] = "\x08";
$CharacterList[9] = "\x09";
$CharacterList[10] = "\x0A";
$CharacterList[11] = "\x0B";
$CharacterList[12] = "\x0C";
$CharacterList[13] = "\x0D";
$CharacterList[14] = "\x0E";
$CharacterList[15] = "\x0F";
$CharacterList[16] = "\x10";
$CharacterList[17] = "\x11";
$CharacterList[18] = "\x12";
$CharacterList[19] = "\x13";
$CharacterList[20] = "\x14";
$CharacterList[21] = "\x15";
$CharacterList[22] = "\x16";
$CharacterList[23] = "\x17";
$CharacterList[24] = "\x18";
$CharacterList[25] = "\x19";
$CharacterList[26] = "\x1A";
$CharacterList[27] = "\x1B";
$CharacterList[28] = "\x1C";
$CharacterList[29] = "\x1D";
$CharacterList[30] = "\x1E";
$CharacterList[31] = "\x1F";
$CharacterList[32] = "\x20";
$CharacterList[33] = "\x21";
$CharacterList[34] = "\x22";
$CharacterList[35] = "\x23";
$CharacterList[36] = "\x24";
50
$CharacterList[37] = "\x25";
$CharacterList[38] = "\x26";
$CharacterList[39] = "\x27";
$CharacterList[40] = "\x28";
$CharacterList[41] = "\x29";
$CharacterList[42] = "\x2A";
$CharacterList[43] = "\x2B";
$CharacterList[44] = "\x2C";
$CharacterList[45] = "\x2D";
$CharacterList[46] = "\x2E";
$CharacterList[47] = "\x2F";
$CharacterList[48] = "\x30";
$CharacterList[49] = "\x31";
$CharacterList[50] = "\x32";
$CharacterList[51] = "\x33";
$CharacterList[52] = "\x34";
$CharacterList[53] = "\x35";
$CharacterList[54] = "\x36";
$CharacterList[55] = "\x37";
$CharacterList[56] = "\x38";
$CharacterList[57] = "\x39";
$CharacterList[58] = "\x3A";
$CharacterList[59] = "\x3B";
$CharacterList[60] = "\x3C";
$CharacterList[61] = "\x3D";
$CharacterList[62] = "\x3E";
$CharacterList[63] = "\x3F";
$CharacterList[64] = "\x40";
$CharacterList[65] = "\x41";
$CharacterList[66] = "\x42";
$CharacterList[67] = "\x43";
$CharacterList[68] = "\x44";
$CharacterList[69] = "\x45";
$CharacterList[70] = "\x46";
$CharacterList[71] = "\x47";
$CharacterList[72] = "\x48";
$CharacterList[73] = "\x49";
$CharacterList[74] = "\x4A";
$CharacterList[75] = "\x4B";
$CharacterList[76] = "\x4C";
$CharacterList[77] = "\x4D";
$CharacterList[78] = "\x4E";
$CharacterList[79] = "\x4F";
$CharacterList[80] = "\x50";
$CharacterList[81] = "\x51";
$CharacterList[82] = "\x52";
$CharacterList[83] = "\x53";
$CharacterList[84] = "\x54";
$CharacterList[85] = "\x55";
$CharacterList[86] = "\x56";
$CharacterList[87] = "\x57";
$CharacterList[88] = "\x58";
$CharacterList[89] = "\x59";
$CharacterList[90] = "\x5A";
$CharacterList[91] = "\x5B";
$CharacterList[92] = "\x5C";
$CharacterList[93] = "\x5D";
$CharacterList[94] = "\x5E";
$CharacterList[95] = "\x5F";
$CharacterList[96] = "\x60";
$CharacterList[97] = "\x61";
51
$CharacterList[98] = "\x62";
$CharacterList[99] = "\x63";
$CharacterList[100] = "\x64";
$CharacterList[101] = "\x65";
$CharacterList[102] = "\x66";
$CharacterList[103] = "\x67";
$CharacterList[104] = "\x68";
$CharacterList[105] = "\x69";
$CharacterList[106] = "\x6A";
$CharacterList[107] = "\x6B";
$CharacterList[108] = "\x6C";
$CharacterList[109] = "\x6D";
$CharacterList[110] = "\x6E";
$CharacterList[111] = "\x6F";
$CharacterList[112] = "\x70";
$CharacterList[113] = "\x71";
$CharacterList[114] = "\x72";
$CharacterList[115] = "\x73";
$CharacterList[116] = "\x74";
$CharacterList[117] = "\x75";
$CharacterList[118] = "\x76";
$CharacterList[119] = "\x77";
$CharacterList[120] = "\x78";
$CharacterList[121] = "\x79";
$CharacterList[122] = "\x7A";
$CharacterList[123] = "\x7B";
$CharacterList[124] = "\x7C";
$CharacterList[125] = "\x7D";
$CharacterList[126] = "\x7E";
$CharacterList[127] = "\x7F";
$CharacterList[128] = "\x80";
$CharacterList[129] = "\x81";
$CharacterList[130] = "\x82";
$CharacterList[131] = "\x83";
$CharacterList[132] = "\x84";
$CharacterList[133] = "\x85";
$CharacterList[134] = "\x86";
$CharacterList[135] = "\x87";
$CharacterList[136] = "\x88";
$CharacterList[137] = "\x89";
$CharacterList[138] = "\x8A";
$CharacterList[139] = "\x8B";
$CharacterList[140] = "\x8C";
$CharacterList[141] = "\x8D";
$CharacterList[142] = "\x8E";
$CharacterList[143] = "\x8F";
$CharacterList[144] = "\x90";
$CharacterList[145] = "\x91";
$CharacterList[146] = "\x92";
$CharacterList[147] = "\x93";
$CharacterList[148] = "\x94";
$CharacterList[149] = "\x95";
$CharacterList[150] = "\x96";
$CharacterList[151] = "\x97";
$CharacterList[152] = "\x98";
$CharacterList[153] = "\x99";
$CharacterList[154] = "\x9A";
$CharacterList[155] = "\x9B";
$CharacterList[156] = "\x9C";
$CharacterList[157] = "\x9D";
$CharacterList[158] = "\x9E";
52
$CharacterList[159] = "\x9F";
$CharacterList[160] = "\xA0";
$CharacterList[161] = "\xA1";
$CharacterList[162] = "\xA2";
$CharacterList[163] = "\xA3";
$CharacterList[164] = "\xA4";
$CharacterList[165] = "\xA5";
$CharacterList[166] = "\xA6";
$CharacterList[167] = "\xA7";
$CharacterList[168] = "\xA8";
$CharacterList[169] = "\xA9";
$CharacterList[170] = "\xAA";
$CharacterList[171] = "\xAB";
$CharacterList[172] = "\xAC";
$CharacterList[173] = "\xAD";
$CharacterList[174] = "\xAE";
$CharacterList[175] = "\xAF";
$CharacterList[176] = "\xB0";
$CharacterList[177] = "\xB1";
$CharacterList[178] = "\xB2";
$CharacterList[179] = "\xB3";
$CharacterList[180] = "\xB4";
$CharacterList[181] = "\xB5";
$CharacterList[182] = "\xB6";
$CharacterList[183] = "\xB7";
$CharacterList[184] = "\xB8";
$CharacterList[185] = "\xB9";
$CharacterList[186] = "\xBA";
$CharacterList[187] = "\xBB";
$CharacterList[188] = "\xBC";
$CharacterList[189] = "\xBD";
$CharacterList[190] = "\xBE";
$CharacterList[191] = "\xBF";
$CharacterList[192] = "\xC0";
$CharacterList[193] = "\xC1";
$CharacterList[194] = "\xC2";
$CharacterList[195] = "\xC3";
$CharacterList[196] = "\xC4";
$CharacterList[197] = "\xC5";
$CharacterList[198] = "\xC6";
$CharacterList[199] = "\xC7";
$CharacterList[200] = "\xC8";
$CharacterList[201] = "\xC9";
$CharacterList[202] = "\xCA";
$CharacterList[203] = "\xCB";
$CharacterList[204] = "\xCC";
$CharacterList[205] = "\xCD";
$CharacterList[206] = "\xCE";
$CharacterList[207] = "\xCF";
$CharacterList[208] = "\xD0";
$CharacterList[209] = "\xD1";
$CharacterList[210] = "\xD2";
$CharacterList[211] = "\xD3";
$CharacterList[212] = "\xD4";
$CharacterList[213] = "\xD5";
$CharacterList[214] = "\xD6";
$CharacterList[215] = "\xD7";
$CharacterList[216] = "\xD8";
$CharacterList[217] = "\xD9";
$CharacterList[218] = "\xDA";
$CharacterList[219] = "\xDB";
53
$CharacterList[220] = "\xDC";
$CharacterList[221] = "\xDD";
$CharacterList[222] = "\xDE";
$CharacterList[223] = "\xDF";
$CharacterList[224] = "\xE0";
$CharacterList[225] = "\xE1";
$CharacterList[226] = "\xE2";
$CharacterList[227] = "\xE3";
$CharacterList[228] = "\xE4";
$CharacterList[229] = "\xE5";
$CharacterList[230] = "\xE6";
$CharacterList[231] = "\xE7";
$CharacterList[232] = "\xE8";
$CharacterList[233] = "\xE9";
$CharacterList[234] = "\xEA";
$CharacterList[235] = "\xEB";
$CharacterList[236] = "\xEC";
$CharacterList[237] = "\xED";
$CharacterList[238] = "\xEE";
$CharacterList[239] = "\xEF";
$CharacterList[240] = "\xF0";
$CharacterList[241] = "\xF1";
$CharacterList[242] = "\xF2";
$CharacterList[243] = "\xF3";
$CharacterList[244] = "\xF4";
$CharacterList[245] = "\xF5";
$CharacterList[246] = "\xF6";
$CharacterList[247] = "\xF7";
$CharacterList[248] = "\xF8";
$CharacterList[249] = "\xF9";
$CharacterList[250] = "\xFA";
$CharacterList[251] = "\xFB";
$CharacterList[252] = "\xFC";
$CharacterList[253] = "\xFD";
$CharacterList[254] = "\xFE";
$CharacterList[255] = "\xFF";
$CharacterList[256] = "\t";
$CharacterList[257] = "\n";
$CharacterList[258] = "END";
function String::CharacterValue(%char)
{
%len = String::Len(%char);
for (%j = 0; (%search = $CharacterList[%j]) != "END"; %j++)
{
if (%search @ "s" == String::charAt(%char, 0) @ "s")
{
return %j;
}
}
return -1;
}
function String::fromCharCode(%code)
{
for (%j = 0; (%search = $CharacterList[%j]) != "END"; %j++)
{
if (%j == %code)
return %search;
}
return "";
54
}
function String::trim(%string)
{
if(String::Replace(%string, " ", "") == "")
return "";
%slen = String::Len(%string);
for(%i = 0; %i < %slen; %i++)
{
if(String::charAt(%string, %i) == " ")
%ftrim++;
else
break;
}
for(%i = %slen - 1; %i >= 0; %i--)
{
if(String::charAt(%string, %i) == " ")
%btrim++;
else
break;
}
return String::Mid(%string, %ftrim, %slen - %btrim);
}
55
$Math::PI = "3.14159265358979323";
function Math::rad2deg(%radians)
{
return %radians * (180 / $Math::PI);
}
function Math::deg2rad(%degrees)
{
return %degrees * ($Math::PI / 180);
}
function Math::roundDown(%delta)
{
return floor(%delta - 0.01);
}
function Math::roundUp(%delta)
{
return ceil(%delta + 0.01);
}
function Math::randomInt(%max)
{
return floor(getRandom() * (%max - 0.01));
}
function Math::sin(%theta)
{
if(%theta == "NaN")
return;
return (%theta - (pow(%theta,3)/6) + (pow(%theta,5)/120) - (pow(%
theta,7)/5040) + (pow(%theta,9)/362880) - (pow(%theta,11)/39916800));
}
function Math::cos(%theta)
{
if(%theta == "NaN")
return;
return (1 - (pow(%theta,2)/2) + (pow(%theta,4)/24) - (pow(%
theta,6)/720) + (pow(%theta,8)/40320) - (pow(%theta,10)/3628800));
}
function Math::tan(%theta)
{
if(%theta == "NaN")
return;
return Sin(%theta) / Cos(%theta);
}
function Math::absolute(%delta)
{
return sqrt(pow(%delta,2));
}
function Math::isNaN(%number)
{
if(%number == "NaN" || String::NumericParse(%number) != %number)
return true;
return false;
}
56
function Vector::rotate(%vec,%rot)
{
%pi = $Math::PI;
%rot3= getWord(%rot,2);
for(%i = 0; %rot3 >= %pi*2; %i++) %rot3 = %rot3 - %pi*2;
if (%rot3 > %pi) %rot3 = %rot3 - %pi*2;
%vec1= getWord(%vec,0);
%vec2= getWord(%vec,1);
%vc = %vec2;
%vec3= getWord(%vec,2);
%ray = %vec1;
%vec1 = %ray*Math::cos(%rot3);
%vec2 = %ray*Math::sin(%rot3);
%vec = %vec1 @" "@ %vec2 @" "@ %vec3;
%vec = Vector::add(%vec,Vector::getFromRot(%rot,%vc,0));
return %vec;
}
function GameBase::getMass(%obj)
{
%mass = (GameBase::getDataName(%obj).Mass);
if (getObjectType(%obj) == "Flyer")
%mass += %obj.PassengerMass;
57
return %mass;
}
function GameBase::getMuzzlePosition(%player)
{
%trans = GameBase::getMuzzleTransform(%player);
%vec6 = getWord(%trans,9);
%vec7 = getWord(%trans,10);
%vec8 = getWord(%trans,11);
return %vec6@" "@%vec7@" "@%vec8;
}
58
function EncryptionSystem::Encipher(%str, %key)
{
%key = EncryptionSystem::GetKey(%key);
%str = String::Reverse(%str);
%slen = String::Len(%str);
%sp = String::trim(%sp);
return String::Reverse(%final);
}
function EncryptionSystem::GetKey(%str)
{
%slen = String::Len(%str);
59
@ECHO OFF
TITLE VOL Compile Batch
ECHO (-) Deleting Old 'Scripts.vol'...
TITLE VOL Compile Batch: Deleting Old 'Scripts.vol'
DEL scripts.vol
ECHO (-) Creating New 'Scripts.vol'...
TITLE VOL Compile Batch: Creating New 'Scripts.vol'
ECHO (-) Archiving Files...
TITLE VOL Compile Batch: Archiving Files
FOR %%f IN (*.cs) DO (
vt -q scripts.vol %%f
ECHO %%f
TITLE VOL Compile Batch: Archiving %%f
)
ECHO (-) Done...
TITLE VOL Compile Batch: Done
60