These scripts are provided "As Is" without warranty of any kind, either expressed or implied. Nameless Voice will not be liable for any incidental, special, consequential or any other damages that may result from the use or inability to use this software.

First of all, I would like to thank Telliamed for making this script module possible.

- About the scripts -

These scripts make use of the Editor->Design Note property in the same way as Telliamed's scripts:

From Telliamed's documentation:

> The Editor\Design Note property is used to specify most parameters for a script. The design note is a string that can be a list of parameters, or a single parameter by itself. A parameters is a keyword, followed by an equals sign (`=`), then an argument. The argument may be surrounded with single or double quotes. Multiple parameters are seperated with a semi-colon (`;`). If you need to include a semi-colon in an argument, then it must be surrounded by quotes. A quote mark can be included by using the other type of quote mark to surround the argument, or escape the quote mark with a back-slash. (e.g. `'a \'quoted\' argument'`)

> When a script looks for an integer or flag parameter, you can have it read a quest variable. After the equals sign, type a dollar sign (`$`) and the name of the quest variable. There may not be space between the dollar sign and the variable name.

In this document, script parameters which are underlined must be specified for the script to function: `NormalParameter`; `RequiredParameter`

All the 'Trap' scripts (those that respond to TurnOn / TurnOff messages) inherit behaviours from a generic 'NVTrap' base script, which allows you to use parameters to imitate an independent Script->Trap Control Flags property for each script, even when you have several on the same object. Each 'Trap' script understands five parameters, (Where `[ScriptName]` is the name of the script as you entered it into the S->Scripts property.):

`[ScriptName]On`
Use this parameter to specify which script message should activate the trap. The default is TurnOn.

`[ScriptName]Off`
Use this parameter to specify which script message should deactivate the trap. The default is TurnOff.

`[ScriptName]Count`
Use this parameter to specify the maximum number of times that the script will work. You can use `[ScriptName]Count=1` to emulate the Once Trap Control Flag. The default is `0` (infinite).
Both TurnOn and TurnOff are counted by default. You can use `[ScriptName]CountOnly=1` to ignore TurnOff, and `[ScriptName]CountOnly=2` to ignore TurnOn. Sending the trap a ResetCount message will reset the counter.

You can use `[ScriptName]On="TurnOff";[ScriptName]Off="TurnOn"` to simulate the Invert Trap Control Flag; `[ScriptName]On="Null"` can be used to simulate NoOn and `[ScriptName]Off="Null"` can be used to simulate NoOff
You should probably avoid using the same message for both. Remember that if you specify `[ScriptName]On="TurnOff"` without specifying `[ScriptName]Off`, then TurnOff will be specified for both values.

The scripts that this applies to are denoted in this document by the words NVTrap in parentheses after their names.
Please note that the standard Trap Control Flags property is not used or supported.

All the 'Trigger' scripts (those that respond to events by sending TurnOn and TurnOff messages) inherit behaviours from a generic 'NVTrigger' base script, which allows you to use parameters to imitate an independent Script->Trap Control Flags property for each script, even when you have several on the same object. Each 'Trigger' script understands six parameters, (Where `[ScriptName]` is the name of the script as you entered it into the S->Scripts property.):

`[ScriptName]TOn`
Use this parameter to specify which script message the trigger should send when activated. The default is TurnOn.

`[ScriptName]TOff`
Use this parameter to specify which script message the trigger should send when deactivated. The default is TurnOff.

You can use trigger on and off parameters to specify a stim to send instead. To do this, first enter the intensity surrounded by square brackets, followed by the stim name. For example: `[ScriptName]TOn="[5.00]WaterStim"`

`[ScriptName]TCount`
Use this parameter to specify the maximum number of times that the script will work. You can use `[ScriptName]TCount=1` to emulate the Once Trap Control Flag. The default is `0` (infinite).
Sending of both TurnOn and TurnOff messages are counted by default. You can use `[ScriptName]TCountOnly=1` to ignore TurnOff, and `[ScriptName]TCountOnly=2` to ignore TurnOn. Sending the trigger a ResetTriggerCount message will reset the counter.

`[ScriptName]TDest`
Use this parameter to specify the object that the trigger should send messages to. Either specify a single object or archetype (see below), or use the name of a link type to broadcast the message along, preceeded by an `&` sybmol. The default is `[ScriptName]TDest="&ControlDevice"`. To have the message sent along a single random link of the specified type (rather than all links of that type), put a question mark (`?`) between the `&` and the link type.
Example: `[ScriptName]TDest="&?ControlDevice"` will send the message down a random ControlDevice link.
If you want the randomly chosen link to be deleted, then use `[ScriptName]KillLinks=1`.
You can also use weighted random links via `[ScriptName]TDest="&Weighted"`. This will examine ScriptParams links and treat their data (must be an integer) as the chance of that link being chosen. (A link with data of 2 will be chosen twice as often as one with data of 1). Weighted random only work with ScriptParams links.
Finally, you can use either `*` or `@` to affect all objects that inherit from a specific archetype: `*` Will only affect objects which are direct descendants, and `@` will affect all descendants.
For example: `[ScriptName]TDest="*Chest"` would affect all Chest (-2571) objects in the mission, but will not affect objects based on its descendant archetypes of Safe (-5986), VicHopeChest (-5773), LC_Chest (-4067), and SeaChest (-2817). `[ScriptName]TDest="@Chest"` would affect all of these objects.

