skip to content
Frictional Game Wiki
User Tools
Register
Log In
Site Tools
Search
Tools
Show page
Old revisions
Backlinks
Recent Changes
Media Manager
Sitemap
Log In
Register
>
Recent Changes
Media Manager
Sitemap
Trace:
hpl2:tutorials:script:entihscript_beginner
<h1>Scripting Basics for Amnesia Mapping Beginners</h1> <div class="level1"> <p> So you want to map some stuff for Amnesia. Great! The world needs more custom Amnesia content. The first thing you will note when you try to pick up Amnesia and whip out really cool maps for it is one thing. The whole Amnesia map idea is intricately woven in script. Now some of you may know scripting, and the lucky of you even know the programming language this particular script is based on, C++. </p> <p> This tutorial is designed to give complete program and script newbies a crash course, and might be helpful to some others, too. </p> </div> <h2>Some Helpful Tips</h2> <div class="level2"> <p> Here are a set of tips for anyone who is going to try mapping and scripting for this game. First tip: Do not take this whole thing here as a first step! You're going to want to do some other things first. Grab the tools, <a href="/doku.php?id=hpl2:amnesia:devenvguide" class="wikilink1" title="hpl2:amnesia:devenvguide">set up a dev environment</a>, <a href="/doku.php?id=hpl2:amnesia:custom_story" class="wikilink1" title="hpl2:amnesia:custom_story">set up a custom story</a>, <a href="/doku.php?id=hpl2:tutorials:level_editor:tutorial_1" class="wikilink1" title="hpl2:tutorials:level_editor:tutorial_1">set up a small map</a>, you know, the usual pre-script things. These tips are, of course, based on personal experience, so may be entirely bunk in some cases. Take with a grain of salt. </p> <hr /> </div> <h3>Addendum To Dev Setup</h3> <div class="level3"> <p> If you're mapping for Amnesia, likelihood is that you are mapping under a custom story, in the custom story folder in the Amnesia directory. You followed the custom story setup and the dev environment setup word for word, and that means there's a few mixups. </p> <p> When you follow the dev environment setup word for word, it seems to cancel out the custom story effort. Loading something that you are working on in the custom story folder through the debug menu alone does not appear to load the custom story content, such as the extra language file and any entities in the custom stories folder. This forces you to work in the main game folders, and pack up everything you need when everything is complete. Or, you have to test frequently outside of dev mode. That is inefficient and prone to mistakes for me, so I found a quick fix for it, so the game will read the custom story content despite debug mode. </p> <p> Towards the start of the development environment setup, you set some things in main_settings.cfg, in your user settings directory (My Documents for us Windows folk – and ~/.frictionalgames/Amnesia/Main for us Linux folks <a href="/lib/exe/fetch.php?tok=daded5&media=http%3A%2F%2Fwiki.frictionalgames.com%2Flib%2Fplugins%2Ffckg%2Ffckeditor%2Feditor%2Fimages%2Fsmiley%2Fmsn%2Fwink_smile.gif" class="media" title="http://wiki.frictionalgames.com/lib/plugins/fckg/fckeditor/editor/images/smiley/msn/wink_smile.gif"><img src="/lib/exe/fetch.php?tok=daded5&media=http%3A%2F%2Fwiki.frictionalgames.com%2Flib%2Fplugins%2Ffckg%2Ffckeditor%2Feditor%2Fimages%2Fsmiley%2Fmsn%2Fwink_smile.gif" class="media" alt="" /></a>). Open that file up again. We need to make just one change, I have found, to make custom story content load perfectly fine. Right after the start, of the file, you have a setting called 'ShowMenu'. If it says 'ShowMenu="false"', change it to say 'ShowMenu="true"'. That's it. </p> <p> The main menu will pop up as if on a standard game. Pick the dev user profile, and check the custom story button. If your story is not in there, something went awry, but you caught it early. Check your story settings configuration file, and your language file, and make sure both don't have any issues. If your story is in there, you will load it up and be in debug mode, and all the custom story content will also load properly, so there is much less fidgeting amongst directories. </p> <p> I haven't found anything to show that this is a bad idea, but if it is, feel free to edit a note in about it. </p> <hr /> </div> <h3>Use Something Better than Notepad</h3> <div class="level3"> <p> This may sound like a silly suggestion, but trust me, it is worth it. When a map picks up in size and complexity, a script file can lead into having 800, 1000, maybe even up to 2000 lines of script. Even the most sane programmer in the world would quickly lose his mind trying to work out 1000 lines of code in standard notepad. </p> <p> The features of <a href="/doku.php?id=hpl2:third_party_tools:text:notepad" class="wikilink1" title="hpl2:third_party_tools:text:notepad">Notepad++</a> will literally save you sanity. In the least, download it, open your script files, and hit the 'Language' tab and set it to C++. It is worth the extra download. </p> <p> End of story. </p> <hr /> </div> <h3>Open the Map in Amnesia BEFORE you Edit Script!</h3> <div class="level3"> <p> There is one universal about scripting and programming. You will make mistakes. You WILL make mistakes. </p> <p> This tip makes it such that mistakes in scripting, rather than having the entire game come to its knees and crash, merely bark an error at you so you can fix it and try again really quick. The title of this tip? It says it all. If you change a script and it is wrong, two things can happen: </p> <p> One, you did not have Amnesia open on the map, and you try to load the map. You will get a popup error which complains of some specific form of issue, often semi-descriptive as to where you messed your script up. Hitting the 'OK' on that prompt closes Amnesia. Obviously, this will drive you insane if you have numerous errors, because no one likes repeatedly starting and shutting down the game. </p> <p> Two, you were in the map and made the change in script, and hit the 'Recompile Language and Script' button in the debug menu. It gives you a more polite little message with the same semi-descriptive issue as before. The difference here is this time, you can close that little message and stay right where you are, script away, and just hit the compile button again. Incredibly useful. </p> </div> <h2>Scripting Syntax for Beginners</h2> <div class="level2"> <p> This section focuses on the syntax and flow of the scripting, for those who don't want to break into learning C++ before trying to script for Amnesia. If you are skilled in scripting and/or programming, and especially if you know enough C++ to know how functions look and work under it, you can likely skip the rest of this tutorial. This is to give beginners a fighting chance of actually understanding what they are doing, and becoming self-sufficient at the craft. </p> <p> Lets jump right into this! Lets say you have a simple map already made… if you don't, head on back and check out the level editor tutorial, and whip up a nice small map, just a single room, and save it somewhere you can load it up easily in-game. Once you have that, open up your text editor of choice, and save a file in the same folder as your map, called "<YOURMAPNAMEHERE>.hps” (of course, without the quotes or <>'s. Make SURE that you don't save it as a 'text file', but that the file type saves as .hps). This is now a script file, and it is blank, and it does nothing. The following is what you might expect such an empty map's script file to look like, so feel free to copy and paste it in there: </p> </div> <h3>Basic Example File</h3> <div class="level3"> <pre class="code c++"> <span class="co1">//===========================================</span> <span class="co1">// Starter's Script File!</span> <span class="co1">//===========================================</span> <span class="co1">//===========================================</span> <span class="co1">// This runs when the map first starts</span> <span class="kw4">void</span> OnStart<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span>ScriptDebugOn<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> GiveItemFromFile<span class="br0">(</span>"lantern"<span class="sy0">,</span> "lantern.<span class="me1">ent"</span><span class="br0">)</span><span class="sy0">;</span> SetPlayerLampOil<span class="br0">(</span><span class="nu17">100.0f</span><span class="br0">)</span><span class="sy0">;</span> <span class="kw1">for</span><span class="br0">(</span><span class="kw4">int</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span>i <span class="sy0"><</span> <span class="nu0">10</span><span class="sy0">;</span>i<span class="sy0">++</span><span class="br0">)</span> <span class="br0">{</span> GiveItemFromFile<span class="br0">(</span>"tinderbox"<span class="sy0">,</span> "tinderbox.<span class="me1">ent"</span><span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="br0">}</span> <span class="co1">//===========================================</span> <span class="co1">// This runs when the player enters the map</span> <span class="kw4">void</span> OnEnter<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">}</span> <span class="co1">//===========================================</span> <span class="co1">// This runs when the player leaves the map</span> <span class="kw4">void</span> OnLeave<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">}</span> </pre><p> </p> <p> If you are new to scripting, you will likely catch wind of what some of that means, but other things be totally lost on. Lets take a look at it piece by piece. </p> </div> <h4>Comment</h4> <div class="level4"> <p> First thing I have there, with the slashes, is a comment. That is just there to be readable to you, the writer of the script. It is not needed, it doesn't perform a function, it is completely ignored by the game. </p> </div> <h4>OnStart</h4> <div class="level4"> <p> Going on down the line, we have 'void OnStart()' as the next meaningful line. This here is the 'definition' of a function, a special one. This one is called whenever the game sees the map and script file are first loaded. What shows us that it is a function? First, we have a data type, 'void', which basically is fancy program talk for 'nothing', or rather, 'when the function is used, don't expect anything back' (in programming C++, functions often return something, like a number; void does not do that). Next we have 'OnStart', which is just the name of the function, so nothing fancy there. Then we have '()', which is the argument list. There is nothing in it, because OnStart doesn't need anything! I'll outline that in a bit. </p> </div> <h4>{ and }</h4> <div class="level4"> <p> Most importantly, we then have the opening bracket, {. If you look down below, lined up with it by indent is a paired }. Whenever OnStart is called, it skips right there to the opening bracket, and does every single line in it from top to bottom, until it hits that closing bracket! That is important to know. If you have something sitting out on its own in the script file, not in any bracket pair and doesn't have its own bracket pair, it likely does nothing whatsoever. </p> </div> <h4>The if</h4> <div class="level4"> <p> Next we have an 'if'. This is just as it sounds! The if statement there has its own bracket pair, just like OnStart. If the condition in the parentheses for the if is true (like, if you have 'if(5 == 5)', which will always be true), it will do all the stuff in the brackets, top to bottom. If it is NOT true (say, you try (5 == 4)), it will do none of it, and will just skip to the if's end bracket and be on its merry way. In our case, we are checking if we are in debug mode, which we likely are. Notice in my comparisons there between 5 and whatever, I use two 'equals' signs! That is because one would not work, it would try to actually set 5 to 4, which is a bit impossible. You'll get an error if you use just one in an if! </p> <p> Valid comparison operators are: </p> <pre class="code"> == Equal to <Less than > Greater than //= Less than/Greater than or equal to != Not equal to && And || Or ! Not </pre><p> </p> <p> The 'And' and 'Or' are a way to combine requirements. && Compares two checks, and if they are both true, it says true. If one is true but the other is not, or if both are not true, it says not true. || Compares two checks as well. If ANY of the two are true, it says true, otherwise it says false. </p> <p> The 'Not' is a special case. When put before a boolean (true/false), it signifies the opposite. </p> <pre class="code c++"> <span class="co1">// This is an if with an and. 5 == 5, so that would be true. 5 is NOT equal to 4, so that would be false.</span> <span class="co1">// Due to the 'and', that means the if would not run.</span> <span class="kw1">if</span><span class="br0">(</span><span class="br0">(</span><span class="nu0">5</span> <span class="sy0">==</span> <span class="nu0">5</span><span class="br0">)</span> <span class="sy0">&&</span> <span class="br0">(</span><span class="nu0">5</span> <span class="sy0">==</span> <span class="nu0">4</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">}</span> <span class="co1">// This is the same if with an or. It, in turn, would run, because one of the two are true</span> <span class="kw1">if</span><span class="br0">(</span><span class="br0">(</span><span class="nu0">5</span> <span class="sy0">==</span> <span class="nu0">5</span><span class="br0">)</span> <span class="sy0">||</span> <span class="br0">(</span><span class="nu0">5</span> <span class="sy0">==</span> <span class="nu0">4</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">}</span> <span class="co1">// Now this is that and with a NOT! since 5 is not equal to 4, it comes up false. The Not sees that and makes</span> <span class="co1">// it return as true for the if statement, meaning both are true for the And, and it will run.</span> <span class="co1">// Do note that I could have just used the Not Equal To, !=, but I wanted to show the not alone, as it can</span> <span class="co1">// be useful for functions which return a true or false, like ScriptDebugOn()</span> <span class="co1">// (Say you have a scripted intro to your map that you don't want playing every time you load up in debug,</span> <span class="co1">// you can simply put it in an if with the condition if(!ScriptDebugOn()).)</span> <span class="kw1">if</span><span class="br0">(</span><span class="br0">(</span><span class="nu0">5</span> <span class="sy0">==</span> <span class="nu0">5</span><span class="br0">)</span> <span class="sy0">&&</span> <span class="sy0">!</span><span class="br0">(</span><span class="nu0">5</span> <span class="sy0">==</span> <span class="nu0">4</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">}</span> </pre><p> </p> </div> <h4>Functions in Play</h4> <div class="level4"> <p> This is what a function looks like when it is being called, and not being defined. There is a whole page of <a href="/doku.php?id=hpl2:amnesia:script_functions" class="wikilink1" title="hpl2:amnesia:script_functions">VITAL scripting functions for Amnesia</a> that I advise you to bookmark if you will be scripting often. If you find the script we use here on that page, 'GiveItemFromFile', you see that unlike OnStart, it takes two arguments, which are separated by comma, the name of the item you are giving, and the entity file of that item. In this case, its the lantern. The next line is a function which sets how much oil the player has, in percent form… in this case i put '100.0f'. The 'f' at the end was because I gave it in float form (floating point… that is, it has a decimal). </p> <p> Important to note is that, when calling a function to actually perform like this here, you fill out the variables you are shown on the script definition (everything on that vital functions page). If the script definition has a 'string' which is called 'EntityName', assume it means the entity you want to affect with the function, for example. </p> <p> Very important to note, whenever you have a separate line in script like this, semicolons must be used! The semicolon basically says 'this line has ended'. </p> </div> <h4>The 'for' loop</h4> <div class="level4"> <p> This next part is not something that comes up in Amnesia scripting often, but knowing it can make things incredibly convenient for you. For example, in my starting script there, I wanted to give the player 10 tinderboxes, just in case they want to run around joyously lighting up all the torches in debug mode like they are celebrating Christmas. Now I could write the give item function 10 times in a row to do this, or I could use a loop. </p> <p> 'for' is one type of loop, useful for things like this here, because it takes a variable and keeps track of it, uses it in a comparison, and then changes it. After the 'for' is the set of arguments, which tells us how to do those 3 things. It thus takes 3, separated by semicolons. The first sets up the variable we will use to count, in this case I create an int (integer/whole number) named i, and start it out at 0. </p> <p> The second tells us what criteria to continue the loop under. In this case, as long as i is less than 10, we keep going. </p> <p> The third tells us what to do with i whenever the loop finishes an iteration. In our situation, it says i++, meaning 'add 1 to i'. </p> <p> The loop will perform whatever is in its brackets for as long as that second portion is true. Every time it hits the closing bracket, it goes to the third argument and does that. If you follow the loop in your mind, it will go from 0 to 9, meaning it will give the player 10 tinderboxes. When i is equal to 10, it is of course no longer less than 10, and the loop does not go again. </p> </div> <h4>Data Types</h4> <div class="level4"> <p> I am adding this session in here for much needed clarification. If you look at the list of Amnesia script functions, you'll see that they take all sorts of types. Here I will clarify what those mean. When a function on that list has an argument like that, what that means is when you call the function to run it, you put an appropriate value in for it, like how we put "lantern" in for GiveItemFromFile, or 100.0f in the oil function below. </p> <pre class="code c++"> <span class="kw4">int</span> <span class="co1">//(Integer, or whole number. Examples include -1023, 0, 6)</span> <span class="kw4">float</span> <span class="co1">//(Floating point, or decimal number. -16.235f, 0.0f, 7.2f, 5.0f)</span> string <span class="co1">//(String. Basically, a 'string' of letters and numbers. Often used as entity names</span> <span class="co1">// like "mansion_door_1". Pretty much always in double quotes.)</span> bool <span class="co1">//(Boolean value. true or false.)</span> </pre><p> </p> </div> <h4>Syntax Conclusion</h4> <div class="level4"> <p> Those are the basics you need to know about syntax to really understand what is going on, and if you are good with this kind of stuff, you blew through that entirely with a mindset of 'makes sense' or 'too simple…'. If you're not good with this stuff, and still find yourself confused, best thing to do is open Amnesia and toy around with the scripting, see what happens. Another ideal thing is to open up an actual map in Amnesia and see what the scripting is like! </p> <p> And remember, just like I have the script here, indenting will save you mind power in figuring out! You'll see what belongs to what more easily, and you will be able to follow the script more easily. So remember, use that tab key! </p> </div> <h2>Amnesia Scripting</h2> <div class="level2"> <p> I am unfortunately not going to cover this here, because there are a good number of other tutorials already on here which cover that! I will just outline a few very important functions. </p> <p> If you did read the syntax blurb up there, you know that anything that is to be done must be in a function of some sort. The trick with scripting is knowing how to work these chunks of scripts together such that they flow. </p> <p> Note that when functions are defined, the parameters remain a data type. When you are writing out the 'void Function(…){…}', whatever is in parentheses should remain a variable, depending on what it needs, such as 'string &in asEntity'. If you're not sure what it needs and you didn't produce the function yourself, seek out if you can find more information on the function (Amnesia default maps are always a good resort to checking script). </p> </div> <h4>Interacts</h4> <div class="level4"> <p> So you want something to happen when you try to interact with an object, such as a door. In the level editor, most interactive objects have an option in entity settings for a player interact callback. Just put a function name in there, and it is then a valid function to use in script! </p> <p> It looks like this in there (note, this is not a functional example, just showing what the function looks like): </p> <pre class="code c++"> <span class="co1">// asEntity becomes the name of the entity which referenced it, simple as that.</span> <span class="co1">// When the variable is referenced in an interact function called by a door named</span> <span class="co1">// "door", asEntity would literally read out as a string saying "door"</span> <span class="kw4">void</span> FunctionNameHere<span class="br0">(</span>string <span class="sy0">&</span>in asEntity<span class="br0">)</span> <span class="br0">{</span> <span class="br0">[</span>STUFF YOU WANT DONE GOES IN HERE<span class="br0">]</span> <span class="br0">}</span> </pre><p> </p> <p> Easy as that, that is run when the player tries to 'use' the entity. The argument 'asEntity' becomes the name of the object used. </p> </div> <h4>Collides</h4> <div class="level4"> <p> So you want something to happen when the player unwittingly comes into contact with something, be it an object or an invisible, intangible area. For this, you can't just set it up in the editor. You need to 'add' the collide callback in another function, such as OnStart. </p> <p> (Same as before, but showing the necessary adding of the callback) </p> <pre class="code c++"> <span class="kw4">void</span> OnStart<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// Creates a collide check for if player enters 'ScriptArea1', that runs the function 'Collide_Area'.</span> <span class="co1">// It deletes the callback when it is run, and only checks for if the player enters the area.</span> AddEntityCollideCallback<span class="br0">(</span>"Player"<span class="sy0">,</span> "ScriptArea1"<span class="sy0">,</span> "Collide_Area"<span class="sy0">,</span> <span class="kw2">true</span><span class="sy0">,</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="co1">// The actual function. asParent becomes the 'parent' of the added callback ("Player"),</span> <span class="co1">// asChild becomes the 'Child' ("ScriptArea1"), alState becomes the state (1 if player entered,</span> <span class="co1">// or -1 if player exited. Can only be 1 in this case). This all happens when the script actually</span> <span class="co1">// runs in-game, do NOT do it in script itself! You can, however, reference the variables asParent,</span> <span class="co1">// asChild, and alState in the function itself, and they will work, though.</span> <span class="co1">// This is important to note because, yes, more than one callback can point to the same function!</span> <span class="co1">// That can be used as a method of differentiating them.</span> <span class="kw4">void</span> Collide_Area<span class="br0">(</span>string <span class="sy0">&</span>in asParent<span class="sy0">,</span> string <span class="sy0">&</span>in asChild<span class="sy0">,</span> <span class="kw4">int</span> alState<span class="br0">)</span> <span class="br0">{</span> <span class="br0">[</span>STUFF YOU WANT DONE HERE...<span class="br0">]</span> <span class="br0">}</span> </pre><p> </p> </div> <h4>Timers</h4> <div class="level4"> <p> Here I will cover timers, which allow you to time out events and occurrences, and if you think hard enough, even allow you to create a timed version of the for loop! If you have done any video game mapping and modding before, you know that it is true that timers rule the world. </p> <p> A timer is called in a function, like any other (as with the past three): </p> <pre class="code c++"> <span class="kw4">void</span> OnStart<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// Creates a timer. The timer is named "Test", triggers 5 seconds after map starts, and runs the function "Timer_Trigger"</span> AddTimer<span class="br0">(</span>"Test"<span class="sy0">,</span> <span class="nu17">5.0f</span><span class="sy0">,</span> "Timer_Trigger"<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="co1">// asTimer becomes timer name. In this case, if you would reference</span> <span class="co1">// asTimer in the below function, it would contain the string "Test".</span> <span class="co1">// This means you could do something like "if(asTimer == "Test")", and</span> <span class="co1">// have multiple timers pointing to the SAME function, but doing wildly</span> <span class="co1">// different things.</span> <span class="kw4">void</span> Timer_Trigger<span class="br0">(</span>string <span class="sy0">&</span>in asTimer<span class="br0">)</span> <span class="br0">{</span> <span class="br0">[</span>PUT STUFF HERE TO DO...<span class="br0">]</span> <span class="br0">}</span> </pre><p> </p> </div> <h4>Local Variables</h4> <div class="level4"> <p> One thing you may notice is that, to do some neat stuff, you need more than just your basic variables and such. You need some way for them to communicate. If you have a timer triggering, triggering itself again repeatedly for 10 seconds, how do you tell it to not trigger itself again after that 10 seconds? This is what I implied by 'timed version of the for loop', by the way. </p> <p> The local variables are called as simply as the following: </p> <pre class="code"> SetLocalVar//("//", //); // can be Int, Float, or String // can be... anything // depends on //. Int can be any whole number, Float any decimal number, String, anything between quotes That set takes the local variable of the given name, and makes it the value. If there is no set to a given variable before use, it will default to 0, 0.0f, or "" (presumably, have not tried strings) AddLocalVar//("//", //); All is same as before, except this time we are not setting the variable to the value, but adding the value to what is already there. GetLocalVar//("//"); This returns whatever is in the variable. </pre><p> </p> <p> For example, we can have this, which gives the player 10 tinderboxes over 10 seconds. This is the only example of this section which is functional, because its harder to understand something like this in description only. </p> <pre class="code c++"> <span class="kw4">void</span> OnStart<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// Adds a timer to start us off. Triggers in one hundredth of a second... or 'really really quick, you don't even know!'</span> AddTimer<span class="br0">(</span>""<span class="sy0">,</span> <span class="nu17">0.01f</span><span class="sy0">,</span> "Amazing_Delayed_Tinderboxes"<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="kw4">void</span> Amazing_Delayed_Tinderboxes<span class="br0">(</span>string <span class="sy0">&</span>in asTimer<span class="br0">)</span> <span class="br0">{</span> <span class="co1">// If the local variable 'TinderCount' is less than 10...</span> <span class="kw1">if</span><span class="br0">(</span>GetLocalVarInt<span class="br0">(</span>"TinderCount"<span class="br0">)</span> <span class="sy0"><</span> <span class="nu0">10</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// Give a tinderbox. Add 1 to the count.</span> GiveItemFromFile<span class="br0">(</span>"tinderbox"<span class="sy0">,</span> "tinderbox.<span class="me1">ent"</span><span class="br0">)</span><span class="sy0">;</span> AddLocalVarInt<span class="br0">(</span>"TinderCount"<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">// Do it all again!</span> AddTimer<span class="br0">(</span>""<span class="sy0">,</span> <span class="nu17">1.0f</span><span class="sy0">,</span> "Amazing_Delayed_Tinderboxes"<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> </pre><p> </p> </div>
hpl2/tutorials/script/entihscript_beginner.txt
· Last modified: 2011/01/01 00:59 by
gbutler69
Page Tools
Show page
Old revisions
Backlinks
Export to PDF
Back to top