This is totally out of date now.

This commit is contained in:
Brian Koropoff 2003-07-17 17:55:09 +00:00
parent 043ec906c4
commit 59db43b377

View file

@ -1,527 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<!-- ================================================================================ -->
<!-- This HTML file was created by AbiWord. -->
<!-- AbiWord is a free, Open Source word processor. -->
<!-- You may obtain more information about AbiWord at www.abisource.com -->
<!-- ================================================================================ -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" >
<title>/home/snax/source/quakeforge/doc/gib.html</title>
<style type="text/css">
body
{
font-family: "Times New Roman";
font-variant: normal;
text-indent: 0in;
widows: 2;
font-style: normal;
font-weight: normal;
text-decoration: none;
color: #000000;
text-align: left;
font-size: 12pt;
font-stretch: normal;
background-color: #ffffff;
}
@media print
{
body
{
padding-top: 1in; padding-bottom: 1in;
padding-left: 1in; padding-right: 1in;
}
}
p, .Normal
{
font-family: "Times New Roman";
margin-top: 0pt;
font-variant: normal;
margin-left: 0pt;
text-indent: 0in;
widows: 2;
font-style: normal;
font-weight: normal;
text-decoration: none;
color: #000000;
text-align: left;
margin-bottom: 0pt;
margin-right: 0pt;
font-size: 12pt;
font-stretch: normal;
}
</style>
</head>
<body><div>
<p style="text-align: center"><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 20.000000pt">GIB Mark III Reference</span></p>
<p style="text-align: center"><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 20.000000pt">Beta version</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Basic Syntax</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">The syntax of GIB is mostly similar to the normal quake console:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">command arg1 arg2 arg3 ...</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">However, there are a few differences when it comes to characters that surround tokens.&nbsp; Double quotes work as you would expect:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">echo "Hello, world!"</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">No processing is done to text inside double quotes.&nbsp; If you want to use variables or function return values, you shouldn't use double quotes.&nbsp; Within double quotes you may now use escape characters.&nbsp; As of now, this allows you to use \" in place of a double quote and \n in place of the newline character.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">echo "This token has two \"quotes\" and\na newline."</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">In addition to double quotes, you may now use curly braces to surround tokens.&nbsp; Curly braces have one unique feature:&nbsp; you may have line breaks within them:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">echo {This token</span></p>
<p><span style="font-family: 'Courier'">has several</span></p>
<p><span style="font-family: 'Courier'">lines}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">This is most useful with functions, loops, and if statements.&nbsp; As with double quotes, no processing is done inside curly braces.&nbsp; The final type of token is one surrounded by parentheses.&nbsp; These enclose math expressions that will be evaluated before the command is executed:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">echo (5*5-(1/(2+1)))</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">See the section on the math evaluator for more information.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">Sometimes you will want to be able to combine tokens of different types into one token.&nbsp; For instance, it might be useful to include a math expression inside a string that will be displayed.&nbsp; You can use a comma (,) between two token to concatenate them:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">echo "5 times 5 is ", (5*5), "."</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">GIB is fairly anal about malformed commands.&nbsp; Unmatched braces, parentheses, and double quotes will generate errors and halt execution of your program.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Variables</span></p>
<p><br>
</p>
<p><span style="text-decoration: underline; font-family: 'Times New Roman'">Types</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">There are three types of variables in GIB: local, global, and console.&nbsp; Local variables are visible only to the current function and are destroyed when that function completes.&nbsp; Global variables are visible to all GIB functions and are never destroyed.&nbsp; Console variables are not strictly part of GIB but can be manipulated and used by it.</span></p>
<p><br>
</p>
<p><span style="text-decoration: underline; font-family: 'Times New Roman'">Structure</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">Local and global variables differ from console variables in that they can be trees.&nbsp; For instance, the following would all be part of the same variable:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">foobar</span></p>
<p><span style="font-family: 'Courier'">foobar.1</span></p>
<p><span style="font-family: 'Courier'">foobar.2</span></p>
<p><span style="font-family: 'Courier'">foobar.2.string</span></p>
<p><span style="font-family: 'Courier'">foobar.3.string</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">If a variable is global, all branches of that variable are automatically global as well.</span></p>
<p><br>
</p>
<p><span style="text-decoration: underline; font-family: 'Times New Roman'">Substitution</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">Any place outside quotes, the following patterns will be replaced with the value of the variable they specify:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">$variable</span></p>
<p><span style="font-family: 'Courier'">${variable}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">In the first example, the end of a variable name is considered to be the first non-alphanumeric, non-underline character, for instance:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">$var1*$var2</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">would be two different variables with a * between them</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">In the second example, everything within the braces ({ and }) is considered part of the variable name.&nbsp; Braces MUST be used when substituting branches of variables:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">${variable.branch.anotherbranch}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">This makes assignment dynamically to a branch less cumbersome, because periods in variable names won't automatically get swallowed.&nbsp; Variables can act as pointers to another variable by containing their name.&nbsp; You can then access the named variable indirectly through the pointer:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">$$pointer</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">You can use this to dynamically access branches as well:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">${variable.$i.string}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">You may trim the value of a variable down into a certain range of characters.&nbsp; For instance:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">$variable[2:5]</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">Will give you characters 2 through 5 of the variable.&nbsp; Characters start at 0.&nbsp; If you try to access characters outside the length of the variable, it will be clipped to the end of the variable.&nbsp;&nbsp; A negative number counts backwards from the end of the variable, so -1 would mean the second from last character, -2 the third from the last, and so on.&nbsp; To specify the last character, use a colon but don't specify a second number.&nbsp; </span><span style="text-position: ; color:#000000; font-family: 'Arial'; font-size: 12.000000pt">If you only want one character, you can omit the colon and second number.&nbsp; </span><span style="font-family: 'Arial'">Consider these examples:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">h = "hello"</span></p>
<p><span style="font-family: 'Courier'">echo $h[0:1]&nbsp; // Prints "he"</span></p>
<p><span style="font-family: 'Courier'">echo $h[:2]&nbsp;&nbsp; // Prints "hel"</span></p>
<p><span style="font-family: 'Courier'">echo $h[2:]&nbsp;&nbsp; // Prints "llo"</span></p>
<p><span style="font-family: 'Courier'">echo $h[1:-1] // Prints "ell"</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">Here is one thing that will not work:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">${variable.$var[0:1].string} // Indexing only works at the top level</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">Variables will be checked in this order when substituting: Local, global, console.</span></p>
<p><br>
</p>
<p><span style="text-decoration: underline; font-family: 'Times New Roman'">Assignment</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">You assign to a GIB variable using the syntax:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">variable = value</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">Assigning to a branch is simple:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">variable.branch = value</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">If you want to dynamically assign to a branch, you can use:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">variable.$i.string = value</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">where the variable i contains the name of the branch to assign to.&nbsp; Note that if the period after $i were considered to be part of the variable name, this wouldn't work.&nbsp; The number and level of branches is theoretically unlimited.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">When assigning to a variable that doesn't exist, it is automatically created as a local.&nbsp; If a local already exists, it is assigned to.&nbsp; If a global already exists, it is assigned to.&nbsp; If both a local and global exist with the same name, the local is assigned to.&nbsp; You should declare your globals in the main body of your GIB script with the following syntax:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">global varname</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">This ensures that the variable and all branches used later on will be persistent across different functions.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">If you can't be certain that a variable you want to use as a local doesn't already exist as a global, you can use the following at the start of your functions:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'">local varname</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'">This will ensure that all further operations on that variable will use a local version.&nbsp; You will be sharing a namespace with any other loaded GIB scripts, so this is advised.&nbsp; On the other hand, it is bad practice to use common variable names such as i as globals.&nbsp; Consider created a single global variable with the name of your script and using branches of it to store global data.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Functions</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Functions are like aliases of the normal quake console, with several differences:</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">- They execute in a new context</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">- They can take arguments</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">- They can return values</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">- They are normally not usable from the console.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">You declare a function as follows:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">function name program</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">In general, you will want to write functions like this:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">function test {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Hello, world!"</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">A function gets its own set of local variables whenever it is executed.&nbsp; Each instance of a function gets a unique set.&nbsp; When a function is executed, several local variables are set up for it.&nbsp; These are argc, the number of arguments the function was called with, and the numbers 0 through argc-1, each containing and argument.&nbsp; Argument 0 is the name of the function.&nbsp; Therefore, even a function called with no arguments will get an argc of 1.&nbsp; Consider the following example:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">function test2 {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "The name of this function is ", $0</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "My first argument is ", $1</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">You can use a "pointer" variable and argc to easily examine each argument passed to a function.&nbsp; The following function prints each argument passed to it on a separate line:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">function printargs {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> local i</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> i = 1</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> while ($i &lt; $argc) {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">&nbsp; echo $$i</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">&nbsp; i = ($i + 1)</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> }</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Functions can return a value to whatever called them at any time.&nbsp; The syntax for return is as follows:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">return value</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">If you omit the value, the function will cease execution but will not return anything.&nbsp; Attempting to return a value where it isn't wanted (to a non-GIB buffer, or to a buffer that has not requested a return value, or at the top of the execution stack) will result in a warning, but execution will proceed as usual.&nbsp; In order to use the return value of a function, you must substitute it into your command using backticks (` `).&nbsp; This key is usually found above the tab key on most keyboards.&nbsp; It usually is the same key with ~ on it.&nbsp; Consider this example:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">function hello {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> return "Hello, world!"</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">echo `hello`</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">The function within the backticks is run, and the return value is substituted in its place.&nbsp; This example would result in "Hello, world!" being printed.&nbsp; Some built-in GIB commands can return values; backticks can be used with these as well.&nbsp; Using backticks with something that does not result in a return value will cause an error.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Normally, GIB functions can only be called from other GIB functions.&nbsp; However, the export command can be used to make a GIB function available to the console:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">function test {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Testing 1 2 3..."</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">export test</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">The ideal GIB script will export several functions for use in binds or at the console and keep the rest unexported as support functions.&nbsp; This reduces namespace pollution.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Flow control</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Several GIB commands are available for controlling the flow of a GIB program:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">while</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage:&nbsp; </span><span style="font-family: 'Courier'; font-size: 12.000000pt">while condition program</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">example:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">i = 0</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">while ($i &lt; 10) {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> i = ($i + 1)</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">notes:&nbsp; While the condition statement evaluates to a non-zero number, the program will be continuously executed.&nbsp; You can use the break command at any time inside a loop to end the loop prematurely.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">for</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">for variable in list program</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">example:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">for i in "1 2 3 4 5" {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo $i, " times 2 is ", ($i * 2)</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">notes: "for" iterates a local variable through each whitespace-separated token of a list.&nbsp; To achieve this, the internal command "__for" is used at the start of each iteration.&nbsp; Manual use of this command is highly discouraged.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">if/ifnot</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">if condition program [else program2]</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">example:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">if $var1 {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Var1 is true."</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">if $var1 {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Var1 is true."</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">} else {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Var1 is false."</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">if $var1 {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Var1 is true."</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">} else if $var2 {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Var2 is true."</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">} else {</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt"> echo "Var1 and var2 are false."</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">}</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">notes:&nbsp; </span><span style="font-family: 'Courier'; font-size: 12.000000pt">if</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> executes </span><span style="font-family: 'Courier'; font-size: 12.000000pt">program </span><span style="font-family: 'Arial'; font-size: 12.000000pt">when condition evaluates to a non-zero number (true).&nbsp; If the condition is false but else and a second program are present, it will be executed instead. </span><span style="font-family: 'Courier'; font-size: 12.000000pt">If-else</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> statements can be chained together.&nbsp; If </span><span style="font-family: 'Courier'; font-size: 12.000000pt">ifnot</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> is used instead of </span><span style="font-family: 'Courier'; font-size: 12.000000pt">if</span><span style="font-family: 'Arial'; font-size: 12.000000pt">, the first program will be executed if the statement is false and the second if the statement is true.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Math Evaluator</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">The math evaluator supports common arithmetic and logical operators and respects order of operations.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">!&nbsp; Unary not</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">** Exponent</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">/&nbsp; Division</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">-&nbsp; Unary negation (to get negative numbers)</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">*&nbsp; Multiplication</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">+&nbsp; Addition</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">-&nbsp; Subtraction</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">== Equality test</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">!= Not-equal test</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">&gt;= Greater-than-or-equal-to test</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">&gt;&nbsp; Greater-then test</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">&lt;= Less-than-or-equal-to test</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">&lt;&nbsp; Less-than test</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">|| Logical or</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">&amp;&amp; Logical and</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Operations will be performed starting at the top of the list and moving down.&nbsp; In addition to binary and unary operators, several functions are available:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">sin&nbsp; Sine</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">cos&nbsp; Cosine</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">tan&nbsp; Tangent</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">asin Inverse (arc) sine</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">acos Inverse (arc) cosine</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">atan Inverse (arc) tangent</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">A function should be used as follows:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">echo "Twice the sin of 5 radians is ", (2 * sin (5)), "."</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Note that all trigonometric functions operate in radians.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">File access</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">GIB provides rudimentary file access to the current game directory (the directory where the currently-loaded mod resides, determined by the console variable gamedir).&nbsp; All subdirectories of the current game directory are accessible, but attempts to escape higher into the file system via ".." will cause an access error.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">file.read</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">file.read file</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Returns the contents of </span><span style="font-family: 'Courier'; font-size: 12.000000pt">file</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">file.write</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">file.write file contents</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Creates/overwrites </span><span style="font-family: 'Courier'; font-size: 12.000000pt">file</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> with </span><span style="font-family: 'Courier'; font-size: 12.000000pt">contents</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">file.find</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">file.find glob [subdir]</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Returns a list suitable for use in a for loop of all files in the current game directory that match </span><span style="font-family: 'Courier'; font-size: 12.000000pt">glob</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.&nbsp; "*.cfg" and "file???.foo" are examples of globs.&nbsp; If the optional </span><span style="font-family: 'Courier'; font-size: 12.000000pt">subdir </span><span style="font-family: 'Arial'; font-size: 12.000000pt">argument is provided, that directory will be searched instead of the root game directory.</span></p>
<p><br>
</p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Threads and callbacks</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Threads are highly experimental at this point, and aren't true threads in that multitasking is not pre-emptive.&nbsp; Threads must issue the wait command to relinquish control to the console and other threads.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Callbacks are functions registered to be started in a thread when a certain event is triggered in the client or server.&nbsp; Currently, only a few events in qw-client can have callbacks associated with them, although more will be added.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">thread.create</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">thread.create program</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Creates a new thread containing </span><span style="font-family: 'Courier'; font-size: 12.000000pt">program</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.&nbsp; Returns a unique ID number that should be saved for looping threads.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">thread.kill</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">thread.kill id</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Immediately ends the thread with the ID </span><span style="font-family: 'Courier'; font-size: 12.000000pt">id</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Game</span><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">-</span><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">play hooks</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">As of the 0.5.2 release of QuakeForge, </span><span style="font-family: 'Arial'; font-size: 12.000000pt">qw-client provides several global variables and callbacks so that GIB can monitor player stats</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.&nbsp; The "player" global tree variable is updated with information as follows:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.health:&nbsp; </span><span style="font-family: 'Courier'; font-size: 12.000000pt">The </span><span style="font-family: 'Courier'; font-size: 12.000000pt">player's health</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.a</span><span style="font-family: 'Courier'; font-size: 12.000000pt">rmor:&nbsp; The pl</span><span style="font-family: 'Courier'; font-size: 12.000000pt">a</span><span style="font-family: 'Courier'; font-size: 12.000000pt">yer's armor</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.armor.type</span><span style="font-family: 'Courier'; font-size: 12.000000pt">:&nbsp; The type </span><span style="font-family: 'Courier'; font-size: 12.000000pt">(green, yellow, red, none) of armor the player is wearing.</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.ammo</span><span style="font-family: 'Courier'; font-size: 12.000000pt">.(type)</span><span style="font-family: 'Courier'; font-size: 12.000000pt">:&nbsp; </span><span style="font-family: 'Courier'; font-size: 12.000000pt">Ammo of (type) that is a</span><span style="font-family: 'Courier'; font-size: 12.000000pt">v</span><span style="font-family: 'Courier'; font-size: 12.000000pt">a</span><span style="font-family: 'Courier'; font-size: 12.000000pt">ilable.&nbsp; </span><span style="font-family: 'Courier'; font-size: 12.000000pt">(type) can be shells, nails, rockets, or cells</span><span style="font-family: 'Courier'; font-size: 12.000000pt">.</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.</span><span style="font-family: 'Courier'; font-size: 12.000000pt">weapon.(number):&nbsp; </span><span style="font-family: 'Courier'; font-size: 12.000000pt">1 i</span><span style="font-family: 'Courier'; font-size: 12.000000pt">f the weapon corresponding to (number</span><span style="font-family: 'Courier'; font-size: 12.000000pt">) is available, 0 otherwise.</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.key.</span><span style="font-family: 'Courier'; font-size: 12.000000pt">(</span><span style="font-family: 'Courier'; font-size: 12.000000pt">number)</span><span style="font-family: 'Courier'; font-size: 12.000000pt">: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">1 if</span><span style="font-family: 'Courier'; font-size: 12.000000pt"> the player has key or flag (number).</span><span style="font-family: 'Courier'; font-size: 12.000000pt">&nbsp; Number can be 1 or 2.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Several callbacks can be registered </span><span style="font-family: 'Arial'; font-size: 12.000000pt">that will get cal</span><span style="font-family: 'Arial'; font-size: 12.000000pt">led when one of these </span><span style="font-family: 'Arial'; font-size: 12.000000pt">stats changes</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.&nbsp; Simply set the glo</span><span style="font-family: 'Arial'; font-size: 12.000000pt">bal variable to the name of the function to be called</span><span style="font-family: 'Arial'; font-size: 12.000000pt">:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.health.callback:&nbsp; Passed the new health value as an argument</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.armor.callback:&nbsp; Passed the new armor value.</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.</span><span style="font-family: 'Courier'; font-size: 12.000000pt">ammo.(type).callback:&nbsp; Passed the new am</span><span style="font-family: 'Courier'; font-size: 12.000000pt">mo value.</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.weapon.callback:&nbsp; Called when available weapons change.</span></p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">player.key.callbac</span><span style="font-family: 'Courier'; font-size: 12.000000pt">k:&nbsp; Called when a</span><span style="font-family: 'Courier'; font-size: 12.000000pt">ny key is gained or lost.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Note that in the future these callbacks may get registered in a different way.&nbsp; These hooks are currently for t</span><span style="font-family: 'Arial'; font-size: 12.000000pt">esting purposes only.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Miscellaneous built-in functions</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">function.get</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">function.get function</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Returns the program text of </span><span style="font-family: 'Courier'; font-size: 12.000000pt">function</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">string.equal</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">string.equal string1 string2</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Returns 1 if the two strings are the same, 0 otherwise.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">string.length</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">string.length string</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Returns the length of </span><span style="font-family: 'Courier'; font-size: 12.000000pt">string</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">range</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">usage: </span><span style="font-family: 'Courier'; font-size: 12.000000pt">range start end [step]</span></p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Returns a space-separated list of numbers between </span><span style="font-family: 'Courier'; font-size: 12.000000pt">start</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> and </span><span style="font-family: 'Courier'; font-size: 12.000000pt">end</span><span style="font-family: 'Arial'; font-size: 12.000000pt">.&nbsp; If a step size isn't specified, 1 is used.&nbsp; If end is less than start and a custom step size is specified, it must be negative.&nbsp; </span><span style="font-family: 'Courier'; font-size: 12.000000pt">step</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> cannot be 0 either.&nbsp; This command is best used with </span><span style="font-family: 'Courier'; font-size: 12.000000pt">for</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> loops.</span></p>
<p><br>
</p>
<p><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">Using </span><span style="font-weight: bold; font-family: 'Times New Roman'; font-size: 16.000000pt">GIB</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">GIB code should be p</span><span style="font-family: 'Arial'; font-size: 12.000000pt">laced in a file with the extension</span><span style="font-family: 'Arial'; font-size: 12.000000pt"> </span><span style="font-family: 'Arial'; font-size: 12.000000pt">.g</span><span style="font-family: 'Arial'; font-size: 12.000000pt">ib.&nbsp; </span><span style="font-family: 'Arial'; font-size: 12.000000pt">You can then load it like any other script with the exe</span><span style="font-family: 'Arial'; font-size: 12.000000pt">c command:</span></p>
<p><br>
</p>
<p><span style="font-family: 'Courier'; font-size: 12.000000pt">exec script.gib</span></p>
<p><br>
</p>
<p><span style="font-family: 'Arial'; font-size: 12.000000pt">Scripts ending in .gib will be placed in a new buffer on the execution stack set to use the GIB interpreter rather than the normal quake console interpreter.&nbsp; Note that all other scripts a</span><span style="font-family: 'Arial'; font-size: 12.000000pt">re simply copied into the current buffer.&nbsp; This means ANY script run from GIB will be considered a GIB script.&nbsp; Future versions of GIB will </span><span style="font-family: 'Arial'; font-size: 12.000000pt">allow you to force a command to be run </span><span style="font-family: 'Arial'; font-size: 12.000000pt">in a standard console buffer.</span></p>
</div>
</body>
</html>