For any parameter that specifies the name or number of an object for the script to affect, you can use `[me]` to use the object with the script, or `[source]` to use the object that sent the triggering message (the latter and may not work in all circumstances). You can also preceed the name of an archetype or metaproperty with the `^` symbol to use the nearest object that inherits from the one specified. For example, `"^Marker"` will affect the nearest object that decends from the Marker archetype, while `"^FrobInert"` will affect the nearest object that has the FrobInert metaproperty (either itself or on one of its archetypes). Unfortunately, this function does not seem to work in System Shock 2.

A description of each of the scripts follows:

Traps: | Version required: | T2 | SS2
NVAirLock (NVTrap) | v1.0.4 | Yes | Yes
NVCreateAndLink (NVLinkBuilder) | v1.0.0 | Yes | Yes
NVItemGiver (NVTrap) | v1.0.2 | Yes | Yes
NVEndTrap (NVTrap) (SS2 only) | v1.0.5 | No | Yes
NVLinkBuilder (NVTrap) | v1.0.0 | Yes | Yes
NVOnscreenText (NVTrap) | v1.0.0 | Yes | Yes
NVRecalcTrap (NVTrap) (SS2 only) | v1.0.5 | No | Yes
NVRelayTrap (NVTrap) (NVTrigger) | v1.0.0 | Yes | Yes
NVScaleDims (NVTrap) | v1.0.0 | Yes | Yes
NVSuspiciousTrap (NVTrap) | v1.0.0 | Yes | No
NVTrapConverse (NVTrap) | v1.0.4 | Yes | Yes
NVTrapSetQVar (NVTrap) | v1.0.7 | Yes | Yes
NVVOTrap (NVTrap) | v1.0.0 | Yes | Yes

Triggers: | Version required: | T2 | SS2
NVFrobToggle (NVTrigger) | v1.0.0 | Yes | Yes
NVHPTrigger (NVTrigger) | v1.0.3 | Yes | Yes
NVRelayTrap (NVTrap) (NVTrigger) | v1.0.0 | Yes | Yes
NVTrigQVar | v1.0.7 | Yes | Yes

AI Scripts: | Version required: | T2 | SS2
NVConvEnhancer DelayedFrob GiveItem SendMessage Follow StopFollowing | v1.0.0 v1.0.0 v1.0.0 v1.0.1 v1.0.0 v1.0.0 | Yes Yes Yes Yes Yes Yes | ? ? ? ? ? ?
NVGhostingMessages | v1.0.0 | Yes | Yes
NVIncapacitatedMessages | v1.0.0 | Yes | ?

Miscellaneous Scripts: | Version required: | T2 | SS2
NVAttachMyObj | v1.0.0 | Yes | Yes
NVComestible (SS2 only) | v1.0.3 | No | Yes
NVCursedObj | v1.0.7 | Yes | No
NVDeathCutscene | v1.0.6 | No | Yes
NVDoorStartsOpen | v1.0.4 | Yes | Yes
NVEmitWhileSelected | v1.0.0 | Yes | No
NVExclusiveObject | v1.0.0 | Yes | Yes
NVHolyH2OHack (NVInvTransform) | v1.0.2 | Yes | ?
NVInvAssembly | v1.0.2 | Yes | Yes
NVInvAssembly2 | v1.0.6 | Yes | Yes
NVInvTransform | v1.0.2 | Yes | Yes
NVInventoryMemory | v1.0.0 | Yes | No
NVKeyringKey | v1.0.6 | Yes | No
NVNameOnCreation | v1.0.0 | Yes | Yes
NVNewWeapon | v1.0.0 | Yes | No
NVPutIntoContainers | v1.0.5 | No | Yes
NVSafeDoor | v1.0.0 | Yes | ?
NVSwapSword | v1.0.7 | Yes | No
NVTweqMessages | v1.0.0 | Yes | ?
NVUnusableUnlessQVar | v1.0.7 | Yes | No

Debug / Mission Design Scripts: (NVDebug.osm) | Version required: | T2 | SS2
NVDifficultyDebug | v1.0.0 | Yes | ?

Version History

- Traps -

NVAirLock (NVTrap)

This script controls two airlock doors, both linked from it with ControlDevice (or SwitchLink for SS2) links.
Upon being triggered, it first locks itself so that it cannot be triggered again until it is finished.
Second, it sends TurnOn down any ScriptParam links with a data "Alarm".
Third, it closes both of its doors.
Once the doors are closed, it sends TurnOn down ScriptParams links with data "Vent".
It then waits for the number of milliseconds specified by `NVAirlockDelay` (the default is 5000ms), and turns the vents off again.
After this, it opens the door that was closed originally.
Finally, once this door is open, TurnOff is sent to the Alarm and the trap is unlocked.
An example setup (Thief 2):
Create a button, two MechBlastDoors, a MechRedAlarm, and a Marker and a TrapTrig.
Arrange the two blast doors in a corridor with a fair space between them, and place all the other objects in that space.
Give the TrapTrig the NVAirlock script.
Create a ControlDevice link from the button to the TrapTrig, and one from the TrapTrig to each of the doors. Now, create a ScriptParams link from the TrapTrig to the MechRedAlarm, data "Alarm", and another from the TrapTrig to the Marker, data "Vent.
Finally, give the marker the ActivateAmbient script and an A->AmbientHacked property with a Schema Name of "M11steam" and a Radius of 30 or so.
You should also give one of the doors the NVDoorStartsOpen script.

