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 Script->ObjList Args property in the same way as Telliamed's scripts:

From Telliamed's documentation:

> The Editor\Design Note Script\ObjList Args property is used to specify most parameters for a script. The Design Note ObjList Args 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 separated 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 and use its value in place of the parameter. 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. )
For example, if you wanted to have an NVRelayTrap which fired a number of times based on the number entered into a combination lock/odometer combo using the combo quest variable, you could specify `NVRelayTrapRepeat=$combo`
Note that if you want to supply the name of quest variable as a script parameter, rather than use the current value of the quest variable, then the dollar sign should not be used.

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 may not work in all circumstances). You can also precede 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 descends from the Marker archetype, while `"^FrobInert"` will affect the nearest object that has the FrobInert metaproperty (either itself or on one of its archetypes).

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

# NVTrap scripts

All the scripts labelled as NVTraps (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
Remember that if you specify `[ScriptName]On="TurnOff"` without specifying `[ScriptName]Off`, then TurnOff will be specified for both values.

`[ScriptName][On/Off]Capacitor`
Use this parameter to specify the number of times that a trap will need to receive its triggering message before it activates. For example, an NVRelayTrap with `NVRelayTrapCapacitor=3` will only relay every third message, while one with `NVRelayTrapOnCapacitor=4; NVRelayTrapOffCapacitor=2` will relay every second TurnOff message but only every fourth TurnOn message. The default is 1.
`[ScriptName][On/Off]CapacitorFalloff` can be used to specify the time, in milliseconds, that it takes for the trap to "lose charge", and the activation count to go back down by one activation.

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.

# NVTrigger scripts

All the scripts labelled as NVTriggers (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"`.
You can also specify a range of stims by specifying the minimum and maximum intensities, separated by a pipe. For example: `[ScriptName]TOn="[5.00|10.00]WaterStim"` will send a WaterStim with a random intensity between 5.00 and 10.00. Note that the result is a floating point number anywhere inside the range, it is not limited to whole numbers.

`[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]FailChance`
Use this parameter to specify a % chance that the trigger will fail (do nothing) when it is activated. For example: `[ScriptName]FailChance=35` will give the trigger a 35% chance to fail when activated.

`[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, preceded by an `&` symbol. The default is `[ScriptName]TDest="&ControlDeviceSwitchLink"`. 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="&?ControlDeviceSwitchLink"` will send the message down a random ControlDevice SwitchLink 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.
In addition, you can affect all objects within a specific radius. First enter a less-than symbol (<), then the radius, followed by a colon (:) and then the archetype name. For example: `[ScriptName]TDest="<5.00:Chest"` will affect all Chest objects or descendants withing a radius of 5.00 DromEd units. Note that the radius function will affect objects in the same way as `@` - in other words, all descendant archetypes will also be affected. By default, the radius is only calculated on the X and Y axis. To measure distance in 3-dimensional space, use the `{` symbol instead of the less-than symbol.

Below is a table with examples of each way that objects can be targeted:

Parameter value | Object(s) to target | Applies to
--- | --- | ---
ObjectName | A specific object named ObjectName. | Any parameter specifying an object.
245 | A specific object with ID 245. | Any parameter specifying an object.
[me] | This object where the script is running. | Any parameter specifying an object.
[source] | The source of the message that triggered this script. | Any parameter specifying an object.
^Marker | The closest object (relative to the object running the script) that descends from the Marker archetype. | Any parameter specifying an object.
^<20:Marker | The closest object (relative to the object running the script) that descends from the Marker archetype and is within 20 units (XY axis only). | Any parameter specifying an object.
^{20:Marker | The closest object (relative to the object running the script) that descends from the Marker archetype and is within 20 units (3-dimensional space). | Any parameter specifying an object.
&ControlDevice | All objects that this object has ControlDevice links to. | An NVTrigger script's TDest
&?ControlDevice | One random object that this object has a ControlDevice link to. The link to that object will be removed afterwards if [ScriptName]KillLinks=1 | An NVTrigger script's TDest
&Weighted | One random object that this object has a ScriptParams link to. The link is using a weighted random using the value of the ScriptParams link, with a link with a value of 2 being twice as likely to be chosen as one with a value of 1. | An NVTrigger script's TDest
*Marker | Every object in the mission that is based on the Marker archetype | An NVTrigger script's TDest
@Marker | Every object in the mission that is based on the Marker archetype or one of its descendants. | An NVTrigger script's TDest
<20:Marker | Every object within 20 units (horizontal distance only) that is based on the Marker archetype or one of its descendants. | An NVTrigger script's TDest
{20:Marker | Every object within 20 units (in all three dimensions) that is based on the Marker archetype or one of its descendants. | An NVTrigger script's TDest

# Targetting scripts

As of NVScript v1.2.0, many of the scripts allow you to specify the object(s) that they should affect, as opposed to merely affecting their own object as in previous versions of NVScript. You can do this via the `[ScriptName]Target` parameter, which generally defaults to [me] in most cases. For example, to have NVMetaTrap add and remove its metaproperty on objects linked from its object via ControlDevice links, you would use `NVMetaTrapTarget="&ControlDevice"`. Scripts which can be targetted in this way are marked as Targetable in their description.

A description of each of the scripts follows:

Traps: | Version required: | T2 | SS2
NVAirLock (NVTrap) | v1.0.4 | Yes | Yes
NVAITeamSetter (NVTrap) | v1.1.0 | Yes | ?
NVAmbientSoundTrap (NVTrap) | v1.0.8 | Yes | ?
NVCameraTrap (Trap) | v1.2.0 | Yes | Yes
NVCreateAndLink (NVLinkBuilder) | v1.0.0 | Yes | Yes
NVCutsceneTrap (NVTrap) | v1.2.2 | Yes | Yes
NVDeleteTrap (NVTrap) | v1.0.8 | Yes | ?
NVDetoxTrap (NVTrap) | v1.1.0 | No | Yes
NVDifficultyRelay (NVTrap) | v1.0.8 | Yes | ?
NVDiminishingParticles (NVTrap) | v1.0.8 | Yes | ?
NVDoorSpeedTrap (NVTrap) | v1.1.0 | Yes | ?
NVEndTrap (NVTrap) (SS2 only) | v1.0.5 | No | Yes
NVGenericScalarTrap (NVTrap) | v1.2.0 | Yes | Yes
NVGibTrap (NVTrap) | v1.1.0 | Yes | Yes
NVGlowTrap (NVGenericScalarTrap) | v1.2.0 | Yes | Yes
NVItemGiver (NVTrap) | v1.0.2 | Yes | Yes
NVLinkBuilder (NVTrap) | v1.0.0 | Yes | Yes
NVMachine (NVTrap) | v1.1.0 | Yes | ?
NVMapTrap (NVTrap) | v1.1.0 | Yes | No
NVMetaTrap (NVTrap) | v1.0.9 | Yes | Yes
NVMultiplayerTrap | v1.1.0 | No | Yes
NVOnscreenText (NVTrap) | v1.0.0 | Yes | Yes
NVParticleGroup (NVTrap) | v1.0.8 | Yes | ?
NVPhantomTrap (NVGenericScalarTrap) | v1.0.8 | Yes | Yes
NVRandomPropertyTrap (NVTrap) | v1.1.0 | ? | ?
NVRecalcTrap (NVTrap) (SS2 only) | v1.0.5 | No | Yes
NVRelayTrap (NVTrap) (NVTrigger) | v1.0.0 | Yes | Yes
NVRemovePropertyTrap (NVTrap) | v1.2.5 | Yes | Yes
NVScaleDims (NVTrap) | v1.0.0 | Yes | Yes
NVSelectTrap (NVTrap) | v1.1.0 | Yes | ?
NVSetPropertyTrap (NVTrap) | v1.2.4 | ? | ?
NVSimpleDoor | v1.0.8 | Yes | ?
NVSimpleSchemaPlayerTrap | v1.0.8 | Yes | ?
NVSlayMeTrap | v1.1.0 | Yes | Yes
NVSRContactTrap | v1.1.0 | Yes | Yes
NVStackOrDropTrap | v1..0 | Yes | Yes
NVStackTrap | v1.0.8 | Yes | ?
NVSuspiciousTrap (NVTrap) | v1.0.0 | Yes | No
NVTextureTrap | v1.0.8 | Yes | ?
NVTranslucentTextTrap | v1.2.0 | No | Yes
NVTrapSetQVar | v1.0.7 | Yes | Yes
NVTweqDevice | v1.0.8 | Yes | ?
NVTrapConverse (NVTrap) | v1.0.4 | Yes | Yes
NVVOTrap (NVTrap) | v1.0.0 | Yes | Yes
NVWakePhysicsTrap | v1.2.4 | Yes | Yes
NVWatchMeTrap | v1.2.4 | 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
NVTriggeringRoom | v1.0.8 | Yes | ?
NVTrigContained | v1.0.8 | Yes | ?
NVTrigOBB | v1.0.8 | Yes | ?
NVTrigRoomPlayer | v1.0.8 | Yes | ?
NVTrigQVar | v1.0.7 | Yes | Yes

AI Scripts: | Version required: | T2 | SS2
NVConvEnhancer DelayedFrob GiveItem SendMessage Follow
StopFollowing
CheckLock
SetQVar

v1.0.0
v1.0.0
v1.0.0
v1.0.1
v1.0.0
v1.0.0
v1.0.8
v1.2.3

Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
?
?
?
?
?
?
No
?
NVGhostingMessages | v1.0.0 | Yes | Yes
NVIncapacitatedMessages | v1.0.0 | Yes | ?

Miscellaneous Scripts: | Version required: | T2 | SS2
NVAlertMessages | v1.2.4 | Yes | Yes
NVAttachMyObj | v1.0.8 | Yes | Yes
NVAttackMessages | v1.1.0 | Yes | Yes
NVBattery (SS2 only) | v1.1.0 | No | Yes
NVCloneContactFrob | v1.0.8 | ? | Yes
NVComestible (SS2 only) | v1.1.0 | No | Yes
NVCombineTypeSetter | v1.1.0 | Yes | Yes
NVConsumeMessages | v1.1.0 | Yes | Yes
NVContainedMessages | v1.1.0 | Yes | Yes
NVCursedObj | v1.0.7 | Yes | No
NVDeathCutscene | v1.0.6 | No | Yes
NVDeathStageFix | v1.1.0 | Yes | ?
NVDoorStartsOpen | v1.0.4 | Yes | Yes
NVEmitWhileSelected | v1.0.0 | Yes | No
NVExclusiveObject | v1.0.0 | Yes | Yes
NVFakeWater | v1.0.0 | Yes | ?
NVGuaranteedLoot | v1.1.0 | No | Yes
NVHealingGland (NVMedPatchScript) | v1.1.0 | No | Yes
NVHolyH2OHack (NVInvTransform) | v1.0.2 | Yes | ?
NVInvAssembly | v1.0.8 | Yes | Yes
NVInvAssembly2 | v1.0.6 | Yes | Yes
NVInvTransform | v1.0.2 | Yes | Yes
NVInventoryMemory | v1.0.0 | Yes | No
NVInvSound | v1.0.8 | Yes | Yes
NVJointControl | v1.2.3 | Yes | ?
NVKeyringKey | v1.0.6 | Yes | No
NVMachineSlot | v1.1.0 | Yes | ?
NVMedKitScript (NVMedPatchScript) | v1.1.0 | No | Yes
NVMedPatchScript | v1.1.0 | No | Yes
NVNameOnCreation | v1.0.0 | Yes | Yes
NVNewWeapon | v1.0.0 | Yes | Yes
NVObjectWatcher | v1.1.0 | Yes | ?
NVParticleTrailProjectile | v1.0.8 | Yes | ?
NVPhysMessages | v1.1.0 | Yes | Yes
NVPickyProjectile | v1.1.0 | Yes | Yes
NVPlayerScript | v1.1.0 | No | Yes
NVPsiKitScript (NVMedPatchScript) | v1.1.0 | No | Yes
NVPutIntoContainers | v1.0.5 | No | Yes
NVQVarName | v1.1.0 | Yes | ?
NVRecycler (SS2 only) | v1.1.0 | No | Yes
NVRotatable | v1.0.8 | Yes | ?
NVSafeDoor | v1.0.0 | Yes | ?
NVShakePlayer | v1.2.0 | Yes | ?
NVSpy | v1.0.0 | Yes | Yes
NVStartUnrotated | v1.1.0 | Yes | ?
NVSwapSword | v1.1.0 | Yes | No
NVTurningSquare | v1.0.0 | Yes | ?
NVTweqMessages | v1.0.0 | Yes | ?
NVTwoSpeedDoor | v1.0.8 | Yes | ?
NVUnusableUnlessQVar | v1.0.8 | Yes | ?
NVVisibilityToQVar | v1.2.0 | Yes | ?
NVWatchMe | v1.2.0 | Yes | ?
NVWhoKilledMe | v1.1.0 | Yes | ?

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 SwitchLink (or SwitchLink for SS2)(or ControlDevice for Thief 2) 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 SwitchLink 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.

# NVAITeamSetter (NVTrap)

When the mission starts or its object is created (on BeginScript), this script sets the AI->AI Core->Team property of its object to the value specified by `NVAITeam`, or to a value equal to the object number if none is specified (effectively giving each AI a unique team). This allows you to have more than the default number of AI teams in a mission.

# NVCreateAndLink (NVTrap->NVLinkBuilder)

A derivative of NVLinkBuilder.
Upon receiving TurnOn, this script creates the object specified by `NVCreateAndLinkCreate`.
It then creates a link to the new object, with the flavour specified by `NVCreateAndLinkLinkType`.
By default, it links from the object with the script, but you can specify a source object via the `NVCreateAndLinkLinkSource` 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. (Note that you cannot use `NVCreateAndLinkLocObj` if you do not also specify `NVCreateAndLinkLoc` (try a value of `0.0,0.0,0.0` if you don't want an offset.)
You can specify data for the link in exactly the same way as you can with NVLinkBuilder, except that the parameters are `NVCreateAndLinkLinkData`#`Field` and `NVCreateAndLinkLinkData`#`Value`. The old params, that simply use 'NV' instead of 'NVCreateAndLink' will still be used as fallbacks, but as of NVScript 1.1.0, the new parameters specific to NVCreateAndLink should be used, to allow NVCreateAndLink and NVLinkBuilder to co-exist on the same object.

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.
Example: you can use the following scripts: NVCreateAndLink, NVCreateAndLink2, NVCreateAndLink3, NVCreateAndLink4, NVCreateAndLink5, NVCreateAndLink6, NVCreateAndLink7, NVCreateAndLink8, NVCreateAndLink9. In each case, replace the NVCreateAndLink in the name of each parameter with the name and number of the script you are using. e.g. `NVCreateAndLink2Create` will specify the object to create for NVCreateAndLink2.

# NVAmbientSoundTrap (NVTrap)

This script plays the schema that is linked to it via a SoundDescription link as an ambient sound.
The sound can be turned on and off by TurnOn and TurnOff messages, unlike the default AmbientSounds script.

# NVLinkBuilder (NVTrap)

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

You can specify data for the link by using `NVLinkBuilderLinkData`#`Field` and `NVLinkBuilderLinkData`#`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 `NVLinkBuilderLinkData`#`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 `NVLinkBuilderLinkData`#`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.

As of v1.2.4, you can use `NVLinkBuilderModifyExistingLink=1` to modify the data of existing link (if it exists), instead of creating a new one. The first matching link is used. Note that modifying the data (instead of removing and adding a new link) allows you to avoid behaviour such as attached objects automatically being deleted when the attachment link is removed.

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.
Example: you can use the following scripts: NVLinkBuilder, NVLinkBuilder2, NVLinkBuilder3, ... up to NVLinkBuilder4. In each case, replace the NVLinkBuilder in the name of each parameter with the name and number of the script you are using. e.g. `NVLinkBuilder2On` will specify the message to trigger NVLinkBuilder2.

# NVGenericScalarTrap (NVTrap)

Targetable: default: `[me]` (Note that the `[source]` target is not supported for this script.)

Smoothly fades one of its object's scalar properties over time.
TurnOn will make the object fade to its max setting, set via the `NVGenericScalarTrapMax` (default: 1.00) parameter, over the course of the time specified by the `NVGenericScalarTrapFadeOn` (default: 1000) parameter.
Similarly, TurnOff will make the object fade to its minimum alpha (`NVGenericScalarTrapMin` - default: 0.00) over the time specified in `NVGenericScalarTrapFadeOff` (default: 1000).
`NVGenericScalarTrapIncrement` (Default: 0.02) specifies the size of the increments by which the property will be scaled.
The property to affect is specified via the `NVGenericScalarTrapPropName` property. You can also specify the subproperty to affect via the `NVGenericScalarTrapSubPropName` property. Omit this parameter if the property does not have any sub-properties.
The script will always start from the object's current value, so if the script is sent TurnOn halfway through fading out, it will fade back in smoothly from its current level, rather than going instantly to the min value and fading to the max from that.
If the object does not have the property, then it will be assumed to have the value specified by `NVGenericScalarTrapDefault`, which defaults to 0.00.

When the fading has finished, a message will be sent to the object, specified by either `NVGenericScalarTrapOnMessage` if the fade was to the maximum value, or `NVGenericScalarTrapOffMessage` if the fade was to the minimum value. These default to FadeOn and FadeOff, respectively.

Note that this is an advanced script and requires an understanding of correct property internal names. Using an invalid property name or subproperty name will probably cause a crash.

# NVEndTrap (NVTrap)
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.

# NVGlowTrap (NVGenericScalarTrap)

Targetable: default: `[me]` (Note that the `[source]` target is not supported for this script.)

Smoothly fades its object's dynamic light over time.
TurnOn will make the object fade to its max glow, set via the `NVGlowMax` parameter, over the course of the time specified by the `NVGlowFadeOn` parameter.
Similarly, TurnOff will make the object fade to its minimum alpha (`NVGlowMin`) over the time specified in `NVGlowFadeOff`.
The defaults are to go from 0 (no dynamic light) to 100 over 1000ms.
The time is how long it would take for the object to go from the minimum glow to the maximum glow value.
The script will always start from the object's current dynamic light value, so if the script is sent TurnOn halfway through fading out, it will fade back in smoothly from its current level of light, rather than going instantly to the min value and fading to the max from that.

As of NVScript v1.2.0, you can use `NVGlowIllumMax` and `NVGlowIllumMin` to specify a maximum and minimum value for the Renderer->Self Illumination property, which will rise and fall with the dynamic light level on the object. You must specify a value for `NVGlowIllumMax` to use this feature.

When the fading has finished, a message will be sent to the object, specified by either `NVGlowTrapOnMessage` if the fade was to the maximum value, or `NVGlowTrapOffMessage` if the fade was to the minimum value. These default to GlowOn and GlowOff, respectively.

See the documentation for NVGenericScalarTrap for more information.

# NVCameraTrap (NVTrap)

Attaches the camera to the script's object on TurnOn, and returns the view to the player on TurnOff
You can use `NVCameraTrapStatic=1` to make the camera static (immovable).

Note: In SS2, this script will only work if its object has a unique name.

You can also have the remote camera automatically return after a set time via `NVCameraTrapReturnTime`, and disable player input while the camera is active by setting `NVCameraTrapDisableControls=1`. Note that the Escape key is never disabled, so the player can still escape to the menu. Also note that you must specify a return time when using the disabled controls option - if you do not, it will default to 10 seconds.

This script requires NewDark to function in Thief 1/Gold.

# NVCutsceneTrap (NVTrap)

This script plays the video clip specified by `NVCutscene` when activated (TurnOn).
The file extension must be included, e.g. `NVCutscene="Credits.avi"`. The file is played from the Movies folder (Thief) or the Cutscenes folder (SS2).

# NVDeleteTrap (NVTrap)

Targetable: default: `&ControlDeviceSwitchLink`

This script deletes all ControlDevice SwitchLink-linked objects when it receives TurnOn.
This is in contrast to the standard destroy trap script TrapDestroy TrapDestroyer, which merely slays the objects rather than deleting them.
Note that an NVDeleteTrap will not delete itself even if it is specified as the target. Use `NVDeleteTrapDeleteSelf=1` to have the trap delete itself after it has finished deleting other objects.

# NVDifficultyRelay (NVTrap)

This script relays TurnOn and TurnOff messages along ScriptParams links depending on the currently set difficulty.
Messages are sent along those links that have their data set to Difficulty#, where # matches the currently difficulty setting.
Not technically an NVTrigger, but supports message customisation like one.

# NVDetoxTrap (NVTrap)
System Shock 2 only.

When activated by TurnOn, this script detoxifies the player by the amount specified by `NVDetoxTrapAmount` (default is 1).

# NVDiminishingParticles (NVTrap)

Upon receiving TurnOn, slowly diminishes the number and lifespan of particles in its particle group over time, eventually slaying the object when there are no particles left.
Every 250ms, the number of particles is reduced by the value specified in `NVDiminishAmount`, and the particles' lifespan is decreased by 0.01. The interval can be modified via the `NVDiminishInterval` parameter.

# NVDoorSpeedTrap (NVTrap)

Multiple speed door controller.
Sets the speed of the door to the value specified by `NVDoorSpeedTrapOnSpeed` on TurnOn, and to that specified by `NVDoorSpeedTrapOffSpeed` on TurnOff.

# NVGibTrap (NVTrap)

Targetable: default: `[me]`

Upon receiving TurnOn, this script sends the object's contents flying and destroys it. The object is not slain, but destroyed / deleted.

# 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.

# NVMachine (NVTrap)

Manufacturing machine trap, for making custom machines like the ones in Soulforge Cathedral.
The machine can manufacture up to 99 recipes, each consisting of up to 10 parts. The item that is created by a recipe is specified by the `NVMachineItem#` parameter (where # is a number between 0 and 99). The parts that make up the recipe are specified by NVMachineItem#Part# parameters (where the first # is machines the recipe number, and the second # is the part number, from 0-9).
Note that the numbers must be consecutive and must start at 0.

To use this script, link its object to a physical object with a ScriptParams link with data Slot for the input slot. This object must have the NVMachineSlot script.
Link the machine to a marker with a ScriptParams link with data Output for the output hopper.
Sending TurnOn to the machine will trigger the construction. The completed item will be placed in the output hopper, along with any excess items that were thrown into the slot. If the recipe is invalid, all the items in the slot will be returned.

# NVMapTrap (NVTrap)

Upon receiving TurnOn, this script marks a specified automap location as having been visited. Use the parameters `NVMapTrapPage` and `NVMapTrapLocation` to specify the map location.

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.

This script requires NewDark to function in Thief 1/Gold.

# NVMetaTrap (NVTrap)

Targetable: default: `[me]`

Upon receiving TurnOn, this script adds the metaproperty specified by the `NVMetaTrapMeta` parameter to its object.
The metaproperty is removed on TurnOff.

You can add a delay before the metaproperty is added or removed via the `NVMetaTrapOnDelay` and `NVMetaTrapOffDelay`, both times are in milliseconds.

As of NVScript v1.1.0, you can use the `NVMetaTrapOnDelay` and `NVMetaTrapOffDelay` params to specify a delay before adding and removing the metaproperty, respectively.

As of NVScript v1.1.0, you can use the `NVMetaTrapQVar` parameter to specify a quest variable to append to the end of the metaproperty name. For example, an NVMetaTrap with `NVMetaTrapQVar="Difficulty"; NVMetaTrapMeta="M-Diff"` will check the value of the "Difficulty" quest variable, and then append that number to the end of the metaproperty name, e.g. "M-Diff0", "M-Diff1", "M-Diff3", etc.

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.
Example: you can use the following scripts: NVMetaTrap, NVMetaTrap2, NVMetaTrap3, ... up to NVMetaTrap10. In each case, replace the NVMetaTrap in the name of each parameter with the name and number of the script you are using. e.g. `NVMetaTrap2Meta` will specify the object to create for NVMetaTrap2.
Note: if the metaproperty parameter for a specific NVMetaTrap is missing, it will fall back to the generic `NVMetaproperty` parameter, regardless of which NVMetaTrap script is searching for it.

# 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 ObjList Args 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.

As of NVScript v1.1.0, you can specify a colour via the `NVOnscreenTextColour` parameter. Colours can be specified as either basic colour names (e.g. "red" or "blue"), or as a HTML-style colour code (e.g. #ff0000 or #0000ff).
Also as of NVScript v1.1.0, you can use the `NVOnscreenTextFocusRead=0` parameter to make the object not automatically display its text when focused. This can be extremely useful when used in combination with Script, FocusScript FrobInfo, as this will make the text appear on screen when the object is frobbed, and remain there for as long as the player is looking at the object.

# NVParticleGroup (NVTrap)

Targetable: default: `[me]`

Upon receiving TurnOn, this script activates its object's particles. TurnOff will deactivate them.

# NVPhantomTrap (NVGenericScalarTrap)

Targetable: default: `[me]` (Note that the `[source]` target is not supported for this script.)

Smoothly fades its object's transparency over time.
TurnOn will make the object fade to its max alpha, set via the `NVPhantomAlphaMax` parameter, over the course of the time specified by the `NVPhantomFadeOn` parameter.
Similarly, TurnOff will make the object fade to its minimum alpha (`NVPhantomAlphaMin`) over the time specified in `NVPhantomFadeOff`.
The defaults are fully invisible (0.00 alpha) to fully opaque (1.00 alpha) over 1000ms.
The time is how long it would take for the object to go from 0.00 to 1.00, so if you are using other min or max values, you will have to adjust the rates accordingly.
The script will always fade from the object's current alpha value, so if the script is sent TurnOn halfway through fading out, it will fade back in smoothly from its current transparency level, rather than going instantly to the min value and fading to the max from that.
Note that an object with 0.00 alpha is normally still (faintly) visible. To make it completely invisible, set `NVPhantomRenderInvisible=0`. This will set the Render Type to None when the alpha reaches zero. You can also use `NVPhantomRenderType` to specify which Render Type should be restored if the object becomes visible again. (The default is 0 - or "Normal".)

When the fading has finished, a message will be sent to the object, specified by either `NVPhantomTrapOnMessage` if the fade was to the maximum value, or `NVPhantomTrapOffMessage` if the fade was to the minimum value. These default to PhantomOn and PhantomOff, respectively.

See the documentation for NVGenericScalarTrap for more information.

# NVSetPropertyTrap (NVTrap)

Targetable: default: `[me]`

Assigns a value to a property upon receiving TurnOn. This is a very advanced and powerful script, but it can also crash the game or editor if not used properly.
The property to modify is specified via the `NVSetPropertyTrapProperty`. This is the internal name of the property as used by the Set Property receptron (amongst other things).
You must specify the subproperty to modify via the `NVSetPropertyTrapSubProperty` parameter, unless the property has no subproperties, in which case this parameter must be omitted.
The property will be set to the value specified in `NVSetPropertyTrapValue`.
Use the `NVSetPropertyTrapType` property to specify the type of property being set. Valid values are int and string. The default is int. Using the wrong type will probably result in a crash.

### string

The property value with be treated as a string.

### int

When setting an integer-type property, the value can instead be set to a random value between `NVSetPropertyTrapMin` and `NVSetPropertyTrapMax`. If the property is a flags value (multiple selections are possible), then use the `NVSetPropertyTrapIsFlags=1` parameter to randomly set those flags. Note that if a single value is set (via `NVSetPropertyTrapValue`), then the Min and Max will be ignored.
If you would like to prefix a string of text in front of the number, use the `NVSetPropertyTrapPrefix` parameter - the Type must be set to int, an the type of the property or subproperty being set must be a string.
Warning: attempting to use this property to put the wrong type of data into a property will probably result in a crash, e.g. putting a string (via the prefix option) into a numeric property.
The script does not currently work for floating point values or vectors. It only works for integers.
This script has only been minimally tested.

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.
Example: you can use the following scripts: NVSetPropertyTrap, NVSetPropertyTrap2, NVSetPropertyTrap4, NVSetPropertyTrap4, NVSetPropertyTrap5. In each case, replace the NVSetPropertyTrap in the name of each parameter with the name and number of the script you are using. e.g. `NVSetPropertyTrap2Property` will specify the property for NVSetPropertyTrap2.

This script is also called NVRandomPropertyTrap, and they can be used interchangeably (albeit with different param names.)

# 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 SwitchLink links. Why? Because this can be used with the various options available to NVTrap and NVTrigger scripts. You can use `NVRelayTrapDelay` to delay the message by the specified number of milliseconds. If you specify `NVRelayTrapDelayMax`, then a random delay between the time specified by `NVRelayTrapDelay` and that specified by `NVRelayTrapDelayMax` will be used. You can also use different timings for on and off messages, by using `NVRelayTrapOnDelay` and `NVRelayTrapOnDelayMax`, and `NVRelayTrapOffDelay` and `NVRelayTrapOffDelayMax`, respectively. Specific on or off delays will supersede the generic delay parameters.
If you want to abort any messages that are still waiting to be sent when the trap is triggered again, use `NVRelayTrapExclusiveDelay=1`.
You can use `NVRelayTrapRepeat` to have the trap send the message a specific number of times each time it is triggerd. Only works when `NVRelayTrapDelay` is specified. The time between each repeat is randomised if you use `NVRelayTrapDelayMax`.
Use `NVRelayTrapRepeat=-1` to repeat the message infinitely. An infinite repeat infers `NVRelayTrapExclusiveDelay=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 `NVRelayTrapRepeatOnly=1`. You can use `NVRelayTrapRepeatOnly=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.)

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.
Example: you can use the following scripts: NVRelayTrap, NVRelayTrap2, NVRelayTrap3, ... up to NVRelayTrap10. In each case, replace the NVRelayTrap in the name of each parameter with the name and number of the script you are using. e.g. `NVRelayTrap2On` will specify the message to trigger NVRelayTrap2.

# NVRemovePropertyTrap (NVTrap)

Targetable: default: `[me]`

Upon receiving TurnOn, this script removes the property specified by `NVRemovePropertyTrapProp` from its object target (by default, itself).
If `NVRemovePropertyTrapReAdd=1`, the property will be re-added to the object with its default values (useful for properties that are not inherited.)

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.
Example: you can use the following scripts: NVRemovePropertyTrap, NVRemovePropertyTrap2, NVRemovePropertyTrap3, NVRemovePropertyTrap4. In each case, replace the NVRemovePropertyTrap in the name of each parameter with the name and number of the script you are using. e.g. `NVRemovePropertyTrap2Prop` will specify the property for NVRemovePropertyTrap2.

# NVSelectTrap (NVTrap)

Upon receiving TurnOn, this script selects (or equips) the inventory item specified by `NVSelectTrapItem`.

# 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.

# NVSimpleDoor (NVTrap)

This is a very simple door script. The door will open on TurnOn and close on TurnOff, and can be toggled open/closed by frobbing it. This script has none of the other functionality of the StdDoor script and, as such, it will open the door even if it is locked.

# NVSimpleSchemaPlayerTrap (NVTrap)

A simple script that plays the schema specified by `NVSchema` at its location upon receiving TurnOn, and halts the schema on TurnOff

# NVSlayMeTrap (NVTrap)

This script slays its object when it receives TurnOn.

# NVSRContactTrap (NVTrap)

This script initiates S & R contact on its own object when it receives TurnOn.

# NVStackOrDropTrap (NVTrap)

Upon receiving TurnOn, this script checks if the player is currently carrying an item of the type specified by `NVStackOrDropTrapObject`. If he is, then the stack count of that object is increased by 1.
If the player is not carrying an item of that type, then one will be created in the world. The object will be placed at (0,0,0) unless the `NVStackOrDropTrapLoc` parameter is specified. If that parameter is given, then it is an offset from the location of the script object, or else the object specified by the `NVStackOrDropTrapLocObj` parameter. You can also use `NVStackOrDropTrapRot` to specify the rotation of the newly created object.

# NVStackTrap (NVTrap)

Targetable: default: `[me]`

This script increases the stack count of its object by 1 when it receives TurnOn, and reduces the stack count by 1 when it recieves TurnOff.
As of NVScript v1.2.0, you can use the `NVStackTrapQuantity` parameter to specify the amount that the stack should be modified by. The default is 1.

# NVTextureTrap (NVTrap)

This script can repeatedly replace textures on nearby brushes with other textures, with a specifiable delay in between, through a pre-defined list of textures.
It will first replace any nearby instances of the texture specified in `NVTextureTrap0` with the texture specified in `NVTextureTrap1`, then waits for the number of milliseconds specified by `NVTextureTrapDelay`, then replace that texture with the one specified in `NVTextureTrap2`, and so on. It will repeat this process until it runs out of valid texture name parameters.
Individual delays for each step can also be specified, by using the `NVTextureTrapDelay#` parameter, where the # is replaced by the stage you wish to specify a time for.
The trap will activate when it receives TurnOn, and will stop (at whatever texture it has reached) when it receives TurnOff.
You specify the maximum distance at which textures will be replaced via the Engine Features->Retexture Radius property. If this property is ommited, the trap will not work.
You can use the parameter `NVTextureTrapLoop=1` to have the trap loop back around to the first texture when it runs out, which will create an infinitely cycling loop.

# NVTranslucentTextTrap (NVTrap)

Displays the specified text in an overlay at the centre of the screen. The text to display is read from a string file. Use the `NVTranslucentTextTrapText` parameter to specify the string name, and the `NVTranslucentTextTrapFile` parameter to specify the filename (default is "misc" for "misc.str"). You must also specify a number that will be appended to the specified string name via the `NVTranslucentTextTrapNumber` parameter. This might be a good place to make use of the parameter dollar-sign functionality to read a quest variable instead of a number. (This is a limiation of the translucent overlay function - all string names must end in a number. 0 will be used if none is specified). You can specify the time, in milliseconds, that the text is displayed via the `NVTranslucentTextTrapTime` parameter. The default is five seconds (5000ms).

# NVTweqDevice (NVTrap)

On TurnOn, this script activates its object's joints tweq in a Forwards direction and plays schemas with tags Event Activate.
On TurnOff, it activates its object's joints tweq in a Reverse direction and plays schemas with tagsEvent Deactivate.

It will generally only operate on the primary joint; to control more than one joint, specify each of the joints to control with `NVTweqDeviceControlJoint#=1`, where # is the joint number.
For example, to control joints 1 and 2, use `NVTweqDeviceControlJoint1=1; NVTweqDeviceControlJoint2=1`

# NVSuspiciousTrap (NVTrap)
Not available for System Shock 2.

Targetable: default: `[me]`

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 (Thief) or Script->QB Name (SS2) 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 (or a mathematical expression, see below) 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.

By default, this script will write to the mission quest variable database. If you want it to use the campaign database instead, use `NVTrapSetQVarCampaign=1`. Quest variables saved in the campaign database will be persisted between missions.

You can also use the r operator to set a qvar to a random value between zero and the specified number or qvar (as opposed to the ? operator, which will add the random amount to the qvar's current value). The ^ operator will raise the quest variable to the specified power.

See also: NVTrigQVar

As of NVScript v1.2.2, you can now use a mathematical expression in the place of the numerical argument. The order of operators is respected, and terms in brackets are evaluated first. All supported mathematical operations inside the expression will be evaluated, and quest variable names can be used in the expression. The resulting number will be used in place of the numerical argument.
For example, =QVar2+(4-1)*2:QVar1 would set QVar1 to the value of QVar2 plus 6. Note that the r and d operators will not work in an expression, for obvious reasons. Spaces in the expression are ignored.

A modified version of Telliamed's guide to the operators is included below, with the new operands supported by this script.

These are the operators that are valid when used with NVTrapSetQVar.

Operator | When Turned On | When Turned Off | Example: Variable = 102
--- | --- | --- | ---
`=` | Sets the variable to the argument. | Sets the variable to 0. | `=3 → 3`
`+` | Adds the argument to the variable. | Subtracts the argument from the variable. | `+3 → 105`
`-` | Subtracts the argument from the variable. | Adds the argument to the variable. | `-3 → 99`
`*` | Multiplies the variable by the argument. | Divides the variable by the argument. | `*3 → 306`
`/` | Divides the variable by the argument. Discards the remainder. | Multiplies the variable by the argument. | `/3 → 34`
`%` | Sets the variable to the remainder of the variable divided by the argument. | multiplies the variable by the argument. | `%4 → 2`
`! |` | Sets the bits in the variable that are set in the argument. (Bitwise 'or'.) | Clears the bits in the variable that are set in the argument. | `!3 → 103`
`{` | Shifts the bits in the variable left by argument bits. (Multiplies by 2 to the power of argument.) | Shifts the bits in the variable right by argument bits. | `{3 → 816`
`}` | Shifts the bits in the variable right by argument bits. (Divides by 2 to the power of argument.) | Shifts the bits in the variable left by argument bits. | `}3 → 12`
`"` | Multiplies the variable by 10, then adds the least-significant decimal digit of the argument (the "ones" place) to the variable. Only the last 8 digits are kept.. | Divides the variable by 10. | `"13 → 1023`
`?` | Adds to the variable a random value greater than or equal to zero and less than or equal to the argument. | Subtracts from the variable a random value greater than or equal to zero and less than or equal to the argument. | `?3 → 102—105`
`d` | Adds to the variable a random value greater than zero and less than or equal to the argument. | Subtracts from the variable a random value greater than zero and less than or equal to the argument. | `d3 → 103—105`
`^` | Raises the quest variable by the power of the argument. NVTrapSetQVar only. | Calculates the root of the quest var, for the powerf of th arguemt. NVTrapSetQVar only. | `^2 → 10404`
`r` | Sets the quest variable to a random number between 0 and the argument. NVTrapSetQVar only. | Sets the quest variable to zero. | `r5 → 3—5`

# NVWakePhysicsTrap (NVTrap)

Targetable: default: `[me]`

When activated, nudges the object's physics slightly to reactive it.

# NVWatchMeTrap (NVTrap)

Targetable: default: `@human`

A remake of the WatchMe script from Thief 1 / Gold, turned into an NVTrap. On TurnOn, AIWatchObj links are created from all humans in the mission to this object. You can use the AI->Utility->Watch: Watch Link Defaults property of the object to specify the configuration of the AIWatchObj links. TurnOff will remove the links again.

The object with the script should not have any AIWatchObj links attached to it other than those controlled by the script, or things may not work as expected.

# 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.
Oh, and since Telliamed added a 'Polite' VOTrap in tnhScript v2.1 (which does nothing if it is triggered when there are AIInvest links to the player), you can use `NVPoliteVO=1` to achieve the same effect.

## - 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 SwitchLink 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.

Multiple copies: This script has multiple copies, allowing you to apply it multiple times with different parameters to the same object. Add a number after the script name to use another instance of the script, and adjust the name of the script used in the script's parameters accordingly.
Example: you can use the following scripts: NVFrobToggle, NVFrobToggle2, NVFrobToggle3, NVFrobToggle4, NVFrobToggle5, NVFrobToggle6, NVFrobToggle7, NVFrobToggle8, NVFrobToggle9, NVFrobToggle10. In each case, replace the NVFrobToggle in the name of each parameter with the name and number of the script you are using. e.g. `NVFrobToggle2Start` will specify the start state for NVFrobToggle2.

# 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.

# NVTriggeringRoom (NVTrigger)

When applied to a room, this script sends EnteredRoom and ExitedRoom message to any object which enters or exits it.
(As an NVTrigger script, both the messages and the target object can be reconfigured.)

# NVTrigContained (NVTrigger)

This script sends TurnOn messages when its object is contained (picked up) by the player, and TurnOff messages when the item is no longer contained (dropped/thrown) by the player.

# NVTrigOBB (NVTrigger)

This script acts like the standard TrigOBB script: it sends TurnOn when someone enters its radius, and TurnOff when they leave. The object must have an OBB physics model with the 'Is Edge Trigger' flag set.
By default, any object that inherits from Creature (-8) or Avatar (-2098) will activate the trigger. You can use NVTrigOBBPlayer=1 to have the script ignore creatures and only trigger when the Avatar enters its radius. Alternatively, you can use `NVTrigOBBArchetype` to specify an archetype to check for instead. Only children of the specified (or objects with the specified metaproperty) will activate the trigger.
A matching object which enters the trigger bounds will be sent the message specified by `NVTrigOBBEnterMessage` (default: NVTrigOBBEnter), and it will be sent the message specified by `NVTrigOBBExitMessage` once it leaves (default: NVTrigOBBExit).
The primary purpose of the script is to be a bounds trigger that supports the added functionality of the NVTrigger system.
In System Shock 2, the Creature (-8) and Avatar (-2098) archetypes are replaced by the Monsters (-162) and The Player (-384) archetypes, respectively.

# NVTrigRoomPlayer (NVTrigger)

This script is basically a duplicate of the standard TrigRoomPlayer script that uses the NVTrigger system.
When applied to a room, it sends TurnOn when the player enters it, and TurnOff when the player leaves.

# 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 formula 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.

By default, NVTrigQVar will only send TurnOn once when its condition becomes true, and TurnOff once when it becomes false. If you want it to send a TurnOn or TurnOff message every time the qvar is changed, use `NVTrigQVarAllowRepeats=1`

See also: NVTrapSetQVar

A modified version of Telliamed's guide to the operators is included below, with the new operands supported by this script.

These are the operators that are valid when used with NVTrigQVar.

Operator | Description | Example: Variable = 102
--- | --- | ---
`=` | Is true if the variable is exactly equal to the argument. | `=102` is true. `=101` is false.
`<` | Is true if the variable is less than the argument. | `<102` is false. `<112` is true. `<101` is false.
`>` | Is true if the variable is greater than the argument. | `>102` is false. `>112` is false. `>101` is true.
`&` | Is true if any of the bits in the argument are also set in the variable. (Bitwise 'and'.) | `&102` is true. `&2` is true. `&1` is false. `&8` is false. `&127` is true.
`"` | Is true if the lowest decimal digits in the variable, the same number as there are in the argument, are the same as the argument. | `"102` is true. `"101` is false. `"2` is true. `"1102` is false.
`+` | Is true if the variable has just increased by exactly the argument. NVTrigQVar only. | (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. NVTrigQVar only. | (Assuming a previous value of 98) `}4` is true. `}2` is true. `}`5 is false.
`}` | Is true if the variable has just increased by at least the argument. NVTrigQVar only. | (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. NVTrigQVar only. | (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. NVTrigQVar only. | %10 is false. %17 is true %20 is false. %51 is true.
`m` | Is true if the variable includes the same digit exactly the number of times specified by the argument. NVTrigQVar only. | Example using m2:QVar QVar = 1102 is true QVar = 1110 is false. QVar = 1234 is false. QVar = 1231 is true.

## - AI Scripts -

# NVConvEnhancer

This script is designed solely for use in AI conversation-style pseudo-scripts, such as those used in Conversations, AIWatchObj links, AI responses, etc.
It adds several new pseudo-script actions that an AI can perform via a conversation, response, etc.
To use these extra actions, you will need to add this script to the AI that you want to be able to perform these extra actions. In the case of conversations, the object with the conversation trap does not need any additional scripts; only the actor who is supposed to perform the actions needs the script.
The actions themselves can be triggered through any normal conversation-like system, by using 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). You can also use the third parameter to specify an object (such as a key) with which the AI should frob the object. Use the format `delay; tool` (for example, `2500; MyKey` will wait 2500ms, and then frob the object specified in Argument 2 with the object named MyKey)

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.

CheckLock: Checks if the AI is able to open the door or other locked object specified by Argument 2, and aborts the pseudoscript (conversation/AIWatchObj link/response/etc.) if (s)he can.
In other words, the remainder of the pseudoscript will only run if the AI cannot open the door.

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.

SetQVar:Sets a quest variable to a value. The quest variable operations to perform use the same syntax as NVTrapSetQVar, but the quest variable data is read from Argument 2 rather than the quest variable property.

# 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.

As of NVScript v1.2.0, you can turn off the ghosting messages for a certain difficulty by using the `NVGhostingMessagesDifficulty#=0` parameter, where `#` is the difficulty level (0 = Normal, 1 = Hard, 2 = Expert).
You can also set the colour of the message via the `NVGhostingMessagesColour` parameter (default: #FFFFFF).

# 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 -

# NVAlertMessages

Listens for Alertness messages and sends more detailed messages with the alert levels.
It will send two messages:

- One with the new alertness level: Alert0, Alert1, Alert2, Alert3
- One with both the old and the new alertness level: Alert0To1, Alert0To2, Alert0To3, Alert1To0, Alert1To2, Alert1To3, Alert2To0, Alert2To1, Alert2To3, Alert3To0, Alert3To1, Alert3To2.

# 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.

As of v1.0.8, you can have this script use ParticleAttachement links to attach the created object, instead of CreatureAttachment links, by setting the parameter `NVAttachMyObjAsParticle=1`.

# NVAttackMessages

This script adds some more messages to AIs, which can be used to trigger NVTrap scripts.
The messages are:

- StartAttackMelee - AI is starting a mêlée attack
- StartAttackRanged - AI is starting a ranged attack
- EndAttackMelee - AI has finished a mêlée attack
- EndAttackRanged - AI has finished a ranged attack
- StartWindupMelee - AI Starts winding up for a mêlée attack
- StartWindupRanged - AI Starts winding up for a ranged attack

# NVBattery
System Shock 2 only.

Fixed Battery script for SS2. This fixes the bug that would cause a battery to recharge a seemingly random amount of energy (rather than 100%) when used after moving it between levels.

# NVCloneContactFrob

When used in inventory, a clone of the object is made and a stimulus reaction is initiated between the clone and the frobber.
This script is designed to allow this system, used by Thief's healing potions, to be used in System Shock 2.

# 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".

As of v1.0.8, you can specify the number of hit points by which the object will heal the player via the `NVComestibleHeal` parameter, and you can also specify an optional number of psi points to restore via the `NVComestiblePsi` parameter.

As of v1.1.0, you can also specify a number of toxin or radtion points to heal, via the `NVComestibleDeTox` and `NVComestibleDeRad` parameters, respectively. You can also specify that a certain trait will give a bonus to the amount of healing given by the item via the `NVComestibleTrait` trait, which defaults to 2 ("Pharmo-Friendly"). If the user has the trait, then the multiplier specified by `NVComestibleTraitBonus` will be applied. This defaults to 1.20, or 120% effectiveness.
An additional bonus of 1.50 (+50% effectiveness) will also be applied if the difficulty level is 0 or 1 (Easy or Normal). This amount can be adjusted via the `NVComestibleDifficultyBonus` parameter.
Finally, another additional bonus can be applied if the quest variable specified by `NVComestibleQVar` is non-zero. This is another multiplier specified by `NVComestibleQVarBonus`, and defaults to 1.20 (+20%).

You cannot use one of these items if it will kill you (it grants negative health greater than the player's current health.)

By default, you cannot use the item if it will have no effect (full health, full psi, no radiation, no toxins.) You can override this behaviour by using `NVComestibleNoCheck=1`.
If the item cannot be used, the appropriate message will be displayed from Misc.str: "CantUseRadPatch", "ToxinNone", "PsiMaxed", "HPMaxed". In the last case, you can specify a custom message to display instead for when the player already has maximum health by using the `NVComestibleHPMaxedMessage` paramter. Note that this parameter specifies the name of a string from Misc.str - you can't enter the message directly into the parameter.

# NVCombineTypeSetter

When the mission starts or its object is created (on BeginScript), this script sets the Engine Features->Stack Count property of its object to the value specified by `NVCombineType`, or to a value equal to the object number if none is specified (effectively giving each object a unique combine type).

# NVConsumeMessages

Sends a "StackConsume" message to its object when its stack count decreased.

# NVContainedMessages

Listens for Contained messages and sends a more detailed message with the contain event.
Contained2 is sent when the object is added to a container (e.g. picked up), and Contained3 when it is removed from the container (e.g. dropped).

# NVCursedObj
Not available 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.

# NVDeathStageFix

This script monitors objects in the mission for the DeathStage property, and automatically removes it if it deems it to be inappropriate (the only known legitimate use for the DeathStage property is on objects with zero hit points, so it is left alone in that case). This should hopefully eliminate the DeathStage 12 bug.
This script can be applied to any object single in the mission. The player or starting point might be good choices. Having the script on multiple objects in the same mission is untested.

# 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 available 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.

You can also use the `NVExclusiveObjectCount` parameter (default: 1) to specify the maximum number of this tye of object that are allowed to exist at one time. If you attempt to create a new one and it would exceed this limit, then the oldest object of this type is deleted.

# NVFakeWater

This script simulates water.
It is meant to be applied to a BoundsTrigger-type object - that is to say, an OBB physics model with the 'Is Edge Trigger' flag.
When the player is inside the edges of the bounding box, then various effects are applied to give the impression of being in/under water.
Other objects entering / exiting the bounding box will have their velocity and gravity reduced.
This script will not work properly if its object is rotated.

# NVGuaranteedLoot
System Shock 2 only.

When the creature with this script dies, items will be added to its inventory with a 100% certainty. The items are specified via the `NVGuaranteedLoot#` parameters, where # is a number between 0 and 99.

# NVHealingGland
System Shock 2 only.

A variant of NVMedPatchScript set up to default to the same values as used by the standard HealingGland script. (15 hp, 1hp per 1500ms)
See NVMedPatchScript for more details.

# 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 (NVTrap, NVTrigger)

When the object with this script is frobbed in the player's inventory, it will first take one item off its stack (unless `NVSpendAssembler` is set to `0`), 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 ObjList Args:

> 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 available. Obviously enough, no error message is displayed if the object itself is not available - after all, what would the player be frobbing?

As of NVScript v1.0.8, this script can be used as an NVTrap (allowing its trigger message to be specified). To do this, set the `NVAssemblyType` parameter, as follows:
`0` - Normal behaviour (listens for FrobInvEnd)
`1` - NVTrap behaviour (listens for configuarable message, FrobInvEnd is ignored)
`2` - Double behaviour (listens for both)

Also as of NVScript v1.0.8, the script will send an Assembled (configurable via the NVTrigger system) message to the stack of the newly assembled object type in the player's inventory (again, the destination is configurable via the NVTrigger system).

# 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). Alternatively, you can specify a sound to play by adding the `NVAssembledSchema` to the object that is the result of assembly.
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 `NVAssembledItem1`; using it on one that inherits from `NVAssemblyPart2` will use `NVAssembledItem2`, and so on. Paremters numbers must be consecutive, for example, `NVAssemblyPart8` will be ignored if there is no `NVAssemblyPart7`, etc.
You can use the appropriate `NVAssemblyPart#Stack` and `NVAssembly#Stack` parameters to specify how many of the target and script object, respectively, are needed and consumed in the assembly. The number of objects returned by the assembly can be specified via `NVAssembledItem#Count`. In each of these cases, the # is either the number of the assembly in question, or omitted.

# 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 available 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.

# NVInvSound

Plays a sound with the schemas Event Activate when frobbed in inventory.

# NVJointControl

A script for controlling joints.
This script can have up to 99 joint configuration sets, each of which is activated by a message specified by `NVJointControlOn#` (where the # is the configuration set number, from 1-99; numbers must be sequential.) Each configuration set can specify the desired position and speed of any of the 6 joints, using the `NVJointControlOn#Joint#` and `NVJointControlOn#Joint#Speed` params, where the first # is the number of the configuration set, and the second # is the joint to control. If no speed is specified, the curent value from the property is used.
The joint will always take the shortest route to its destination. You can specify extreme destination angles (such as -90 instead of 270) if you want to force it to take a different route.
When a joint starts moving, a JointStarted# message will be sent to the object, and when a joint reaches its destination, a JointComplete# message is sent, where the # is the number of the joint whose movement has started or completed.

Example Design Note ObjList Args params:

> NVJointControlOn1="TurnOn"; NVJointControlOn1Joint1=180; NVJointControlOn1Joint1Speed=30; NVJointControlOn1Joint2=90; NVJointControlOn1Joint2Speed=3; NVJointControlOn2="JointComplete2"; NVJointControlOn2Joint3=-180; NVJointControlOn2Joint3Speed=30; NVJointControlOn2Joint4=270; NVJointControlOn2Joint4Speed=3

This example will activate joints 1 and 2 on TurnOn, moving joint 1 to 180 degrees at a speed of 30, and joint 2 to 90 degrees at a speed of 3. Once joint 2 reaches its destination, the second set of joints will activate, moving joint 3 to -180 degrees at a speed of 30, and joint 4 to 270 degrees at a speed of 3.

# NVKeyringKey
Not available 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 1 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: 1; LockID: [As specified in `NVKeyringId`; default: 192].

# NVMachineSlot

See NVMachine.

# NVMultiplayerTrap
System Shock 2 only.

A special level-change script that activates multiplayer mode during the level transition. This can be used to make fan missions multiplayer without using the default Earth / Station game startup. The script also activates the players' HUDs during the level change. As with any other level change marker, the destination level is specified via the Multilevel->Dest Level and Multilevel->DestLoc properties.
This script need only be used once, at the initial transition between the single-player (e.g. character creation) part of the game and the multiplayer section (e.g. the rest of the game). The result of using this script once multiplayer has already been initialised is unknown.

# NVMedKitScript
System Shock 2 only.

A variant of NVMedPatchScript set up to default to the same values as used by the standard MedKitScript script. (200 hp, 5hp per 1500ms)
See NVMedPatchScript for more details.

# NVMedPatchScript
System Shock 2 only.

A improved and customisable medical hypo script. Its effect can be adjusted with the following parameters:

Param name | Default | Description
--- | --- | ---
`NVMedPatchScriptHealTotal` | ( = 10 ) | Total amount healed
`NVMedPatchScriptHealTotal` | ( = 0 ) | Total amount of psi points restored
`NVMedPatchScriptTrait` | ( = 2 / 'Pharmo Friendly') | Trait that gives modifier
`NVMedPatchScriptTraitBonus` | ( = 1.20 ) | Multiplier for trait (e.g. Pharmo Friendly)
`NVMedPatchScriptEasyBonus` | ( = 1.50 ) | Multiplier for 'Easy' difficulty
`NVMedPatchScriptHealInc` | ( = 2 ) | HP healed per 1500ms
`NVMedPatchScriptPsiInc` | ( = 2 ) | Psi points restored per 1500ms

For any of the derivitave scripts, replace 'NVMedPatchScript' in each parameter name with the name of that script.

# 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

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.

If you want to use this script on a gun in SS2 (as of NVScript v1.1.0), you should use NVGun instead - it has all the functionality of this script, plus it sendss gun-related messages to the object when its state changes (ammo is used, condition degrades, weapon setting is changed).

# NVObjectWatcher

The object with this script will rotate to track the object specified by the `NVObjectToWatch` parameter. Its rotation will be adjusted every 50ms to always face the target object.
If you specify `NVObjectWatcherZOnly=1` then the object will only be tracked horizontally, and height differences will be ignored. The watching can be turned on and off via NVActivate and NVDeactivate messages (for some reason). If you need to control it manually, you will need to send the appropriate messages (e.g. through an NVTrigger script.)

# NVParticleTrailProjectile

This script is a workaround for a problem with projectiles that have particle trails: if the projectile object is slain, its particle is destroyed instantly. As such, the particle effect will not finish its path to the point of impact, but instantly disappear.
When a projectile with this script hits something, its attached particles are turned off and its object is hidden, to be destroyed ten seconds later. The script also creates and then immediately slays a copy of the projectile, so any corpses or particle effects associated with its impact will be created properly.
The object with this script must not have its Physics->Misc->Collision Type set to Slay on Impact or Destroy on Impact for this script to function.

# NVPhysMessages

The object with this script will receive physics-related messages: PhysMadeNonPhysical, PhysMadePhysical, PhysCollision, PhysContactCreate, PhysContactDestroy, PhysEnter, PhysExit, PhysFellAsleep, PhysWokeUp.

# NVPickyProjectile

For use on projectiles. The object with this script will ignore collisions with any object that inherits from the archetype named in `NVPickyProjectileIgnore` (in other words, it will fly straight through it.) The object will be slain if it collides with anything else. Note that the object must not have its Physics->Misc-> Collision Type set to Slay On Impact for this script to work.

# NVPlayerScript
System Shock 2 only.

This script fixes various bugs and issues in SS2. These include:

- The player's weapon becomes invisible when using Psi Invisibility (to use this, set a Transparency->Alpha on the Inviso metaproperty; this will be copied to the weapon arm models.)
- Psi Burnout no longer wastes your psi points when you have the Power Psi trait (can be disabled with `NVRegainPsiFromBurnout=0`)
- The security system no longer breaks and leaves security cameras being permanently offline if you hack security, save, and reload
- You can no longer continue to research items if you lose the required skill (e.g. due to using a LabAssistant implant)

This script must be added to the player under the standard PlayerScript script, so that it is loaded afterwards.

# NVPsiKitScript
System Shock 2 only.

A variant of NVMedPatchScript set up to default to the same values as used by the standard psi hypo, except with a delayed psi point increase rather than adding the full bonus instantaneously. (20 pp, 2pp per 1500ms)
See NVMedPatchScript for more details.

# 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 it's 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.

# NVQVarName

This script is used to make an object's name (or label) change based on the value of a qvar. The qvar is specified via the `NVQVarNameQVar` parameter.
The new name is assembled from three parts: two text strings read from ObjNames.str with the quest variable placed in the middle. The first part is specified via the `NVQVarNamePart1` parameter, and the second part is specified by the `NVQVarNamePart2` parameter and the `NVQVarNamePart2Singular` parameter. The singular value is only used if the value of the qvar is 1. This should allow you to make the name grammatically correct. The normal (plural) name will be used if this parameter is not specified.
(Somewhat illogical) example: Using the following Design Note ObjList Args will result in the item being named "Sword#Blackjack", where the # is the number of points of damage the player has dealt. If the player has dealt exactly one point of damage, the label will be "Sword1Apple" instead:

Design Note ObjList Args:

> NVQVarNameQVar="DrSDmgDealt"; NVQVarNamePart1="Name_Swords"; NVQVarNamePart2="Name_Blackjack"; NVQVarNamePart2Singular="Name_Apple"

# NVRecycler
System Shock 2 only.

Fixed Recycler script for SS2. This fixes the bug that would allow you to recycle an implant that was currently being worn, permanently applying its effect.

# NVRotatable

This script allows its object to be rotated by the player holding down the frob button on it. Its TweqRotate is activated when it receives FrobWorldBegin, and deactivated when it receives FrobWorldEnd or WorldDeSelect.
The script will send the StartRotate message to itself when it starts to rotate, and the StopRotate message one second after it has finished rotating.
The object needs to have the Script and FocusScript flags set in the World Action of its Engine Features->Frob Info property. If you forget the latter, then the object will not stop rotating if you look away from it while it is moving.

# 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.) The code must be 8 digits or less.
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 a quest variable is shorter than the code length specified by `NVSafeDoorCodeLength` (default: 4), then the code will be assumed to be padded with leading zeroes to fill out the code length (this is because quest variables, as integers, cannot have leading zeroes.) This means that if you want to use a code shorter than 4 digits, you will need to specify a shorter code length; also, if you want a code that starts with a leading zero and is longer than 4 digits , you will need a longer code length. (You do not need to specify the code length if the code is longer than 4 digits and does not start with zero.) 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.

# NVShakePlayer

This is a copy of a script from System Shock 2. When applied to the player, it causes the screen to shake when the player is hit by a ShakeStim, with the severity of the shake being dependant upon the intensity of the stimulus. The object needs to have a Send To Scripts receptron for the ShakeStim. (You may also need to create a stimulus named ShakeStim - the stimulus name is not configurable.)
The shaking takes the form of a series of jolts: one when the script is activated, and five more at 50ms intervals. To increase the length of the shaking, send additional stims to re-activate the script once the effect has finished.

This script requires NewDark to function in Thief 1/Gold.

# NVSpy

Writes every message that this script receives both to the screen and to the monolog. Useful for seeing which script messages an object receives.

You can set this script to ignore Timer messages y using the `NVSpyIgnoreTimer=1` param.

# NVStartUnrotated

An object with this script has its rotations set to 0.00° on BeginScript.

# NVSwapSword
Not available for System Shock 2.

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.
As of NVScript v1.1.0, you can use the `NVSwapSwordTarget` parameter to specify a weapon other than "Sword" to swap out.

# NVTurningSquare

Stepping inside this edge trigger will rotate the player by 180°, and teleport him to the inverse of his position relative to the turning square's centre.

# 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.

# NVTwoSpeedDoor

This script allows a door to have a different opening speed to its closing speed.
Speeds are specified via the `NVDoorOpeningSpeed` and `NVDoorClosingSpeed` parameters.

# 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.
Note that this script takes over the Engine Features->FrobInfo property of any objects that have it, so any settings applied to the object itself (rather than to its archetype) will be lost.
As of the complete rewrite of this script in v1.0.8, the arrows will become usable if they are currently selected when the quest variable is changed.

# NVVisibilityToQVar

When this script is placed upon the player, it maintains the mission-scope a qvar NVVisibilityQVar, constantly updating it to contains the player's current visibility level on a scale from 0 (invisible) to 100 (fully visible).

# NVWatchMe

Targetable: default: `@human`

A remake of the WatchMe script from Thief 1 / Gold. When an object with this script is created, AIWatchObj links are automatically created from all humans in the mission to this object. You can use the AI->Utility->Watch: Watch Link Defaults property of the object to specify the configuration of the AIWatchObj links.

# NVWhoKilledMe

When the object with this script is Slain, it will display a message based on who killed it. The message will take the format of "X was killed by Y", where the names of each party are taken from the `NVWhoKilledMeName` parameter on that object. The message " was killed by " can be specified via the `NVWhoKilledMeMsg` parameter, and its colour can bew chosen with the `NVWhoKilledMeColour` parameter.

## - 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.3.1

- NVSetPropertyTrap now supports multiple versions.
- NVSetPropertyTrap will now recalc stats if used on a Player (SS2 only)
- NVPlayerScript now sends GainedTrait# message when gaining a trait.
- NVSecurityComputer can now specify schema to play when hacked via NVSecurityComputerHackedSchema.

# v1.3.0

- Source code now on GitHub.
- A few minor bugfixes and documentation updates.

# v1.2.9

- Added full source code.

# v1.2.8

- Fixed a bug where the script state (such as activation counts, capacitors, and timer handles) of multiple scripts on the same object could get scrambled upon save/load. This changes the way all scripts store their state, and so may cause glitches in saved games made in earlier versions of NVScript, as saved script state will be lost.
- Fixed a bug with NVKeyringKey where the keyring would not be selected in inventory upon picking up a key.

# v1.2.7

- Fixed a bug with the `^` identifier used to refer to the closest object of a specified type not working if no minimum distance was specified.

# v1.2.6

- Added the following scripts to the Thief 1 / Gold module. (Note that they will only work when running NewDark):
  - NVMapTrap
  - NVCameraTrap
  - NVShakePlayer

# v1.2.5

- Re-added the missing `NVPhantomRenderInvisible` and `NVPhantomRenderType` parameters to NVPhantomTrap. (These were accidentally removed in v.1.2.0.
- Added the ability to specify a specific trigger archetype for NVTrigOBB, and also added sending of messages to the triggering object. Finally, fixed a bug where the exit trigger functionality did not work correctly in System Shock 2.
- New script: NVRemovePropertyTrap

# v1.2.4

- Fixed several bugs in NVSafeDoor.
- The "source" target will now use the stim source for scripts activated via Send to Scripts receptrons.
- New script: NVAlertMessages
- New script: NVWatchMeTrap
- New script: NVWakePhysicsTrap
- Fixed a bug where NVConvEnhancer's StopFollowing action was not correctly removing links created by the Follow action.
- Fixed an error in the documentation for NVConvEnhancer.
- Added an option to disable player controls and an automatic return timer to NVCameraTrap.
- Added an option to modify an existing link to NVLinkBuilder.

# v1.2.3

- New script: NVJointControl
- NVConvEnhancer: Added SetQVar action.
- Fixed a bug in NVGenericScalarTrap which would make it never reach 0.00 in a property.
- Fixed several bugs in NVTrigQVar, including one where the `"` operator was not working, and one where quest variable lookup was not working for quest variables with names starting with the letter 'r'.
- Updated the documentation to reflect the fact that NVLinkBuilder supports multiple versions.

# v1.2.2

- Major overhaul of NVTrapSetQVar to allow the use of complex mathematical expressions in place of the numerical argument.
- Fixed a bug where NVTrigQVar might not work properly between reloads.
- Fixed a bug in a content-getting function used by NVInvAssembly, NVHolyH2OHack, NVSwapSword, and NVStackOrDropTrap, which ought to have been causing a crash, but wasn't for some reason.
- Added documentation for NVCameraTrap. Also updated it to better support SS2.

# v1.2.1

- Fixed a bug in NVRelayTrap where it would not fall back to `NVRelayDelayMax` if a specific maximum delay for on or off was not specified. The order is now: `NVRelayTrapOnDelayMax`, then `NVRelayTrapDelayMax`, and finally `NVRelayDelayMax`. The last variant will obviously not work with the multiple script feature.
- Added documentation for NVMachine.
- Fixed some errors in the documentation.
- Removed a debug message accidentally left in NVGenericScalarTrap.
- Fixed a bug in NVGenericScalarTrap which could make it go slightly above the max or slightly below the min before stopping.

# v1.2.0

- Implemented a new targeting system for the following scripts:
  - NVMetaTrap
  - NVDeleteTrap
  - NVGibTrap
  - NVParticleGroup
  - NVPhantomTrap
  - NVStackTrap
  - NVSuspiciousTrap
  - NVGenericScalarTrap
  - NVGlowTrap
  - NVWatchMe>
- New script: NVGenericScalarTrap
  - NVPhantomTrap and NVGlowTrap are now subtypes of this script.
- New script: NVWatchMe
- New script: NVVisibilityToQVar
- New script: NVTranslucentTextTrap
- New script: NVShakePlayer
- Add difficulty levels and text colours to NVGhostingMessages.
- Added Renderer->Self Illumination feature to NVGlowTrap
- Added r operator to NVTrapSetQVar
- Added m operator and `NVTrigQVarAllowRepeats` param to NVTrigQVar
- Fixed a crash bug.

# v1.1.0

- New script: NVAITeamSetter
- New script: NVAttackMessages
- New script: NVBattery (SS2 only)
- New script: NVCombineTypeSetter
- New script: NVConsumeMessages
- New script: NVContainedMessages
- New script: NVCutsceneTrap
- New script: NVDeathStageFix
- New script: NVDetoxTrap (SS2 only)
- New script: NVDoorSpeedTrap
- New script: NVGlowTrap
- New script: NVGibTrap
- New script: NVGuaranteedLoot (SS2 only)
- New script: NVHealingGland (SS2 only)
- New script: NVMapTrap (T2 only)
- New script: NVMedKitScript (SS2 only)
- New script: NVMedPatchScript (SS2 only)
- New script: NVMultiplayerTrap (SS2 only)
- New script: NVPickyProjectile
- New script: NVPlayerScript (SS2 only)
- New script: NVQVarName
- New script: NVRecycler (SS2 only)
- New script: NVPsiKitScript (SS2 only)
- New script: NVRandomPropertyTrap
- New script: NVSelectTrap
- New script: NVSlayMeTrap
- New script: NVSRContactTrap
- New script: NVStackOrDropTrap
- New script: NVStartUnrotated
- New script: NVWhoKilledMe
- Added new functionality to NVComestible.
- Added `NVOnscreenTextFocusRead` parameter to NVOnscreenText
- Added multiple copies of NVRelayTrap, NVMetaTrap and NVCreateAndLink.
- Updated NVSwapSword to allow swapping of other weapons, such as the blackjack.
- Fixed a bug in NVUnusableUnlessQvar

# v1.0.9

- Fixed a bug that had broken the NVKeyringKey script.

# v1.0.8

- New script: NVAmbientSoundTrap (NVTrap)
- New script: NVCloneContactFrob
- New script: NVDeleteTrap (NVTrap)
- New script: NVDifficultyRelay (NVTrap)
- New script: NVDiminishingParticles
- New script: NVInvSound (NVTrap)
- New script: NVMetaTrap (NVTrap)
- New script: NVParticleGroup(NVTrap)
- New script: NVParticleTrailProjectile
- New script: NVPhantomTrap (NVTrap)
- New script: NVRotatable
- New script: NVSimpleDoor (NVTrap)
- New script: NVSimpleSchemaPlayerTrap (NVTrap)
- New script: NVStackTrap (NVTrap)
- New script: NVTextureTrap (NVTrap)
- New script: NVTrigOBB (NVTrigger)
- New script: NVTrigContained (NVTrigger)
- New script: NVTrigRoomPlayer (NVTrigger)
- New script: NVTwoSpeedDoor
- New script: NVTweqDevice
- Completely rewrote NVUnusableUnlessQVar - it will now respond to the quest variable changing while the player has its object selected in inventory.
- Completely rewrote NVSwapSword - it should now be a lot more reliable.
- Added new functionality to NVInvAssembly - it can now be used as an NVTrap, and sends a message (via the NVTrigger system) to the assembled object's stack.
- NVConvEnhancer: Added CheckLock action. Also fixed a bug that would cause the Follow action to crash in SS2.
- Fixed a nasty by in NVNewWeapon that could crash the game when the script was unloaded.
- Fixed a bug that was causing NVCreateAndLink to not work anymore. Unsure when that bug crept in..
- Added FailChance functionality to all NVTrigger scripts.
.

# v1.0.7

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

# 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 history. (!)

# v1.0.5

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

# v1.0.4

- New script: NVAirlock
- New script: NVDoorStartsOpen
- New script: NVTrapConverse

# 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)