Table of Contents
The Public Scripts package is a collection of scripts modules for Dark Engine™ based games. These modules collect a number of well-known scripts into a single place. So fan-mission designers have greater freedom to create novel and entertaining experiences.
This manual is divided into three parts.
Installation: | If you just need Public Scripts in order to play a fan-mission, this is the only section you need to read. |
---|---|
DromEd Reference: | Designers will find descriptions of the scripts here; and instructions on how to use them. |
Programmer’s Reference: | This section describes the source code to Public Scripts for anyone who wants to make their own custom scripts. |
Public Scripts are copyright © 2005-2007 Tom N Harris.
This software is released under the terms of the GNU General Public License.
Unmodified copies of the compiled binary files may be distributed along with fan-missions and expansion packs intended for use with Dark Engine™ based games without the creator being required to provide the source code for this software. The fan-mission or expansion pack must completely comply with the terms of the Dromed License issued by Eidos Interactive, and the fan-mission or expansion pack must include the following copyright information:
This fan-mission uses Public Scripts. Copyright © 2007 Tom N Harris This software is licensed under terms of the GNU General Public License. Please see http://www.thiefmissions.com/telliamed/#PublicScripts for more information, or write to [insert your email address here].
You must then be prepared to answer any queries regarding the scripts, which may include offering copies of the original software package in case the official website is inaccessible.
Third-party distributors must include the complete Public Scripts package in their archive if they distribute any fan-missions or expansion packs that use this software.
The first step to using a custom script module is to copy the appropriate files to a place where the game can find them. The Public Scripts package uses three files: script.osm, version.osm, and dh2.osl. But the first file, script.osm must match the game it is being installed for. A script module from Thief Gold can’t be used in System Shock 2. (Although there are exceptions, like version.osm.)
The simplest way to copy the right files is to run the included Setup.exe program. This is an automated installer that will copy the right files to the right places. If you already have a copy of Public Scripts installed, the older files will be backed-up to a zip-format archive with a name like _Restore-20060201.zip, although the numbers will be different. If there is a problem, you can restore the old files from the backup archive.
The main Public Scripts script module is named script.osm. This is the same name as an older script module distributed as “Gaylesaver’s Custom Scripts”. The reason the names are the same is because Public Scripts includes scripts that do the same thing as the “Gaylesaver” scripts. These are not merely copies, but completely new scripts made to be compatible, but with less problems than the originals. The “Gaylesaver” scripts are no longer being updated, so I am providing Public Scripts as an improved alternative.
You cannot have both Public Scripts and the “Gaylesaver” scripts installed at the same time. When you install Public Scripts, the old script.osm will be overwritten. The old file darkhooks.dlx is not removed, however. This is harmless, but if you have no intention of ever using the “Gaylesaver” scripts again, then you probably want to delete it.
This section is for fan-mission authors.
You are free to include copies of script.osm and dh2.osl with your fan-mission, provided that you follow all the rules. But do you really want to? Scripts are computer code, and some people may rightfully be concerned about letting any random computer program they download be run on their computer. There is also the possibility that there may be a bug in this particular version of Public Scripts. (And a very good possibility at that, it annoys me to say.) So do you really want to have to release a new copy of your FM every time I discover some new problem with the scripts; or worse, leave an old buggy copy floating around?
The more reasonable solution is to ask the end-users to download the scripts themselves. They can be more confident that the scripts are safe, and upgrade whenever the need arises. To make this practical, though, you need a way to notify the user when the scripts have not been installed. The script VersionCheck is what makes this possible. This script is placed into a separate module named version.osm, and it is this file that you include with your FM. The same file can be used in Thief 1, Thief 2, and System Shock 2.
The VersionCheck script is intended to be used as a trigger. If the required scripts are found, it will send a , or it will send otherwise. Specify the script modules to look for in the Editor\Design Note or, in System Shock 2, Script\Objlist. The property is a list of file names separated with semi-colons (;
). If a file doesn’t have an extension, then .osm will be added. The script will fail if any of the files can’t be found in the game directory. The version of a file can be checked by typing a ‘=
’ followed by the minimum version number. The script will fail if the version of the file is lower than specified. The following example tests if script.osm is present, and if tnhscript.osm is at least version 1.5.
script.osm;tnhscript=1.5
VersionCheck can also display a message if the scripts aren’t found. In Thief, it uses the Book\Text and Book\Art properties. It’s just like any other book. In System Shock 2, the property Script\Use Message is used. The property value is the name of a string that will be read from the file strings\error.str.
Some of the scripts need an external library called Dark Hook 2. This is provided by the file dh2.osl. If the file isn’t found then the script won’t operate. However, other scripts that don’t require Dark Hook 2 will still work.
Before using any scripts, you must load the appropriate modules into each mission. You’re probably already familiar with doing this for gen.osm, convict.osm, or allobjs.osm. A custom script is just one more module that needs to be loaded. DromEd lets you load as many script modules as you want.
Type the DromEd command: script_load and the name of a script module to load it. The .osm extension isn’t necessary. When DromEd needs a script, it will search each loaded module beginning with the most recently loaded. You can print the list of loaded modules to the monolog with the command script_dump_files.
Scripts are attached to an object with the Scripts property. You can put the names of four scripts in each property, but DromEd will combine all the Scripts properties from all of the ancestors of an object. This is different than other properties where each object will override the properties that come before it. When you need to override an inherited script property, you set the Don’t Inherit flag on the Scripts property.
Scripts also inherit features of base scripts, so many scripts can have similar behaviors. This inheritance is built-in to the scripts and doesn’t require you to do anything in DromEd. The inheritance described in this manual refers to this, not the object hierarchy. Some of the base scripts are also described separately, to make the manual easier to read.
The more you use scripts, the more you need to know about what is going on behind the scenes. This becomes most obvious when the game isn’t working as you expected it to. DromEd provides some commands to aid in the debugging of scripts. To view the debug information, you need to have a monolog enabled. The monolog is a text file that records messages from the DromEd, the game, and some scripts.
There are two ways to enable a monolog. You could tell DromEd to automatically open it at startup. Edit your dromed.cfg or user.cfg configuration file. (I prefer to use dromed.cfg for editor-only options.) Add on a new line the option monolog and the name of the file you want to create. The disadvantage with automatically opening the monolog is that the previous contents of the file will be erased each time you start DromEd. Instead, you can manually open the monolog every time you need it. After starting DromEd, type the command mlog and the name of the file. If you type mlog close, then the monolog is closed. Opening a monolog with a different name will close the previous file.
With the monolog open, you can use DromEd’s built-in script debugging commands. These are called trace lines. A trace monitors the messages sent to a particular object. You create a trace with the trace_add command. The command takes four arguments, the object to monitor, the message to trace, the word “spew
”, then a trace line number. A trace line is a group of traces so you can toggle many traces on and off together. There are 32 trace lines. A line is toggled with the trace_line command. The “spew
” argument tells DromEd to write the message to the monolog. The word “break
” could also be used, but this is only useful for script programmers with a symbolic debugger installed.
Trace lines just tell you when an object receives a certain message. Many messages contain extra information that you may want to know about. Public Scripts includes a script for this purpose. Add the script Spy to any object and it’ll record every message that the object receives in the monolog, along with the extra information from the message.
Many custom scripts need extra information to function. They may use an already existing property, but most often there isn’t anything suitable. So a special string property is used to give options to the scripts. In Thief this is the Editor\Design Note, and in System Shock 2 it is the Script\Objlist. This will be referred to as the “design note” from now on.
The design note consists of a list of parameter names and values separated with semi-colons (‘;
’). Parameter names do not contain spaces and are not case-sensitive. The parameter name is followed by ‘=
’ then the value. Any space before or after the value will be ignored. The value can be enclosed in single or double-quote marks, which must be done if you need to use a quote mark or semi-colon in the value. The value may be interpreted as an integer, floating-point number, string, boolean, time, or object.
Integer: | A whole number, positive or negative. |
---|---|
Floating-Point: | A positive or negative number with optional fractional part. Use a period (‘. ’) to separate the whole and fractional parts. |
String: | Any kind of text. |
Boolean: | A true or false value. The words ‘true ’ or ‘yes ’, or a non-zero number will be considered true. You can also shorten the word to a single letter, i.e. ‘T ’ for true and ‘F ’ for false. |
Time: | As a number by itself, it’s milliseconds. Put the letter ‘s ’ after the number for seconds, and ‘m ’ for minutes. |
Object: | A DromEd object. Can be the numeric ID, or the name of the object. |
Color: | Color values can be written in HTML format, which is a hash mark (‘# ’) followed by six hexadecimal numbers. The English color names described in HTML 4 are also recognized. Another way to specify a color is the red, blue, and green components (in that order) separated with commas. |
Where an integer, boolean, or time is requested, you can substitute the name of a quest variable for the value. Type a dollar sign (‘$
’) followed by the name of the qvar.
Many of the scripts are types of “traps”. (The terms “relay”, “router”, “filter”, and “trigger” are also sometimes used, but they all amount to the same thing.) The purpose of a trap is to respond to, or generate,
and messages. Some traps both respond to and generate messages. And sometimes one or the other message will be ignored.Traps are usually linked together using ControlDevice links. System Shock 2 uses SwitchLink links instead, but this manual will only refer to ControlDevice; you’ll just have to mentally translate for SS2.
The behavior of a trap can be altered with the Script\Trap Control Flags property. The Invert flag will reverse the normal meanings of and . Once causes the trap to be locked after it has been activated. The NoOn and NoOff flags make the trap ignore the respective messages. (Prior to reversing by Invert.) In System Shock 2, Enter means NoOff and Exit means NoOn.
Thief 1 doesn’t have the Script\Trap Control Flags, so a design note parameter is used instead. The parameter name is tcf and it is specified as a string of two-character symbols. The flags are:
!+ : | NoOn |
---|---|
!- : | NoOff |
<> : | Invert |
01 : | Once |
When a trap is locked, it will ignore all messages. A trap that has been turned on will automatically turn off if the Script\Timing (Thief) or Script\Delay Time (SS2) is set. The time is in milliseconds for Thief and seconds (with fractional part) for SS2. The timer is not used when a trap is turned off.
In the Thief games, it is possible to link to the Player object. Create the link to the starting-point marker and when the game starts, those links will be moved to the Player marker. This even applies to some non-trap scripts.
Compatible Scripts: | These are scripts that appeared in an older custom script module. |
---|---|
Common Scripts: | These scripts are useful in all games. |
Thief 1 Scripts: | Scripts for Thief: The Dark Project and Thief Gold. |
Thief 2 Scripts: | Scripts for Thief 2: The Metal Age. |
SS2 Scripts: | Scripts for System Shock 2. |
These are scripts that appeared in an older custom script module. Missions that already use the older version should be able to upgrade simply by changing the OSM file.
Allows an AI to transfer an item from it’s inventory to another object.
Script: | AIItemGiver |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | Contains |
This script is intended to be used from a pseudo-script; usually a conversation. Place the script on an AI in the conversation that Contains some object. Use the Script message command to send the message to the actor. The other two arguments are the destination (MsgData1) and the object to transfer (MsgData2). The item will then be removed from the AI’s inventory and put in the inventory of the destination. Objects that combine, even loot, will transfer properly.
Relays specific messages to other objects.
Script: | Forwarder |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(message) |
This is a generic relay and filter that works with any message. Instead of the usual ControlDevice or SwitchLink links, it uses ScriptParams where the data of the link is the name of the message that will be relayed. You can have any number of links with different data. The length of the ScriptParams data field is only 15 characters, though. You can get around this redirecting the script to read the message name from an object property. For the link data, type the character ‘#
’ then the name or ID of an object. On that object, add a design note and set it to the name of the message to be relayed. The entire design note will be read, so you can’t be using it for any other parameter.
Display text when focused.
Script: | IntrinsicCover |
---|---|
Inherits: | IntrinsicText |
Messages: |
A variation of IntrinsicText that displays the text when it receives .
Display text when frobbed.
Script: | IntrinsicPlaque |
---|---|
Inherits: | IntrinsicText |
Messages: |
A variation of IntrinsicText that displays the text when it receives .
Display colored text.
Script: | IntrinsicText |
---|---|
Inherits: | BaseTrap |
Parameters: | text(string), clr(color), clr_red(integer), clr_green(integer), clr_blue(integer), time(time) |
Properties: | Book\Text |
IntrinsicText displays text on-screen when triggered. If the Book\Text property exists, then it is used as the name of a string file to read. Without a book file, the text to display can be written in the design note. Using a book allows you to display translatable text; but the design note doesn’t require you to create a custom resource.
When reading the text from the design note, the text parameter will be used if it exists. Otherwise, the entire design note is shown. You must use text if you want other parameters.
The clr parameter will change the color of the text in Thief. Alternately, the three parameters clr_red, clr_green, and clr_blue can be used. On-screen text color can’t be changed in System Shock 2. The length of time the text is shown is determined by the number of words. You can specify an duration with the time parameter. The time and clr parameters can be used with either Book\Text or the text parameter.
Play a schema when frobbed.
Script: | InvSchema |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | SoundDescription |
Properties: | Sound\Object Sound |
When the object is frobbed in the inventory, a specified schema will be played. If the frobber is the Player, the schema will be played as an ambient, otherwise it is played normally at the location of the frobber.
Thief: Create a SoundDescription link to the schema. The link can be from an archetype of the script object as well.
SS2: Set the schema name in the Sound\Object Sound property.
Move links from one object to another, including data.
Script: | LinkTemplate |
---|---|
Inherits: | BaseTrap |
Parameters: | object(object), dest(object), flavor(string), on_create(boolean), off_destroy(boolean), singleton(boolean) |
This trap will add links to another object when turned on, and remove them when turned off. It is a template because the links are originally created anchored to the script object. That way, the link data can be set appropriately.
The object parameter is required and specifies the object that will become the new source of the links. If dest is specified, then only links to that object will be moved. Flavor will only move those types of links. If it isn’t specified, then all links except reverse trigger links will be moved.
On object object in place of the script object. The link that was on the script object will then be deleted. If on_create is set, then the old links are not removed. On , valid links with object as the endpoint will be removed, and re-linked to the script object. If off_destroy is set, then the links are not re-linked. Note that it’s possible that the links removed from object could be different than the ones originally copied to it. For instance, if you just add one Contains link on , then will move all the Contains links including those not added by LinkTemplate. Using a specific dest will usually avoid unexpected side-effects.
, a copy of each valid link will be created with theSome links, such as AIAwareness, only work right if there is just one link between any two objects. Otherwise you’ll get an error that says “Singleton link expected
”. You can instruct LinkTemplate to avoid duplicate links by setting the singleton flag.
Adjust the object’s physics to match its true size.
Script: | PhysModelCorrect |
---|---|
Inherits: | BaseScript |
Messages: | , |
Properties: | Physics\Model\Dimensions, Shape\Scale |
Normally, resizing an object in DromEd does not alter the physical size of the object. You could manually adjust each resized object, or you could save time and just add this script. When the game starts, this script evaluates the Shape\Scale of the object and its archetype to determine the true size of the object. The Physics\Model\Dimensions property is then set accordingly. This works for Sphere and SphereHat objects as well as OBBs.
The dimensions can be readjusted at any time by sending
to the object.Trigger a randomly selected object.
Script: | RandomRelay |
---|---|
Inherits: | BaseTrap |
Links: | ControlDevice, SwitchLink, ScriptParams(weight) |
Parameters: | reusable(boolean), rechargeable(boolean), preserve(boolean), weighted(boolean) |
A RandomRelay relays a or message to a randomly selected destination. The simplest mode is un-weighted and uses standard trigger links. After the relay has been used, it will lock itself. Essentially, this trap has the Once trap control flag on by default. You must set reusable to use the relay more than once. But each destination will only be triggered once, and the link to the destination removed. To keep the links intact, set preserve.
RandomRelay can also work with weighted destinations. Destinations with higher weights, relative to the other destinations, are more likely to be chosen. The destinations are linked to with ScriptParams and the data of the links are set to the weight for that destination. Reusable and preserve also apply to weighted relays. Additionally, the relay can be rechargeable, which implies preserve. A rechargeable relay will disable a destination after it is used, but maintains the link. When all links have been used, the relay is reset and it can send to previous destinations again.
This script is also named RandomRelay1x2. There is no difference.
An object that can be used a fixed number of times.
Script: | Sippable |
---|---|
Inherits: | BaseScript |
Messages: | , |
Properties: | Inventory\Object Name, Obj\Object name |
Parameters: | sips(integer) |
A Sippable object display a usage count as part of its inventory name. When it is frobbed in the inventory, the count is reduced by one and, if there are no more uses left, the object is destroyed. The inventory name of the object is set as usual, in the Inventory\Object Name or Obj\Object name property. In the string resource, include the sub-string “%d
” in the name. That sub-string will be replaced with the number of uses.
Magic Potion\n %d sips left
If the string resource doesn’t exist, or there is no “%d
” in the name, then a fallback, but untranslatable, method is used. The number of uses plus the words “sips left
” will be added to the end of the object name.
Display all messages received by the object.
Script: | Spy |
---|
This is a debugging aid. It shows every message that is received by an object. The messages are shown on-screen as well as coped to the monolog. Much of the additional data that accompanies messages is also displayed. Using Spy can help you make sense of the complex interactions of objects. Or it’ll just confuse you way more than you already are.
Periodically stimulate linked objects.
Script: | TimedStimulator |
---|---|
Inherits: | TrapStim |
Links: | ScriptParams(interval) |
Parameters: | interval(time), stage(integer), device(boolean) |
...
Script: | ToolMP |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | ScriptParams(S...), ScriptParams([AR]@...), ScriptParams(MeantDest) |
Schemas: | “Event Activate ” |
Parameters: | effect(string) |
Adjust the hitpoints of an object.
Script: | TrapHP |
---|---|
Inherits: | BaseTrap |
Properties: | Game\Damage Model\Hit Points |
Parameters: | hitcount(integer), target(object), culprit(object), damage(object) |
Heals the target by hitcount points, which defaults to 1. Turning the trap off will damage the target by hitcount points. Hitcount can be negative, which would have the same effect as a positive value with the trap control flag Invert set. The source of the stim is the script object by default, you can change it with culprit. Damage sets the type of the stim.
Add or remove meta-properties.
Script: | TrapMetaProp |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(S...), ScriptParams([AR]@...) |
This script will add or remove metaproperties on linked objects. Either operation can be performed when the trap is activated. First create a ScriptParams link to each metaproperty you want to add or remove. Set the data of each link to “S
” followed by some key, such as a number or name. Each key should be different. Next create ScriptParams links to the objects you want to modify. Set the data of each link to either “A@
” or “R@
” followed by the key from one of the metaproperty links. When turned on, the objects with an “A@
” link will have the referenced metaproperty added, and those with “R@
” will have the metaproperty removed. Turning off the trap will do the opposite for each link.
Gradually fade in/out.
Script: | TrapPhantom |
---|---|
Inherits: | BaseTrap |
Links: | ControlDevice |
Properties: | Renderer\Transparency (alpha) |
Parameters: | alpha_min(float), alpha_max(float), rate(float), fade_time(time), curve(integer) |
This script will manipulate the transparency of the object it’s on. When turned on, the object will become more visible, up to the value of alpha_max. Turning it off will make it transparent, stopping at alpha_min. The speed of the change can be set with either the fade_time or rate parameters. If fade_time is set, then it is the duration of the fade. Otherwise, the rate parameter is the change in the transparency level every second. When the object becomes fully visible, a is relayed along trigger links. is relayed when it becomes invisible.
The curve parameter, which didn’t appear in the original version of this script, allows you to tweak the equation used to calculate the transparency. The transition is linear by default, which is a curve value of 0. The other equations are:
1: | x2 |
---|---|
2: | √x |
3: | log x |
4: | 10x |
5: | ln x |
6: | ex |
Convert
to any other message.Script: | TrapScrMsgRelay |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(message) |
Parameters: | status_index(integer), data(string), data1(string), data2(string), data3(string) |
Stimulate linked objects.
Script: | TrapStim |
---|---|
Inherits: | BaseTrap |
Links: | ControlDevice |
Stimuli: | ScriptStim |
Parameters: | stim(object), intensity(integer) |
Teleport an object maintaining relative position to a pair of reference objects.
Script: | TrapTeleportDelta |
---|---|
Inherits: | BaseTrap |
Links: | ControlDevice, ScriptParams(dm) |
Trigger when an AI becomes aware of an object.
Script: | TrigAIAwareShift |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | AIAwareness, ScriptParams(af...), ScriptParams(av...), ScriptParams(aa...) |
Send
when an object is picked up.Script: | TrigBodyPickup |
---|---|
Inherits: | BaseScript |
Messages: | , , |
Links: | ControlDevice |
Trigger the object that causes damage.
Script: | TrigDamageRTC |
---|---|
Inherits: | BaseScript |
Messages: | , |
Trigger when certain types of objects enter a bounding-box.
Script: | TrigOBBSpec |
---|---|
Inherits: | BaseTrap |
Messages: | , , |
Links: | ScriptParams(arc), ScriptParams(cd), Population |
Metaproperties: |
These scripts are useful in all games.
Common actions to be taken after a book is read.
Script: | PostReadPlaque |
---|---|
Inherits: | BaseTrap |
Links: | SoundDescription, ControlDevice, SwitchLink |
Properties: | Book\Text, Book\Art, Script\Use Message, Trap\Quest Var, Script\QBName, Script\Timing, Script\Delay Time, Sound\Object Sound |
This is an abstract script for when an action should be taken after a book has been read. The advantage over traditional triggering methods is that the actions will always occur after the book-mode screen has been shown. This script can’t be used directly; use either PostReadPlaque or PostReadScroll instead.
The script can play a voice-over schema and set a quest variable. If both actions are being used, then the quest variable is changed after the schema plays. Specify the schema to play by creating a SoundDescription link, which can be on an archetype of the object. Unfortunately, the script can’t tell on its own when a voice-over has finished playing. So set the Script\Timing property to the length of the schema.
After the voice-over has played or, if no schema was specified, after the book is read, a quest variable is modified. The name and operation are specified in the Trap\Quest Var property. The same options as for TrapMissionQVar.
You can also use trigger links with this script. They will be activated when the book is read.
System Shock 2 doesn’t have a book-mode, so this script isn’t as useful as in a Thief game. The text to display is determined by the Script\Use Message property. Set the voice-over schema name with the Sound\Object Sound property, and use the Script\Delay Time property. The quest variable is specified with the Script\QBName property using the same format.
Abstract script for displaying text with quest-variable substitutions.
Script: | BaseQVarText |
---|---|
Properties: | Book\Text, Script\Use Message |
This script displays text on-screen that can include the values of quest variables. The text to display, which is specified by the Book\Text or Script\Use Message property, is scanned for replaceable sub-strings. Each sub-string is evaluated and a replacement made. The replacements themselves may contain further replacements, and those will be processed as well. When all of the sub-strings have been found, the text is displayed. This only works for on-screen text, so the Book\Art property is ignored.
This script can’t be used directly. You can use QVarPlaque, QVarScroll, or TrapQVarText depending on how you want the script to be triggered.
Each replaceable sub-string begins with the character ‘%
’ and then the name of the quest variable enclosed in curly braces (‘{
’ and ‘}
’). This will insert the value of the quest variable in place of the sub-string. Instead of the value, other text can be inserted by adding a conditional character before the braces. The possible conditions are ‘=
’, ‘<
’, ‘>
’, and ‘?
’. After the curly braces, write one or two sets of square brackets (‘[
’ and ‘]
’) with the new text in each. The first set will be printed if the condition is true, and the optional second set will be printed if it is false.
The ‘=
’, ‘<
’, and ‘>
’ conditionals test if the quest variable is equal to, less than, or greater than some number. Write the number to compare to immediately after the conditional character. The last conditional, ‘?
’, just tests if the variable is non-zero.
The following example prints the value of the quest variable bottles
if it is not zero, or the text “No more
” if it is zero. Then the word “bottle
” is pluralized if necessary.
%?{bottles}[%{bottles}][No more] bottle%=1{bottles}[][s] of beer on the wall.
Perform actions after reading a book in the world.
Script: | PostReadPlaque |
---|---|
Inherits: | BasePostRead |
Messages: |
This is for books that are frobbed in the world. The actions that occur are described in BasePostRead.
Perform actions after reading a book in the inventory.
Script: | PostReadScroll |
---|---|
Inherits: | BasePostRead |
Messages: |
This is for books that are frobbed in the inventory. The actions that occur are described in BasePostRead.
Display text when frobbed in the world.
Script: | QVarPlaque |
---|---|
Inherits: | BaseQVarText |
Messages: |
This script activates when the object is frobbed in the world. The text is displayed as described in BaseQVarText.
Display text when frobbed in inventory.
Script: | QVarScroll |
---|---|
Inherits: | BaseQVarText |
Messages: |
This script activates when the object is frobbed in the inventory. The text is displayed as described in BaseQVarText.
An object that becomes something else when picked up.
Script: | Transmogrify |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | Transmute, Mutate |
This script lets you make objects that act like the crystals from Thief. There are two types of objects: one that appears in the world, and another for the inventory. This script goes on the object that is created in the world. When the object is picked up by the Player, it will create the other type of object and put that in the inventory instead. The link that associates the two objects can be placed on the archetypes, which makes it easy to implement different types of transmogrifying objects.
Thief: Link the objects using a Transmute link.
SS2: Link the objects using a Mutate link.
Set a quest variable in the campaign database.
Script: | TrapCampaignQVar |
---|---|
Inherits: | TrapMissionQVar |
The quest variable that this trap sets will be saved in the campaign database, so it can be read in later missions as well. The variable actually gets written to the mission database first, and only gets moved when the game ends. Trust me, this is the best way to make the script work. Just don’t be surprised if DromEd doesn’t always show the variable in the campaign database.
In System Shock 2, the default for most scripts is to store quest variables in the campaign database. The hack described above does not apply in SS2.
Destroy a door the right way.
Script: | TrapDestroyDoor |
---|---|
Inherits: | BaseTrap |
Messages: | |
Links: | ControlDevice, SwitchLink |
Doors are difficult to destroy by ordinary means. Traps that slay an object will only make the door pop open. And teleporting a door away will leave behind the black rectangle when the Blocks Vision? flag is on. This script will make sure a door is really destroyed, and leaves the portal open. The doors to destroy are linked to using ControlDevice or SwitchLink links.
Fade the screen in and out.
Script: | TrapFader |
---|---|
Inherits: | BaseTrap |
Parameters: | fade_time(time), fade_color(color) |
The screen will fade out when this trap is turned on. Turning off the trap will fade the screen back in. You should always use the revert timer with this trap so the screen doesn’t get stuck in the fade-out. The fade_time is the time it will take for the screen to fade completely in or out. When using the revert feature of the trap, the timer will start at the same time as the fade. So you should set it to at least the same length as fade_time.
Thief 1: The screen will not fade in, but will just instantly reappear.
Thief 2: Fading in will make the player unwield any weapons.
SS2: The color of the fade can be changed with the fade_color parameter. The default is black.
The configuration setting no_endgame prevents this script from working.
Alternate between
and .Script: | TrapFlipFlop |
---|---|
Inherits: | BaseScript |
Messages: | , |
This trap only responds to Invert and Once trap control flags will be used.
. Each time it is triggered, it will send either or , alternating between the two. TheSets a quest variable, with complete arithmetic operations.
Script: | TrapMissionQVar |
---|---|
Inherits: | BaseTrap |
Properties: | Trap\Quest Var, Script\QBName |
Parameters: | initqv(integer) |
When activated, the script will modify the value of a quest variable. The variable name and operation to perform are specified in the Trap\Quest Var or Script\QBName property. The quest variable is stored in the mission database. Thief games can also write the variable to the campaign database using TrapCampaignQVar.
The operation format is the same as from TrapSetQVar from Thief. First is a single-character operation, followed by an integer argument to the operation. Then there is a colon (‘:
’) followed by the name of the quest variable. There should be no spaces up until the variable name. Spaces are allowed in the name, however. The following table explains the possible operations, and includes an example of what happens when the trap is activated with a certain argument. In all cases, the original value of the quest variable is 102.
Op | Turn On | Turn Off | Example |
---|---|---|---|
= | Sets the value to the argument. | Sets the value to 0. | =3 → 3 |
+ | Adds the argument to the value. | Subtracts the argument from the value. | +3 → 105 |
- | Subtracts the argument from the value. | Adds the argument to the value. | -3 → 99 |
* | Multiplies the value by the argument. | Divides the value by the argument. | *3 → 306 |
/ | Divides the value by the argument. | Multiplies the value by the argument. | /3 → 34 |
% | Takes the remainder of the value divided by the argument. | Multiplies the value by the argument. | %4 → 2 |
| | Performs bitwise-or with the value and the argument. | Clears the bits in the value that are set in the argument. | |3 → 103 |
{ | Shifts the bits in the value to the left. | Shifts the bits in the value to the right. | {3 → 816 |
} | Shifts the bits in the value to the right. | Shifts the bits in the value to the left. | }3 → 12 |
" | Multiplies the value by 10, then adds the least-significant decimal digit of the argument to the variable. | Divides the value by 10. | "3 → 1023 |
# | Multiplies the value by 10, then adds the least-significant decimal digit of the argument to the variable. The value will always be less than 10000. | Divides the value by 10. | #31 → 1021 |
? | Adds to the value a random number ≥ 0 and ≤ the argument. | Subtracts from the value a random number ≥ 0 and ≤ the argument. | ?3 → 102—105 |
d | Adds to the value a random number > 0 and ≤ the argument. | Subtracts from the value a random number > 0 and ≤ the argument. | d3 → 103—105 |
You don’t have to create the quest variable ahead of time with this script. If the parameter initqv is set, then the variable will be set to that value when the game starts.
Relay if a quest-variable meets the requirement.
Script: | TrapQVarFilter |
---|---|
Inherits: | BaseTrap |
Properties: | Trap\Quest Var, Script\QBName |
This script will relay messages if a quest variable condition is met. Set the Trap\Quest Var or Script\QBName property like TrigQuestVar. Then, when the test is true, the relay will pass messages.
Display text when turned on.
Script: | TrapQVarText |
---|---|
Inherits: | BaseQVarText |
Messages: |
When this trap is activated it displays text as described in BaseQVarText.
Trigger when an odd number of switches is turned on.
Script: | TrapRequireOne |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(Require) |
This script combines the outputs of multiple triggers so that when any one of the triggers changes state, the state of the trap changes. With only two sources, this is called a three-way switch; but this trap can have any number of sources. In particular, the trap is turned on when an odd number of triggers has been turned on. The triggers that are turned on are tracked using ScriptParams links that have the data set to “Require”.
Trigger when just one switch is turned on.
Script: | TrapRequireOneOnly |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(Require) |
A simple timer.
Script: | TrapTimer |
---|---|
Inherits: | BaseTrap |
Properties: | Script\Timing, Script\Delay Time |
A timer is the most useful type of trap that isn’t present in most of the standard games. What were they thinking? Set the time to delay the message in Script\Timing (as milliseconds) or in Script\Delay Time (as seconds). The extra data of the message will not be preserved.
This trap works like the standard TrapRelay in that it will pass not just and , but other (though not all) types of messages as well.
Trigger when an AI enter a bounding-box.
Script: | TrigOBBCreature |
---|---|
Inherits: | TrigOBBSpec |
Messages: | , |
Links: | Population |
This is an OBB trigger, also known as a tripwire, that triggers when an AI enters the bounding-box of the object. Actually, it reacts to objects of type Creature (Thief) or Monsters (SS2). The creature is tracked the same way as for TrigOBBSpec.
Trigger when a quest variable changes.
Script: | TrigQuestVar |
---|---|
Inherits: | BaseTrap |
Messages: | |
Properties: | Trap\Quest Var, Script\QBName |
When the value of a quest variable changes, this script tests it against a condition and sends Thief 2, so there’s no difference between this script and TrigQVar in that game.
when the condition becomes true, or if it is now false. (Or it sends nothing if the condition hasn’t changed.) The possible tests are the same as inThe condition in the Trap\Quest Var or Script\QBName property is similar to that used by TrapMissionQVar. The first character is the type of the test, ‘=
’, ‘<
’, ‘>
’, ‘&
’, or ‘"
’. Following this is the number to test against, then a colon (‘:
’) and finally the name of the quest variable. There should not be any spaces from the start of the string up to the name of the variable. (Variables names can have spaces in them.)
The tests ‘=
’, ‘<
’, and ‘>
’ test if the quest variable is equal-to, less-than, or greater-than the given number. The ‘&
’ test compares the numbers as a set of binary bits. If any of the bits set in the test number are also set in the quest variable, the condition is true. The ‘"
’ test compares the decimal digits of the numbers. The quest variable must have the same digits in the same places as the test number. Digits greater than those in the test number are ignored. You can test against 0, even in the leading digits. (So testing against “01
” is actually different than testing against just “1
”.)
Trigger when a moving terrain object reaches the waypoint.
Script: | TrigWaypoint |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | ControlDevice |
Put this script on a TerrPt and it will activate its trigger links when the moving terrain object reaches it.
Scripts for Thief: The Dark Project and Thief Gold. These are mostly ports of scripts from Thief 2.
Disable an attack SFX when an AI is knocked-out.
Script: | CleanUpAttack |
---|---|
Inherits: | BaseScript |
Messages: | , |
Reveal a secret when the object is frobbed.
Script: | FrobFind |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Dark GameSys\Stats |
QVars: | DrSSecrets, DrSScrtCnt |
Reveal a secret when the door is opened.
Script: | HiddenDoor |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Dark GameSys\Stats |
QVars: | DrSSecrets, DrSScrtCnt |
Makes the player invisible when used.
Script: | InvisiPotion |
---|---|
Inherits: | TimedPotion |
Messages: | , |
Properties: | AI\State\Current visibility |
Metaproperties: |
When this potion is used by the Player, then he will be made invisible using the metaproperty . The metaproperty only needs to include a Scripts with Invisible in it.
The Renderer\Invisible doesn’t exist in Thief 1, so the player’s weapon doesn’t disappear like in Thief 2.
Makes the object invisible.
Script: | Invisible |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | AIAttack |
Properties: | AI\State\Current visibility |
This script is activated by the message InvisiPotion script. The object will be made invisible to AI.
, which is sent by theUse the loot collected in the previous mission.
Script: | LastMissionLoot |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Dark Gamesys\Loot, Difficulty\Script |
QVars: | total_loot |
This script will set the object’s Dark Gamesys\Loot property to the amount of loot collected in the previous mission. To activate it, you need to add the Difficulty\Script property and set the flags for which difficulty levels you want to use the script on. If the script isn’t activated, then the Dark Gamesys\Loot property is left unmodified.
Decreases the player’s gravity and movement speed when used.
Script: | LoGravPotion |
---|---|
Inherits: | TimedPotion |
Properties: | Physics\Model\Attributes |
Ignore mines when the AI is disabled.
Script: | NoPingBack |
---|---|
Inherits: | BaseScript |
Messages: | |
Metaproperties: |
A door that remains closed when unlocked.
Script: | NonAutoDoor |
---|---|
Inherits: | BaseScript |
Messages: | , , , , , , , , , , , , |
Links: | ScriptParams(Double) |
Properties: | Door\Rotating, Door\Translating, Engine Features\Locked |
Schemas: | “Event StateChange, OpenState, OldOpenState ”, “Event Reject, Operation OpenDoor ” |
Become alerted when bumped by the player.
Script: | NoticesPlayerBumps |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | AI\AI Core\Alertness cap |
Stimulate objects that touch this one.
Script: | PhysARContact |
---|---|
Inherits: | BaseScript |
Messages: | , |
Set the object’s gravity when touched.
Script: | ReGravitize |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Physics\Model\Attributes |
Cancels an AI’s behavior when it is killed.
Script: | ShutUpYerDead |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | AIAwareness |
Reveal a secret when the object is slain.
Script: | SlayFind |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Dark GameSys\Stats |
QVars: | DrSSecrets, DrSScrtCnt |
A generic potion with a timed activation period.
Script: | TimedPotion |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | ScriptParams(Potion) |
Properties: | Script\Timing, Engine Features\Combine Type |
Schemas: | “Event Deactivate ” |
This script is used for potions that activate when frobbed in the inventory. The potion will be active for a specified period of time. Using another potion of the same type will restart the timer. The duration of the potion is specified with the Script\Timing property in milliseconds. The default time is 8.6 seconds, and the potion will always last at least 1 second. The environmental schema tags “Event Deactivate
” will be played just before the potion ends. This script doesn’t make any sound when the potion begins, though.
If the object is in an AI’s inventory when the game starts, then the metaproperty Thief 1, so you don’t have to create it yourself.
is added to the AI. This already exists inChange an object’s shape when unlocked.
Script: | TransformLock |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Tweq\Models, Engine Features\KeyDst |
Control a tweqable object.
Script: | TrapDirection |
---|---|
Inherits: | BaseTrap |
Messages: | , |
Links: | ControlDevice |
Reveal a secret when the trap is activated.
Script: | TrapFindSecret |
---|---|
Inherits: | BaseTrap |
Properties: | Dark GameSys\Stats |
QVars: | DrSSecrets, DrSScrtCnt |
Trigger when a mission is almost over.
Script: | TrapNonFinalComplete |
---|---|
Inherits: | BaseTrap |
Messages: | , |
QVars: | goal_state_*, goal_visible_* |
Only relay
messages.Script: | TrapOffFilter |
---|---|
Inherits: | BaseScript |
Messages: |
This is an old-fashioned relay that only passes trap features.
. It doesn’t support any of the more advancedRelay a message one time only.
Script: | TrapOnce |
---|---|
Inherits: | BaseScript |
Messages: | , |
This is an old-fashioned trap that will relay a single trap features.
or only. It doesn’t support any of the more advancedActivate AI patrol routes.
Script: | TrapPatroller |
---|---|
Inherits: | BaseTrap |
Links: | ControlDevice |
Properties: | AI\Ability Settings\Patrol: Does patrol |
Automatically turn off after being turned on.
Script: | TrapRevert |
---|---|
Inherits: | BaseScript |
Messages: | , , |
Properties: | Script\Timing |
This is an old-fashioned trap. It relays a Script\Timing property as milliseconds. If it is not present, or is 0, then the trap acts like a normal relay. Sending a message while the timer is active will cancel the previous timer.
or message then, after a period of time, sends the opposite message. The time is specified in theSlay an object using a stimulus.
Script: | TrapSlayer |
---|---|
Inherits: | BaseTrap |
Links: | ControlDevice |
Properties: | Game\Damage Model\Hit Points |
Stimuli: | BashStim |
Change the texture of terrain.
Script: | TrapTexture |
---|---|
Inherits: | BaseTrap |
Properties: | Script\TerrReplaceOn, Script\TerrReplaceOff, Engine Features\Retexture Radius |
This trap controls the texture of nearby terrain. Set the properties to the path to the texture resource for when the trap is turned on and when it is turned off. The destroyed texture isn’t supported by this script. Any cells within the retexture radius will have their polygons swapped between the old and new textures. You need to have the textures initially set to the same state as the trap. Changing textures won’t work if the new texture isn’t also loaded into the mission.
Trigger when the player enters a region.
Script: | TrigOBBPlayer |
---|---|
Inherits: | BaseTrap |
Messages: | , |
Schemas: | “Event Activate ”, “Event Deactivate ” |
This trap triggers when the Player object enters the bounding-box dimensions of the object. The properties of the object should be set like the standard BoundsTrigger trap. Of course, you’ll want to modify the dimensions to the appropriate size. An environmental schema with tags “Event Activate
” will be played when the trap turns on, and “Event Deactivate
” when turned off.
Trigger when the player carries an object into a room.
Script: | TrigRoomDelivery |
---|---|
Inherits: | TrigRoomObject |
Messages: |
Trigger when the object is dropped in a room.
Script: | TrigRoomDeposit |
---|---|
Inherits: | TrigRoomObject |
Messages: |
Scripts for Thief 2: The Metal Age. Many of these scripts originally appeared in Thief 1.
Helper for burrick gas clouds.
Script: | Burplauncher |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | Firer |
This script is meant to be put on the burplauncher object that is emitted by burricks. When any part of the cloud of gas collides with something else, this script will destroy all other parts of the cloud. However, burplauncher works just fine without the script, and the difference isn’t very noticeable.
Destroy objects when they aren’t visible.
Script: | CleanObjDestroy |
---|---|
Inherits: | BaseTrap |
Messages: | |
Links: | ControlDevice |
An object that will fall down when stepped on.
Script: | CollapseFloor |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | Corpse, Flinderize |
Properties: | Physics\Misc\Pressure Plate |
A collapsing floor is a type of pressure plate. The object is usually placed above a pit. You can configure the Physics\Misc\Pressure Plate however you like. A slower speed and longer travel distance will give the player time to get off of the collapsing section before it falls. When the object is fully depressed, it will be destroyed. To make the object appear to fall to the bottom of the pit, you need to create a separate archetype for the falling object. Create a Corpse link from the collapsing floor to the falling object. You can also use Flinderize links for falling objects that will be scattered.
An animated light that automatically turns on and off.
Script: | ControlWindowShade |
---|---|
Inherits: | WindowShade |
Messages: | |
Properties: | Script\Timing |
Parameters: | auto_time_min, auto_time_max |
This is a variation of WindowShade that also periodically turns the light on or off. The time between changes is randomly selected, between 5 and 15 seconds by default. This can be changed with the auto_time_min and auto_time_max parameters. Whether the light will be changed to on or to off depends on the Script\Timing property. This number is the probability that the light will be turned on. A value of 100 or greater will keep the light turned on all the time.
Controller for complex multi-part conversations.
Script: | ConvControl |
---|---|
Inherits: | BaseScript |
Messages: | , , , , , , , , , |
Links: | ControlDevice |
This script allows you to make complex multi-part conversations that can be interrupted and resumed. The controller is linked to a number of conversation traps. When the controller is turned on, it will trigger the first of the linked conversations. One of the conversation actors should have the ConvSpeaker script so it can send a message back to the controller. When this happens, the controller will remove the link to the conversation that was just triggered and proceed to the next one. This continues until an actor sends , or if the controller is turned off.
A locked controller does not trigger any conversation. If the controller is turned on while locked, or was turned on when it became locked, then it will continue the conversations once it is unlocked.
The messages
and are also accepted and will turn the controller on and off, respectively. The message will act like locking the controller, and is like unlocking it.Allow an AI to perform complex conversation actions.
Script: | ConvSpeaker |
---|---|
Inherits: | BaseScript |
Messages: | , , , , , , , , , , , , |
This script responds to messages from an AI involved in a conversation or other pseudo-script. Add this script to the AI and use the action Script message with the message name as the first argument. Some of these messages use the other arguments of the command. Where the description mentions the “first argument”, it is referring to the arguments the message receives, which are offset by one in the pseudo-script action dialog box. So you’d type the “first” argument for the message as the second argument for the action.
ConvNext, ConvEnd : | Relay the message to the controller of a conversation. Meant to be used with ConvControl. The controller object will be located automatically, but you can specify a specific object as the first argument. |
---|---|
PlayAmbient, PlayVO : | Play a schema as either an ambient sound, or as a voice-over. The first argument is the name of the schema object. |
Slay : | Slays a specified argument. Leave the argument blank, or type “self ” to slay this AI. Otherwise, the argument is the object to slay. |
CompleteGoal, FailGoal, CancelGoal : | Changes the state of an objective. The argument is a comma (‘, ’) separated list of objective numbers that will be modified. |
ShowGoal, HideGoal : | Changes the visibility of an objective. The argument is a comma (‘, ’) separated list of objective numbers that will be modified. |
SwapGoal : | Simultaneously makes one objective visible and hides another. This message takes two arguments; both comma (‘, ’) separated lists of objective numbers. The first argument is the objectives to hide, and the second is the objectives to show. |
IsGoalShown, IsGoalComplete : | Checks if an objective is visible or if it is completed. The argument is a comma (‘, ’) separated lists of objective numbers. If any of the objectives are hidden or incomplete, then the pseudo-script stops. |
Lets you pick up AI after they have been disabled.
Script: | CorpseFrobFixed |
---|---|
Inherits: | BaseScript |
Messages: | , , |
Metaproperties: |
Trigger for complex conversations.
Script: | CuttyCell |
---|---|
Inherits: | BaseScript |
Messages: | , , , |
This is a room script that generates the ConvControl script. It activates when the Player enters or leaves the room.
and message for theThe controller can also be triggered with standard
and messages, so this script isn’t really necessary.An object that can grow and shrink when damaged.
Script: | Elemental |
---|---|
Inherits: | BaseScript |
Messages: | , |
Properties: | Shape\Scale, Tweq\Scale, Tweq\ScaleState |
Parameters: | health_curve(integer) |
This script will adjust the Shape\Scale to match the health of the object. Add the Tweq\Scale property to the object and it will shrink when slain.
The health_curve parameter modifies the relationship between the health of the object and its size. See the description of TrapPhantom for the possible values.
Abstract script for factory switches.
Script: | FactoryBase |
---|---|
Inherits: | BaseScript |
Messages: | , , , , |
Links: | ControlDevice, ScriptParams(ErrorOutput), FrobProxy |
Properties: | Tweq\Joints, Tweq\JointState |
Schemas: | “Event StateChange DirectionState ... ” |
The objects that are used in factory set-ups share many actions. Because most of the objects are levers, or act similarly to levers, this script mostly does all the things that you would expect from the StdTwoState script, such as activating tweqs, environmental schemas, and sending and messages.
A typical factory uses one cauldron, two levers, a gauge, one mold, and a product. Optional devices include, a buzzer, a mold socket, a gear, and sparks. With a worker, the factory can be automated. See the scripts for each individual device for specific directions.
Controller for a cauldron in a factory.
Script: | FactoryCauldron |
---|---|
Inherits: | FactoryBase |
Links: | ScriptParams(Synch), ScriptParams(Sparks) |
Properties: | Tweq\Models, Renderer\AnimLight |
Schemas: | cauldron_lp, lava_pour, cauldron_pivot |
A cauldron is a lever that, when on, indicates that molten iron is being poured into a mold. It has a joint tweq for tilting, and a model tweq for showing pouring iron. It can also be illuminated while pouring.
A cauldron is normally activated by a lever using a ControlDevice link. The cauldron should link to a gauge using ControlDevice. While moving forwards or backwards, it will turn a gear that is linked using ScriptParams links with the data “Synch”. The gear should use the script TweqOnOff. While pouring, a particle SFX can be activated. Link to the SFX using a ScriptParams link with the data “Sparks”. If the factory is automated, the worker AI must link to the cauldron using Owns.
Controller for a gauge in a factory.
Script: | FactoryGauge |
---|---|
Inherits: | FactoryBase |
Messages: | , |
Links: | ScriptParams(Mold) |
Parameters: | rates(float,float,float), overflow(float) |
A gauge in a factory indicates when a mold has been filled. The joint tweq of the gauge can be in three stages: rising, overflow, and falling. The speed of the tweq in each stage must be set using the parameter rates set to three floating-point values separated by commas. You also configure the Tweq\Joints property for the first stage. After the first stage, the gauge will continue moving forward at the speed from the second value in rates, and will add the value of overflow to the “high” position of the tweq. After the second stage, the tweq will reverse and return to the “low” position at the third speed from rates. The default rates are “1.75,0.5,30
” and the default overflow is “20
”.
When the gauge goes from the first to the second stage, it will send the message ScriptParams links that have the data set to “Mold”. This link should point to the factory mold. It sends along ControlDevice links after the second stage. This message should pass through an Inverter to turn off the lever that controls the cauldron. Another link can also go to a buzzer. It does not send at any time.
alongA lever in a factory.
Script: | FactoryLever |
---|---|
Inherits: | FactoryBase |
Messages: | |
Links: | ScriptParams(LockMe) |
A factory lever uses locks to prevent it from being toggled at inappropriate times. There are typically two factories in each factory: one controlling a cauldron and one controlling a mold. The lever will link to the controlled object using ControlDevice. Each lever has an associated FnordLock that the lever links to using Lock. There should also be a ScriptParams link with the data “LockMe” from each lever to the lock for the other lever. The lever can also link to a buzzer using a ScriptParams link with the data set to “ErrorOutput”. This will be used if the lever is frobbed while it is locked.
A light that automatically turns off.
Script: | FactoryLight |
---|---|
Inherits: | BaseScript |
Messages: | , |
Properties: | Renderer\Render Type, Renderer\AnimLight, Script\Timing |
Schemas: | “Event Activate ” |
A factory light is most often used as a buzzer. When activated, the light will turn on and play a schema. After the time set in Script\Timing, the light will turn off. If Script\Timing is not set, then the light will be on for 550 milliseconds.
The object doesn’t have to use Renderer\AnimLight. Without the property, the “light” will be turned on by setting the Renderer\Render Type to Unlit, and turned off by resetting it to Normal.
...
Script: | FactoryMold |
---|---|
Inherits: | FactoryLever |
Messages: | , , , , , |
Links: | ScriptParams(Mold), Owns, Contains |
Properties: | Physics\Model\Attributes |
...
Script: | FactoryWork |
---|---|
Inherits: | BaseScript |
Messages: | , , , , , |
Links: | Owns, Route, ScriptParams(WithHammer) |
Metaproperties: | , |
Objects: | TrolPt, Molds, Hammers, SmeltingCauldr |
Parameters: | frobmotion(string), pickupmotion(string), dropmotion(string) |
Adjust the color of a SFX.
Script: | FireElemSparx |
---|---|
Inherits: | BaseScript |
Messages: | , , , , , , |
Properties: | SFX\Particles |
The FireElement sends messages to its attached SFX indicating the alert level of the AI. This script adjusts the color of the particles based on those messages.
An AI made out of fire.
Script: | FireElement |
---|---|
Inherits: | Elemental |
Messages: | , , , , , |
Properties: | Renderer\Dynamic Light, Renderer\Extra Light, Renderer\Transparency |
Metaproperties: | |
Stimuli: | WaterStim |
Objects: | FElemHit, SteamPuff |
Wake up AI when the player attacks.
Script: | HeStartedIt |
---|---|
Inherits: | BaseScript |
Messages: | , |
Metaproperties: | |
Stimuli: | Knockout |
Wake up AI when grabbed.
Script: | Horn |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | AmbientHacked |
Metaproperties: |
Toggles the state of hot plates.
Script: | HotPlateControl |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | ControlDevice |
Properties: | Tweq\Joints, Tweq\Flicker, Shape\Joint Positions, Renderer\Extra Light |
Metaproperties: |
This script uses a combination of a joint tweq and a flicker tweq to determine when linked hot plates are dangerous. The joint tweq, which determines when the plates are on or off, should vary between -1
and 1
. The flicker tweq determines how often the plates are updated and should have a fairly low period. Each time the flicker triggers, the Renderer\Extra Light amount is set to the position of joint 1. If the value is greater than zero, then the meta-property is added, and it is removed if the value is less than zero.
Trigger when colliding with a specific object.
Script: | MagicBones |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | Owns |
This script is meant to be used with MagicCoffin. When the object collides with its owner, it will slay itself and send to the owner.
Trigger when owned objects have been slain.
Script: | MagicCoffin |
---|---|
Inherits: | BaseTrap |
Messages: | |
Links: | Owns |
This object should be an unrendered bounding-box. Create Owns links to objects that have the MagicBones script. That script will slay each object when it collides with this one. When all of the objects have been slain, the trap will be activated.
Change the shape of an object to match it’s stack size.
Script: | ModelByCount |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Engine Features\Stack Count, Tweq\Models |
...
Script: | MoldSocket |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | ScriptParams, Owns |
Properties: | Physics\Model\Attributes, Engine Features\KeySrc, Engine Features\KeyDst |
Trigger for complex conversations.
Script: | NearCuttyCell |
---|---|
Inherits: | BaseScript |
Messages: | , , , , |
Links: | Population |
Metaproperties: |
This is a room script that generates the ConvControl script. It activates when an AI on a bad team enters or leaves the room.
and messages for thePutting a lock on the controller does the same thing as this script, and can be more flexible. This script only exists to ease the transition from Thief 1.
Makes the AI flee when triggered.
Script: | Prisoner |
---|---|
Inherits: | BaseScript |
Messages: | |
Metaproperties: | |
Signals: |
Makes a locked object unfrobbable.
Script: | ReallyLocked |
---|---|
Inherits: | BaseScript |
Messages: | , |
Metaproperties: |
Lock the object again after it has been unlocked.
Script: | ResetLockbox |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | Lock, AIDoor |
Properties: | Tweq\Flicker |
Add the property Tweq\Flicker to the object and configure it for the time when the lock should reset. The tweq will be activated when the object is unlocked. When the tweq halts, the object is locked again. If the lock is linked to a door that is being used by an AI, then it wait some more before locking the object.
Set watch links when a door is opened.
Script: | SecureDoor |
---|---|
Inherits: | BaseScript |
Messages: | , , |
Links: | AIWatchObj |
Parameters: | watcher(object) |
AIWatchObj links will be created to this door if it changes from its original state. The links will be removed if it returns to normal. Put AI\Utility\Watch: Watch link defaults on the door to configure the links. The links will be created for all Human objects by default. Set the watcher parameter to the name of an archetype to override this.
You can make a door start in the open state by adding the property Difficulty\Close (Open) Door and leaving the flags unchecked.
Create crushing vines when the object hits the player.
Script: | StickyVines |
---|---|
Inherits: | BaseScript |
Messages: | |
Objects: | JunkEarthWebs |
Use this script on the EarthShot projectile. When it hits the Player, a JunkEarthWebs object will be put in his inventory.
JunkEarthWebs needs to have both JunkWebs and JunkVines on it.
Wakes up inactive AI.
Script: | TrapAIWake |
---|---|
Inherits: | BaseTrap |
Messages: | , |
Use this to activate the WakeableAI script.
Make an object suspicious.
Script: | TrapSecureDoor |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | AIWatchObj |
Properties: | Engine Features\Suspicious |
Parameters: | watcher(object) |
The simplest way to use this script is to add the Engine Features\Suspicious property to the object. Then the Is Suspicious flag will be just be turned on and off.
Another way creates AIWatchObj links to the object when it is turned on, and removes the links when turned off. Use the AI\Utility\Watch: Watch link defaults property to configure the links. The links will be created on all Human objects by default, or on the archetype specified in the watcher parameter.
Slay an object using a stimulus.
Script: | TrapSlayer |
---|---|
Inherits: | BaseTrap |
Links: | ControlDevice |
Properties: | Game\Damage Model\Hit Points |
Stimuli: | BashStim |
Trigger when the player trips the trap.
Script: | TrigOBBPlayerStuff |
---|---|
Inherits: | BaseTrap |
Messages: | , |
Links: | Firer |
Wake up an inactive AI.
Script: | WakeableAI |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | AI\State\Current mode |
Use this script on AI that won’t be part of the mission until teleported in. Set the AI\State\Current mode property to Asleep for improved performance. Then trigger the sleeping AI with the TrapAIWake script and they will wake up.
Create watch links.
Script: | WatchMe |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | AIWatchObj |
Parameters: | watcher(object) |
An animated light that changes nearby textures.
Script: | WindowShade |
---|---|
Inherits: | BaseTrap |
Messages: | , |
Properties: | Renderer\Anim Light, Script\TerrReplaceOn, Script\TerrReplaceOff, Script\TerrReplaceDestroy |
This is a combination of AnimLight and TrapTexture. When the light is turned on, nearby terrain will be set to the texture specified in Script\TerrReplaceOn. When turned off, Script\TerrReplaceOff is used. The object can also be slain, and then it will turn the light off and set the terrain to Script\TerrReplaceDestroy. The light can be turned back on after being slain, but the texture won’t change anymore.
The starting texture should be set to match the initial state of the light.
Scripts for System Shock 2. Many of these scripts are ports from Thief.
Controls animated lights.
Script: | AnimLight |
---|---|
Inherits: | BaseTrap |
Messages: | , , , , , |
Links: | SwitchLink, ParticleAttachement |
Properties: | Renderer\Anim Light, Renderer\Self Illumination, AmbientHacked, Tweq\Flicker, Tweq\FlickerState |
This is an alternative to BaseLight with features that should be familiar to Thief users. Along with and , the light can be changed with the message. The script also toggles the AmbientHacked property, and toggles any attached SFX. (You may want to use StdParticleGroup as well.) The light can be configured to flicker when it is turned on or off. An AnimLight can also act as a trigger.
This script doesn’t play any environmental schemas, though. If you want the object to play an activate or deactivate sound, you’ll need to add the LightSound script to the object.
Some of the Renderer\Anim Light modes do not work, including smoothly dim, smoothly brighten, and random.
An object that stims the user when frobbed in inventory.
Script: | CloneContactFrob |
---|---|
Inherits: | BaseScript |
Messages: | |
Properties: | Engine Features\Stack Count, Renderer\Has Refs |
When this object is frobbed in the inventory, an invisible copy is made and used to stimulate the frobber by contact. The stack count of the visible object is then decremented. The life cycle of the stimulus source for the object should be configured to eventually destroy the object. Because the object is copied, any relevant properties should be set on the archetype.
This is the script that Thief uses for its healing potions.
Send a message when an AI dies.
Script: | NotifyRegion |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | ScriptParams(Population) |
When this AI is killed, a ScriptParams links that have the data “Population”. These links are usually created by a room or OBB trigger script. Without this script, the trigger will see the AI enter, but never leave.
property is sent alongThis script is normally put on the metaproperty
, which gets added to the AI by a trigger that needs it.Stimulate objects that touch this one.
Script: | PhysARContact |
---|---|
Inherits: | BaseScript |
Messages: | , |
Control a particle SFX.
Script: | StdParticleGroup |
---|---|
Inherits: | BaseScript |
Messages: | , , |
Properties: | SFX\Particles |
An upgrade machine that can be used more than once.
Script: | TraitMachineReusable |
---|---|
Inherits: | BaseScript |
Messages: | , , , |
Properties: | Engine Features\Locked |
Schemas: | “Event Activate ” |
This script acts like the standard TraitMachine script; but instead of permanently disabling the machine after use, it just locks it. The machine can then be used a second time if it becomes unlocked. The machine can be unlocked by sending a message, or locked by sending .
The lock only prevents a player from opening the trait selection overlay. If the object has already been frobbed, and the machine receives a
, then a trait can still be selected.Relay messages with a minimum time between them.
Script: | TrapCapacitor |
---|---|
Inherits: | BaseTrap |
Properties: | Script\Delay Time |
When a capacitor sends
, it will block other messages from being relayed for a period of time. If a message attempts to pass through during the discharge time, then it will be queued until the timer expires. Only the most recently received message will be sent.This script is used when a device takes a significant amount of time to activate. A capacitor will prevent it from being turned off too quickly after it has been turned on.
Start a conversation.
Script: | TrapConverse |
---|---|
Inherits: | BaseTrap |
Links: | AIConversationActor |
Properties: | AI\Conversations\Conversation |
A conversation is an elaborate set of pseudo-scripts. They are used a lot in Thief, but not at all in System Shock 2. I can’t imagine why.
A conversation can involve up to six different AI, known as actors. Create AIConversationActor links from the conversation trap to the actors, and set the data for each link to the actor number for that AI, starting with 1. (It’s easy to forget this, since the default value is 0.) Add the property AI\Conversations\Conversation to the trap and set the actions you want to occur. Each step of the conversation is a set of actions that will be taken. The next step doesn’t occur until the previous step has completed.
The normal AI behavior can sometimes interfere with a conversation. It helps to add the metaproperty
to the actors in a conversation.I could say more, but I’m afraid that I might say something wrong. Conversations are damned tricky and I don’t have very good luck with them.
Relay if the correct code is entered in a keypad.
Script: | TrapKeypad |
---|---|
Inherits: | BaseTrap |
Messages: | |
Links: | ScriptParams(ErrorOutput) |
Properties: | Script\Keypad Code |
Relay if the player has enough credits.
Script: | TrapNanites |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(ErrorOutput) |
Parameters: | nanites(integer) |
This is a relay that will add nanites to the player when turned on. Turning off the trap, or specifying a negative value for nanites, will deduct the amount from the player. If there aren’t enough nanites to deduct, then a message is displayed, and a message is sent along ScriptParams links that have the data “ErrorOutput”. Adding nanites will always succeed. The trap can have a revert timer set and the player will only be charged once.
Activate a patrol route on linked AI.
Script: | TrapPatrol |
---|---|
Inherits: | BaseTrap |
Links: | SwitchLink |
Properties: | AI\Ability Settings\Patrol: Does patrol |
Trigger if all the controllers are turned on.
Script: | TrapRequireAll |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(Require), SwitchLink |
This script monitors a number of triggers. When they have all been turned on, the trap relays ScriptParams links with the data set to “Require”. The triggers must all link to this trap using SwitchLink.
. is sent if any of the triggers turns off. The triggers that have been turned on are tracked usingTrigger if any of the controllers is turned on.
Script: | TrapRequireAny |
---|---|
Inherits: | BaseTrap |
Links: | ScriptParams(Require) |
This script monitors a number of triggers and sends ScriptParams links with the data set to “Require”. Unlike TrapRequireAll, the triggers can communicate with this trap over links other than SwitchLink.
when at least one of them is turned on. is sent when all the triggers are turned off. The triggers that have been turned on are tracked usingA relay that will automatically turn itself off.
Script: | TrapRevert |
---|---|
Inherits: | BaseTrap |
This is a standard trap that just relays messages. The revert timer will function for messages, though, as well as .
Change the texture of terrain.
Script: | TrapTexture |
---|---|
Inherits: | BaseTrap |
Properties: | Engine Features\Retexture Radius |
Parameters: | terrreplaceon(string), terrreplaceoff(string) |
This trap controls the texture of nearby terrain. Set the parameters to the path to the texture resource for when the trap is turned on and when it is turned off. Any cells within the retexture radius will have their polygons swapped between the old and new textures. You need to have the textures initially set to the same state as the trap. Changing textures won’t work if the new texture isn’t also loaded into the mission. The default value of Engine Features\Retexture Radius is zero, so you must set the property for this script to function.
Trigger when an AI is alerted.
Script: | TrigAIAlert |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | SwitchLink |
Trigger when an object goes into or out of a container.
Script: | TrigContained |
---|---|
Inherits: | BaseTrap |
Messages: |
A repeating trigger.
Script: | TrigFlicker |
---|---|
Inherits: | BaseTrap |
Messages: | |
Properties: | Tweq\Flicker, Tweq\FlickerState |
Trigger when an object is frobbed in the inventory
Script: | TrigInvFrob |
---|---|
Inherits: | BaseTrap |
Messages: |
Trigger when a pressure plate is depressed.
Script: | TrigPPlate |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | SwitchLink |
Properties: | Physics\Misc\Pressure Plate |
Pressure plates are a specialized type of terrain-like object. The object must have an OBB physics model and the property Physics\Misc\Pressure Plate. When sufficient weight is placed atop the object, it will move down. This script is activated by that movement. is relayed along SwitchLink links when the pressure plate is completely lowered, and is relayed when it raises up again.
Trigger when a pressure plate begins moving.
Script: | TrigPPlateImmed |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | SwitchLink |
Properties: | Physics\Misc\Pressure Plate |
This script is activated by a pressure plate object, like TrigPPlate. is relayed when the pressure plate begins moving down, and is relayed when it begins moving upwards.
Trigger when an AI enters a room.
Script: | TrigRoomCreature |
---|---|
Inherits: | BaseScript |
Messages: | , , , , |
Links: | SwitchLink, ScriptParams(Population) |
Metaproperties: |
This is a trigger for rooms. It is activated when an AI enters the room. The trigger will deactivate after all AI have left the room. The AI inside the room are tracked using ScriptParams links that have the data set to “Population”. You should create a metaproperty named that contains the script NotifyRegion. The trigger will add this metaproperty to the AI it is tracking so it can get the message if the AI were to be slain inside the room.
Trigger when a player carries an object into a room.
Script: | TrigRoomDelivery |
---|---|
Inherits: | TrigRoomObject |
Messages: |
Trigger when the object is dropped in a room.
Script: | TrigRoomDeposit |
---|---|
Inherits: | TrigRoomObject |
Messages: |
Trigger when an object enters a room.
Script: | TrigRoomObject |
---|---|
Inherits: | BaseScript |
Messages: | |
Links: | SwitchLink, ScriptParams(Route) |
Trigger when moving between two rooms.
Script: | TrigRoomPlayerTrans |
---|---|
Inherits: | BaseScript |
Messages: | , |
Links: | SwitchLink, ScriptParams(Route) |
Trigger when someone enters or exits a room.
Script: | TrigRoomPopChange |
---|---|
Inherits: | TrigRoomCreature |
Messages: | , , , , |
This section is for OSM developers.
The source code for Public Scripts is included with the software. Under the terms of the GNU General Public License, you may use this source code to create your own software. Or you can just study it for informational purposes.
The source code that makes up the scripts is actually four somewhat independent packages.
Public Scripts: | The scripts themselves. This is the core of the OSM; everything else is supplemental. |
---|---|
ScriptLib Library: | A library of functions useful in any script project. |
lg Library: | The core headers and support code required to build an OSM. |
Dark Hook 2: | A DLL that allows script modules to register hook functions with the game. |
The Public Scripts are built with a modular design that allows a single set of source files to be compiled for all three games. The classes are compact enough to be self-documenting. And, by virtue of the pre-processor, only three extra lines of code are needed to add a new script.
There are many simple procedures that scripts use often enough to justify creating a library out of.
Get the contents of the design note.
char* GetObjectParams(
iObject)
;
int iObject;
Retrieves the contents of the design note for a particular object. The return value, if non-NULL
, will have been allocated by g_pMalloc and should be free’d by the same.
Get the value of a design note parameter.
char* GetObjectParamString(
iObject, pszParam)
;
int iObject;
const char* pszParam;
int GetObjectParamInt(
iObject, pszParam)
;
int iObject;
const char* pszParam;
float GetObjectParamFloat(
iObject, pszParam)
;
int iObject;
const char* pszParam;
bool GetObjectParamBool(
iObject, pszParam)
;
int iObject;
const char* pszParam;
int GetObjectParamObject(
iObject, pszParam)
;
int iObject;
const char* pszParam;
int GetObjectParamTime(
iObject, pszParam)
;
int iObject;
const char* pszParam;
Retrieves a design note parameter for a particular object. If the parameter doesn’t exist, the return value is NULL
or 0
. For GetObjectParamString
, a non-NULL
value will have been allocated by g_pMalloc.
This library contains the interface definitions required for scripts to interact with the game. The most significant interfaces are found in scrservices.h.
The documentation files for Public Scripts (what you are now reading) are generated from a modified DocBook XML source. The root of the document is in PublicScripts.xml and other fragments are in PublicScripts-common.xml, PublicScripts-dev.xml, PublicScripts-legacy.xml, PublicScripts-t1.xml, PublicScripts-t2.xml, and PublicScripts-ss2.xml. All the files use UTF-8 encoding and CRLF line-endings.
2.0 - The “Machina Populi” release. Sometime in the future.
Beta 1 - 2006-12-30 Adjustments for compatibility with MSVC. Drop FrobSounds, StopHere, and TrigBraindead from T1. They’re already in Thief Gold. TrapFlipFlop initializes on . Add IntrinsicText. Affects IntrinsicCover and IntrinsicPlaque.
Test 4 - 2006-08-12 Add TrapRequireOne, TrapRequireOneOnly. SS2: TrapRequirement is gone. Requirements are handled by an abstract class that can be used in any game. Population tracking for OBB and Room triggers moved into a common abstract class. TrigOBBSpec: Trigger on any submodel. Use population tracking to avoid double-triggering. utils.cpp: But in FixupScriptParamsHack. TrapMissionQVar: SS2 can use this script to store mission-specific qvars. Change how TrapRequireOne and TrapRequireOneOnly deal with trap control flags so it makes more sense. T2: HotPlateControl didn’t set the meta-property at the right times.
Test 3 - 2006-02-15
Still working at it.
Haven’t really been keeping track of changes, I’ll do a better job from now on... maybe.
First appearance of this snazzy XML documentation.
Test 2 - 2005-11-28
Some further refinements. I think I only showed this to NamelessVoice.
Test 1 - 2005-06-29 A first glimpse at Public Scripts.