NVLinkBuilder (NVTrap)

Upon receiving TurnOn, this script creates a link with the flavour specified by `NVLinkType` between the objects specified by `NVLinkSource` and `NVLinkDest`.
A TurnOff message will remove the link.

You can specify data for the link by using `NVLinkData`#`Field` and `NVLinkData`#`Value` (where # is a number between 1 and 10, maximum). To specify booleans, use `1` for True and `0` for False; to specify vectors use the format: `"0.00, 0.00, 0.00"`.
If the link you want to create has no fields (such as ScriptParams links), then you must omit `NVLinkDatak`#`Field`.

To find out the name of the field, create the appropriate flavour of link in DromEd and hit Edit Data. The field name is exactly the same as the label next to each box, including spaces and other special characters. If there are no labels in the Link Data window, then that link flavour has no fields (and you need to omit `NVLinkData`#`Field`).
For example, valid fields on a Flinderize link are: "Count", "Impulse", "Scatter?", and "Offset".
If you specify an invalid link flavour or an invalid field name, DromEd will throw up an error message and possibly crash when this script is triggered. You have been warned.

NVCreateAndLink (NVTrap->NVLinkBuilder)

A derivative of NVLinkBuilder.
Upon receiving TurnOn, this script creates the object specified by `NVCreate`.
It then creates a link to the new object, with the flavour specified by `NVLinkType`.
By default, it links from the object with the script, but you can specify a source object via the `NVLinkSource` parameter.
A TurnOff message will destroy the object if it still exists and is still linked. Alternatively, you can specify `NVSlayCreated=1` to have the object slain rather than destroyed.
You can use the `NVCreateAndLinkLoc` parameter to specify the location at which to create the object and `NVCreateAndLinkRot` to specify the rotation. (Specify both values as a string with three numbers separated by comas, eg: `NVCreateAndLinkLoc="1.0,0.0,0.0"; NVCreateAndLinkRot="360,0,0"`)
By default, this is a relative value from the location of the current object, but you can use the `NVCreateAndLinkLocObj` parameter to specify another object, or 0 for an absolute location.
If you do not specify a location, the object will be created at 0, 0, 0.
You can specify data for the link in exactly the same way as you can with NVLinkBuilder.

NVEndTrap
System Shock 2 only.

Upon receiving TurnOn, this trap will instantly end the game. The `NVEndVideo` parameter can be used to specify the filename of a video to play. The filename specified must include the file extension (typically, .avi) and the file should be located in the cutscenes folder.

NVItemGiver

Gives the object specified by the `NVGiveWhat` parameter to the object specified by the `NVGiveTo` parameter (or the Player if none is specified). If the item is an archetype, an instance of that object is created instead. Objects will stack where appropriate.

NVOnscreenText (NVTrap)

Loads a book string and displays both the text and the quest variable that it specifies onscreen.
This behaves slightly differently from a standard book; rather than simply displaying the value of the string "page_0", it displays first the contents string "page_0", then the value of the quest variable specified in the string "QVar", and finally the contents of "page_1".

So, for example (assuming that the quest variable TestQVar is 54), the string file:

> Page_0: "At present, the qvar is "
> QVar: "TestQVar"
> Page_1: ". Thank you for asking."

would be displayed as "At present, the qvar is 54. Thank you for asking."
You can also use Design Note parameters instead of a string file. Use the parameters `NVPage_0`, `NVQVar`, and `NVPage_1`. You can also use `NVText` instead of `NVPage_0` for simple onscreen texts.

NVRecalcTrap(NVTrap)
System Shock 2 only.

Upon receiving TurnOn, this script will recalculate the player's derived statistics, such as Psi points, max Psi points, inventory capacity, etc., based on the player's current stats.

NVRelayTrap(NVTrap, NVTrigger)

Relays TurnOn and TurnOff messages along its ControlDevice links. Why? Because this can be used with the various options availiable to NVTrap and NVTrigger scripts. You can `NVRelayDelay` to delay the message by the specified number of milliseconds. If you specify `NVRelayDelayMax`, then a random delay between the time specified by `NVRelayDelay` and that specified by `NVRelayDelayMax` will be used.
If you want to abort any messages that are still waiting to be sent when the trap is triggered again, use `NVExclusiveDelay=1`.
You can use `NVRelayRepeat` to have the trap send the message a specific number of times each time it is triggerd. Only works when `NVRelayDelay` is specified. The time between each repeat is randomised if you use `NVRelayDelayMax`.
Use `NVRelayRepeat=-1` to repeat the message infinitely. An infinite repeat infers `NVExclusiveDelay=1`. The infinite repeat will stop if the script receives the opposite message from that which triggered it. TurnOff will stop an infinite-repeating TurnOn, and TurnOn an infinite-repeating TurnOff.
If you only want to allow TurnOn messages to activate the repeating trigger, then use `NVRepeatOnly=1`. You can use `NVRepeatOnly=2` to only allow repeating TurnOff messages.

(Theoretically, this should work for both patched and unpatched versions of Thief 2, but I haven't tested it. If it does, then it could be used instead of TrapTimedRelay.)

NVScaleDims (NVTrap)

This script is designed to be used in conjunction with the default TweqOnOff script and the Tweq->Scale property, but it can also be useful if you change the Shape->Scale of an object ingame using other methods.
Upon receiving TurnOn, this script will scale the physical dimensions and offset of the object to match its current Shape->Scale.
If the Tweq->ScaleState property is currently active (AnimS is On), then a timer named "FixDims" is started, which will fix the dimensions every 100ms until either a TurnOff or TweqComplete message is received (at which point the timer will be turned off to save system resources and prevent lag).
The `NVBaseLock=1` parameter will anchor the lower edge of OBB objects, so that they grow/shrink upwards only.

NVSuspiciousTrap (NVTrap)
Not availiable for System Shock 2.

Upon receiving TurnOn, this script makes its object suspicious.
The suspiciousness is removed via TurnOff.
If any AIs have an AISuspiciousLink to the object when it is turned off, then it is removed, along with an AIWatchObj links (in case you're using Telliamed's HighlySuspicious script).

NVTrapConverse (NVTrap)
Upon receiving TurnOn, this script triggers the conversation associated with its object.
Basically, this is a clone of the standard TrapConverse script.
Although you might find some use from the added flexibility of an NVTrap, this script is primarily for use with System Shock 2, which lacks TrapConverse.

NVTrapSetQVar (NVTrap)
An improved version of the standard TrapSetQVar script.
Upon being triggered, it sets the value of a quest variable. A quest variable that does not exist will be created, and its previous value will be assumed as zero.

For details of how to use the Trap->Quest Var property, see Telliamed's excellent guide.
NVTrapSetQVar and NVTrigQVar support a few new features, however.
Firstly, you can use the name of a quest variable in place of the numerical argument, in which case the value of that variable will be used instead. For example, you could use +QVar2:QVar1 to set QVar1 to its current value plus that of QVar2. You can also place a question mark ('?') in front of the name of this qvar to give a random number between zero and its value - so +?Qvar2:QVar1 would increase QVar1 by a random value between zero and that of QVar2.

See also: NVTrigQVar

NVVOTrap(NVTrap)

A replacement for the standard VOSounds script.
Plays a different voiceover schema depending on the value of a quest variable. Use the parameter `NVVOQVar` to specify the quest variable to read, and create ScriptParams links to each schema. The schema will be played if the link data is equal to the value of the variable.
If no link matches or the quest variable doesn't exist, then a SoundDescription link is used instead (if one exists).
The script will only play one schema (the first matching link). If you can actually think of a reason to have it play multiple voiceovers at the same time, then I can easily change it.

- Triggers -

NVFrobToggle (NVTrigger)

When an object with this script is frobbed, either in the world or in inventory (FrobWorldEnd and FrobInvEnd messages), alternating TurnOn and TurnOff messages are sent along its ControlDevice links.
As this is an NVTrigger script, you can use `NVFrobToggleTDest="[Me]"` to send the messages to the object itself, rather than along the links; this is of particular use in this case as it can allow you to cut down on objects.
If you want the object to start 'on' (the first frob will send TurnOff, rather than the default TurnOn), use the `NVFrobToggleStart=1` parameter.

NVHPTrigger(NVTrigger)

Sends TurnOn when an object's hit points drop to or below the value specified by `NVHitPoints`. If the hit points raise above that value again, then TurnOff is sent.

NVTrigQVar(NVTrigger)

An improved version of the standard TrigQVar script.
Watches the state of a quest variable, and sends TurnOn when its value changes to satisfy the foruma specified in the Trap->Quest Var property. If the value changes so that it no longer satisfies the formula, it sends TurnOff instead.

For details of how to use the Trap->Quest Var property, see Telliamed's excellent guide.
NVTrigQVar and NVTrapSetQVar support a few new features, however.
Firstly, you can use the name of a quest variable in place of the numerical argument, in which case the value of that variable will be used instead. For example, you could use >QVar2:QVar1 to check if Qvar1 is greater than QVar2. You can also place a question mark ('?') in front of the name of this qvar to give a random number between zero and its value.

NVTrigQVar supports the following additional operators:

Operator | Description | Example: Variable = 102
+ | Is true if the variable has just increased by exactly the argument. | (Assuming a previous value of 98) +4 is true. +2 is false. +5 is false.
- | Is true if the variable has just decreased by exactly the argument. | (Assuming a previous value of 106) -4 is true. -2 is false. -5 is false.
} | Is true if the variable has just increased by at least the argument. | (Assuming a previous value of 98) }4 is true. }2 is true. }5 is false.
{ | Is true if the variable has just decreased by at least the argument. | (Assuming a previous value of 106) {4 is true. {2 is true. {5 is false.
% | Is true if the variable can be evenly divided by the argument. | %10 is false. %17 is true %20 is false. %51 is true.

See also: NVTrapSetQVar

- AI Scripts -

NVConvEnhancer

This script is designed soley for use in AI pseudo-scripts.
It adds several new pseudo-script actions that an AI can perform via a conversation, response, etc. To use these extra actions, simply use the Script Message action, enter the name of the enhanced action into the Argument 1 box, and use Argument 2 and Argument 3 to specify the action's parameters (which vary between each enhanced action, see below.) The following enhanced actions are supported:

DelayedFrob: Frob the object specified in Argument 2 after the number of milliseconds specified in Argument 3. The pseudo-script will continue immediately. The object will be frobbed regardless of what happens to the AI during the delay (unless its object is deleted / destroyed).
GiveItem: Place the object specified in Argument 2 into the inventory of the Player object. You can use Argument 3 to specify a delay (in milliseconds) before the item is given. You can also use Argument 3 to specify the name of a destination object, if you do not want to give the object to the player. To specify both for the action, use the format `delay; destination` (for example, `2500; Footlocker3` will wait 2500ms, and then place the item into the object named Footlocker3). Don't specify the destination first.
If the object to give is abstract (an archetype) then a new object of that type will be created and given instead. Given objects will stack with other objects of that type where applicable.
SendMessage: Sends the message specified by Argument 2 to the object specified in Argument 3 . You can also use Argument 3 to specify a delay (in milliseconds) before the message is sent; use the format `delay; destination` (for example, `2500; Footlocker3` will wait 2500ms, and then send the message to the object named Footlocker3. Don't specify the destination first.
Follow: Tells the AI to start following the object specified in Argument 2, or the Player object if none is specified. The AI will navigate using the pathfinding database, and run to keep up if he or she gets too far behind. Please note that using this action will stop the AI from patrolling, and he or she will not return to the patrol or to his/her origin when the following stops. Of course, you can simply set the AI to patrol again manually, by setting the AI->Ability Settings->Patrol: Does Patrol property back to True.
StopFollowing: Tells the AI to stop following any objects he or she might be following. There are no arguments. The place that the AI is standing will become his or her new idling origin. If you absolutely must have the AI return to his or her original origins after following something, then give that AI a custom metaproperty with the AI->State->Idling: Origins property manually entered.

NVGhostingMessages

This script handles Ghosting Failed messages.
An AI with this script will cause ghosting to fail if he is injured, killed, knocked out, or his AI->State->Current Alertness is raised to 2 or higher.
Each time ghosting is failed, the mission-scope quest variable NVGhostingFailed is incremented by 1.
The first time ghosting is failed, the message "Ghosting Failed!" is displayed. If the mission-scope quest variable NVGhostingMessages is set to 1, then the message (and count) will be displayed every time ghosting is failed.
You can also use the `NVGhostingMessages=1` parameter.

This script can also be applied to normal (non-AI) objects, which will then fail ghosting when damaged or slain.
AIs who inherit from "bow man", with an AI->Ability Settings->Flee: Conditions for Flee of Never and AI->AI Core->Notices Bodies = False (the archers in "Life of the Party") will not trigger this script, nor will objects named "Cavador", or anything with the parameter `NVGhostingIgnore=1`.

You can change the default ghosting failed message by defining your own in PlayHint.str. The three strings used by the script are: GhostingFailed (displayed the first time ghosting is failed), GhostingFailed2a (the first part of the message displayed on subsequent failures - this goes before the count) and GhostingFailed2b (this goes after the count). Here is a sample of a PlayHint.str using the default messages:

> GhostingFailed: "Ghosting Failed!"
> GhostingFailed2a: "Ghosting Failed!\n(Total: "
> GhostingFailed2b: " times)"

You will probably want to include a space at the end of GhostingFailed2a and one at the start of GhostingFailed2b when writing your own custom message.

NVIncapacitatedMessages

An AI with this script will send an 'Incapacitated' message to itself when it is knocked out or killed. The message is sent just after the AI finished his or her knockout/death motion.

- Miscellaneous -

NVAttachMyObj

On Sim start or when Created ingame, this script crawls back through the inheritance of the object looking for the first ScriptParams link with a data of 'Attach'.
It then creates an object of the type linked to and adds a CreatureAttachment link from the script's object to the newly created object.
You can specifiy the attachment joint via the `NVAttachMyObjJoint` paramter.

NVComestible
System Shock 2 only.

When used in inventory, the object with this script will heal the player by one hit point and reduce its stack count by one.
It also plays a schema with the tags "Event Activate".

NVCursedObj
Not availiable for System Shock 2.

The object with this script will be permanently selected for as long as the player is carrying it.
It will be selected when the player picks it up, and will be immediately re-selected if the player tries to put it away or select another object of the same type.
When the player tries to deselect the object, the string specified by the `NVCurseMessage` parameter will be read from the string file NVCursedObj.str - if none is specified, the Default string is used. (If the file is not found, no message is displayed.)
Unless you want to drive the player mad, do not use more than one object of the same type (weapon, item) with this script. The objects will constantly be cycled every 100ms.

NVDoorStartsOpen

When applied to a door, this script causes that door to open at great speed when the mission initially starts (or when its object is created ingame). Use it to make doors start open.

NVDeathCutscene
System Shock 2 only.

If the player object has this script, then the video specified by the `NVEndVideo` parameter will be played when he dies. The filename specified must include the file extension (typically, .avi) and the file should be located in the cutscenes folder.
Note that this script will not work unless the player object has the PlayerScript script with a higher priority (in other words, it must be below PlayerScript in the script list, or on an ancestor of the object with PlayerScript).

NVEmitWhileSelected
Not availiable for System Shock 2.

The object with this script causes the player to emit objects while he has it selected in his inventory.
Upon being selected in the player's inventory (InvSelect), the script copies the Tweq->Emit and Tweq->EmitterState properties (CfgTweqEmit, StStweqEmit) from the object to the player.
The AnimS is then set to On to activate the emitter.

When the object is deselected (InvDeselect), then AnimS is set to Off to deactivate the emitter.
The emitter is also stopped when the item is automatically hidden after being selected for too long (InvDeFocus), and restarted when the object is refocused (InvFocus). You can set the parameter `NVIgnoreDeFocus=1` if you want the emitter to continue while the object is hidden.

You can specify which of the five Tweq property sets should be used via the `NVTweqNum` parameter. (For example, use `NVTweqNum=3` to use Tweq->Emit3 and Tweq->Emitter3State.)
This script will only work if the item it is applied to has the FocusScript flag in it's Engine Features->Frob Info: Inv Action.

NVExclusiveObject

When this object is created, or at the beginning of the simulation (Sim and Create messages), all other objects that inherit from its direct archetype are destroyed, to ensure that there is only ever ONE of these objects.

NVFirerHack

When placed upon the archetype of a projectile or other movavble object, this script removes the F->Firer property shortly after being thrown or fired. In other words, the object will be able to collide with the player after he throws it. For example, if the player shoots an arrow with this script straight up into the air, it will injure him when it comes down on his head.

NVHolyH2OHack (NVInvTransform)

A companian script for the standard HolyH2O; if there are no water arrows in the player's inventory when it is frobbed, it will activate an NVInvTransform.
To use it, find the HolyH2O (-2435) archetype and add it to the Script 1 field of S->Scripts, leaving HolyH2o as Script 0.
Now, add Engine Features->FrobInfo and remove the 'Use Ammo' flag from Inv Action. If you fail to do this, and you use the `NVInvTransformStack` parameter of NVInvTransform, then you will always lose one item with each transformation.

NVInvAssembly

When the object with this script is frobbed in the player's inventory, it will first take one item off its stack, and one item from the stack of the object specified in `NVAssemblyPart`, and replace them with the object specified by `NVAssembledItem`. It also plays a schema with the tags "Event Acquire" for Thief 2 or "Event Create" for System Shock 2 (from NVScript v1.0.5 and upwards). If either of the components do not exist, a message is displayed and nothing else happens. The message is read from the string file NVInvAssembly.str - the specific string to read is defined by the `NVAssemblyError` parameter.
For example:

Design Note:

> NVAssemblyPart="Broadhead"; NVAssembledItem="Water"; NVAssemblyError="shafts"

NVInvAssembly.str:

> default: "Not enough components."
> shafts: "Not enough shafts."
> gear: "You don't have enough gears to repair that."

Wih this setup, the object would combine itself and one broadhead into a water arrow, displaying the error 'shafts' ("Not enough shafts") if no broadheads are availiable. Obviously enough, no error message is displayed if the object itself is not availiable - after all, what would the player be frobbing?

NVInvAssembly2

When the object with this script is used on an object that inherits from the object specified by the `NVAssemblyPart` parameter, it will reduce the stack count of both objects by 1, and replace them by the object specified by `NVAssembledItem`. It also plays a schema with the tags "Event Acquire" (or "Event Create" in System Shock 2). Although this script is primarily designed for System Shock 2's inventory system, it can also be used in Thief via Inv to World Tool Frobs - in which case the world object is slain when its stack count reaches zero (rather than simply being destroyed/deleted).
You can specify multiple part/item combinations by simply appending a number to end of the appropriate parameter. For example, using the object with this script on an object that inherits from `NVAssemblyPart1` will replace the objects with the one specified by `NVAssemblyItem1`; using it on one that inherits from `NVAssemblyPart2` will use `NVAssemblyItem2`, and so on. Paremters numbers must be consecutive, for example, `NVAssemblyPart8` will be ignored if there is no `NVAssemblyPart7`, etc.

NVInvTransform

A base for other scripts, but it can be used on its own as well - in which case it responds to FrobInvEnd.
Transforms itself in the player's inventory into another object.
When triggered, it will transform itself into a new item of the type specified by the the `NVInvTransform` parameter.
The default is to convert the entire stack in one go; you can use the `NVInvTransformStack` parameter to only transform a certain number of the objects.

NVInventoryMemory
Not availiable for System Shock 2.

If placed upon the Player object (starting point, Avatar archetype, etc.), this script will restore the player's inventory selections when a saved game is resumed.

NVKeyringKey
Not availiable for System Shock 2.

This script handles the combination of all keys into one single keyring object.
Simply replace the StdKey script on your keys with this one, and they will merge into a single, undroppable keyring object. The keyring's Stack Count will indicate the number of keys the ring contains.
You can create multiple keyring sets. Use the `NVKeyringId` parameter to specify the keyring ID that a specific key should be added to. The default ID is 192.
Note: Do not use any locks with a RegionMask of 0 and a LockID of any used keyring ID (by default, 192) in your mission, as they will be openable by ANY key.
You can also specify the model name of the keyring via the `NVKeyringModel` parameter; the default is MKeyring. You can also specify keyring's inventory label via the `NVKeyringName` parameter; the defaults is name_keys.
In truth, this script changes the Engine Features->KeyDst property of any locked objects that would be opened by the key's Engine Features->KeySrc so that it can be opened by a single 'keyring' object (which is created if it doesn't exist). It then increases the keyring's stack count and destroys the key.
The KeySrc of this keyring is to MasterBit: False; RegionMask: 0; LockID: [As specified in `NVKeyringId`; default: 192].

NVNameOnCreation

When this object is created, or at the beginning of the simulation (Sim and Create messages), the object with this script is given the name specified by the `NVSymName` parameter, unless an object with that name already exists.
If the name is already taken, nothing will happen unless you use the `NVSymNameIncrement=1` parameter; then a number will be appended to the end of the chosen name until an unused name is found, up to 99 attempts. (For example, if you created multiple objects all set to be automatically given the name "NamedObject", then the first would be named "NamedObject", the second would become "NamedObject1", the next "NamedObject2", and so on, up to "NamedObject99".)

NVNewWeapon
Not availiable for System Shock 2.

This script allows the creation of new weapons.
It adds the metaproperty specified by `NVWeaponMeta` to the player arm object which is created when the weapon is equipped.
It also send the 'InitArm' message to the player arm, after the metaprop has been added.
One use for this script is to add a metaproperty with the Motions->Actor Tag List property, allowing you to have a weapon with its own motion set. You could also make the arm transparent or give it a script set up to trigger when it receives the InitArm message.

NVPutIntoContainers
System Shock 2 only.

When asked to tidy your room, you stare back blankly and think "But you CAN'T put things back in containers"
- d0om (1000 clues that you have been Dromeding too much, No. 92.)

This script allows its item to be placed inside containers.
The object must have the Tool Action of its Engine Features->FrobInfo set to Script for this to work.
Note that only objects that descend from the 'Usable Containers (-118)' archetype are treated as 'containers'.
Objects with unusual inventory dimensions will confuse the script (it will probably just tell the player they don't fit in the container). Also, the objects may sometimes appear in impossible arrangements inside the container when it's near its capacity.
The contents of the container should be limited to 4x4; before I placed this limit, extra contents would vanish completely from the world. It might still be possible to 'overstuff' the containers somehow - by manually adding your own Contains links, for example - so be careful.
Also, I once managed to crash ShockEd while putting things into a nearly-full container, but I'm now quite sure what caused it. If you can pin it down, please let me know.

NVSafeDoor

This script allows you to easily create safe doors such as the one seen in my C5 entry "The Haunting". Its use is fairly straightforward, but it assumes that the object it is applied to is a safe door.
When frobbed, the safe door's first joint begins to rotate, and stops when the frob button is released. The joint will snap to the nearest 36 degrees (in other words, there are only ten positions where the joint can stop). To open the safe, it must stop once on each digit in the safe's code, in the correct order, with no mistakes in between.
The combination is read from the mission-scope quest variable NVSafeDoor (you can specify a different variable via the `NVSafeQVar` parameter.)
If no combination is specified, then the safe will invent a random four-digit code when the mission starts and place that into the qvar.
If the safe is frobbed by an AI, it will automatically advance to the next correct digit in the code, and then add an AIWatchObj link from the frobbing AI to the safe's object, unless the safe is opening, in which case the AIWatchObj link is created to the object specified by the `NVSafeOpenAction` parameter (optional).
The AI->Utility->Watch: Watch link defaults property of the safe should contain a step to frob the object. See below for more specific instructions on how to set up the safe.
To have an AI open the safe, however, you should not order that AI to frob the object, but simply goto its location and then add an AIWatchObj link to it.

To set up the safe, first, create a SpecialDoors (-6181)
Set its properties as follows:

Shape->Model Name: NVSafeDoor
Schema->Class Tags: BoxType Safe
Physics->Model->Attributes:
COG Offset: 0.00 -1.00 0.00
Physics->Models->Dimensions:
Offset: 0.075 0.00 0.00
Size: 0.25 2.00 2.00
Engine Features->FrobInfo: Script, FocusScript
Engine Features->Locked: True
Render->Transparency (alpha): 1.00
Door->Rotating:
Set up however you wish. The default values are okay.

Tweq->Joints:
Halt: Stop Tweq
AnimC: NoLimit, Sim
MiscC: [None]
CurveC: [None]
Primary Joint: 1
Joint1AnimC: NoLimit, Sim
Joint1CurveC: [None]
Rate-Low-High: 12 -360 360
S->Scripts: (Please note that the order of these is important.)
Script 0: StdDoor
Script 1: NVSafeDoor
Don't Inherit: True

AI->Utility->Watch: Watch link defaults
Watch Kind: Self Entry
Priority: Normal
Trigger: Radius 8
Height: 8
Required Awareness: 0
Line Requirement: None
Minimum Alertness: 0
Maximum Alertness: 1
Exit: Link kill option: After Trigger
Kill like links: False
No test once triggered: True
Response Step 1: Play Sound/Motion
Argument 1:
Argument 2:
Argument 3: Ghost 0, Safe 0
Response Step 2: Frob Object
Argument 1: [object name/number of the safe door]
Argument 2:
Argument 3:
Response Step 3: Wait
Argument 1: 10000
Argument 2: Ghost 0, Safe 1
Argument 3:

In order for the safe to work properly, you need to have a custom motion database with the appropriate motions for the AIs, and you need to have the custom schema 'safe_loop' defined. All the files needed for the safe (including the motions, object, sounds, some example schemas and motion schemas) can be found in the 'NVSafeDoor' archive in the 3D Models section of The Nameless Tower.

NVSwapSword

When the object with this script is frobbed in the world, it will remove the sword from the player's inventory and place it at its object's location, then add itself to the player's inventory, effectively swapping itself with the player's sword.
In order to use this script, the sword must have World Action of its Engine Features->FrobInfo set to Script.
Note that the player will be able to pick up the sword he was previously carrying, so you need to either give it this script or set it's World Action to None to stop the player from taking it back up.

NVTweqMessages

Upon receiving a TweqComplete message, this script sends its object a more detailed tweq message, with the following format: "Tweq[Type]Complete[Direction]".
For example:TweqScaleCompleteForward, TweqEmitterCompleteForward, TweqAllCompleteReverse, or TweqModelsCompleteReverse. This is primarily for use with the various NVTrap scripts.

NVUnusableUnlessQVar

An object with this script will be unfrobbable in the player's inventory unless a certain quest variable, defined by NVUnusableUnlessQVar, is set (non-zero).
This script is primarily designed for making the player start without a bow; simply add this script to all arrows and he will not be able to shoot them until you set a quest variable indicating that the bow has been picked up.
The arrows will not become usable if they are currently selected when the quest variable is changed; the player must first put them away and then draw them again. Is this enough of an issue to be worth the trouble of fixing?

- Debug Scripts-

These scripts are designed soley for use by mission desginers during the design and beta-testing proccess.
They are not included in the main script module, but instead reside in NVDebug.osm - which you will need to temporarily load to use these in your mission You should make sure to remove the script module from your mission before release.

NVDifficultyDebug

If the quest variable DebugDifficulty is set, then this script sets the difficulty to its value when the game starts, and then proccesses the difficulty.
This script should only be used for playtesting purposes, and should be removed before the final mission is packaged.
It doesn't matter which object you place this script on (you probably shouldn't use it on more than one object...)
The player's hitpoints and vulnerabilities are not affected by this script, but that hardly matters.

- Version History -

v1.0.7

- New Script: NVCursedObj.
- New Script: NVSwapSword
- New Script: NVTrapSetQVar (NVTrap)
- New Script: NVTrigQVar (NVTrigger)
- New Script: NVUnusableUnlessQVar
- The 'Event Acquire' or 'Event Create' schemas are now played correctly in NVInvAssembly and NVInvAssembly2.
- The various scripts that add items to the player's inventory now force an inventory refresh in SS2.
- NVGhostingMessages: Added support for custom 'ghosting failed' messages.

v1.0.6

- Added weighted random link support to NVTrigger scripts. Added `KillLinks` parameter for random links.
- NVKeyringKey: Added support for multiple keyrings, parameters for customising model and inventory names of keyrings, and improved the locked-obj finding algorithm to properly understand the RegionMask.
- NVInvAssembly2: Added multiple part/item support.
- New script: NVDeathCutscene (SS2 only).
- Added version histroy. (!)

v1.0.5

- New script: NVEndTrap (NVTrap) (SS2 only).
- New script: NVInvAssembly2.
- New script: NVPutIntoContainers (SS2 only)
- New script: NVRecalcTrap (NVTrap) (SS2 only).

v1.0.4

- New script: NVAirlock
- New script: NVDoorStartsOpen
- New script: NVTrapConverse (NVTrap)

v1.0.3

- Added full System Shock 2 support via SS2 version.
- New script: NVHPTrigger (Yes, this was supposedly in v1.0.0.)
- New script: NVComestible (SS2 only).
- Fixed some nasty bugs in NVHolyH2O and NVInvTransform.
- NVAttachMyObj: Added attachment joint support.
- NVCreateAndLink: Added creation location paramters.

v1.0.2

- Added preliminary SS2 support via SS2 version.
- New script: NVItemGiver.
- New script: NVInvTransform.
- New script: NVInvAssembly.
- New script: NVHolyH2O.

v1.0.1

- New script: NVKeyringKey.
- NVConvEnhancer: Changed the order of arguments for the SendMessage conv enhancer; they now follow the pattern of the other conv enhancers.

v1.0.0

- First official release.
- New Script: NVAttachMyObj
- New Script: NVConvEnhancer
- New Script: NVCreateAndLink (NVTrap)
- New Script: NVDifficultyDebug
- New Script: NVEmitWhileSelected
- New Script: NVExclusiveObject
- New Script: NVFrobToggle (NVTrigger)
- New Script: NVGhostingMessages
- New Script: NVHPTrigger (NVTrigger)
- New Script: NVIncapacitatedMessages
- New Script: NVInventoryMemory
- New Script: NVKeyringKey
- New Script: NVLinkBuilder (NVTrap)
- New Script: NVNameOnCreation
- New Script: NVOnscreenText (NVTrap)
- New Script: NVRelayTrap (NVTrap) (NVTrigger)
- New Script: NVSafeDoor
- New Script: NVScaleDims (NVTrap)
- New Script: NVSuspiciousTrap (NVTrap)
- New Script: NVTweqMessages
- New Script: NVVOTrap (NVTrap)