Morrowind Script Extender Scripting
January 28, 2007 - the MWSE team
www.sourceforge.net/projects/mwse
So you want to write scripts using the new MWSE functions? If you don't know how to write normal Morrowind scripts,
please go read GhanBuriGhan's 'Morrrowind Scripting for Dummies' and at least learn the basics of writing the standard
scripts in the Construction Set then come back here.
Writing extended scripts is only slightly more difficult than the standard scripts. MWSE adds over 80 new functions,
2 new types, and alternate set, if, and while statements for use with the new functions.
Compiling Scripts with the Extended Functions
The New String and Reference Variable Types
Assignment with the New 'setx' Command
Flow Control Blocks with 'ifx' and 'whilex'
The Functions
Sample Scripts
Compiling Scripts with the Extended Functions
To compile the scripts, use the MWEdit, available from www.sourceforge.net/projects/mwedit. This editor provides
support for all of the new MWSE functions. You may need to replace customfunctions.data
with the
version provided by MWSE; this file defines the MWSE functions (and other custom functions).
The Construction Set doesn't support these new functions, but you will want to use it for all of the non-script
portions of your plug-in. You can also use the Construction Set to edit your scripts, but it will give errors
when you try to compile and save the scripts. We recommend that you create the scripts using the Construction Set
and attach them to the appropriate objects as needed. Then you can write the contents of those scripts using
MWEditSE.
Note that both string and reference variables are recorded as long in the scripts
but they are not interchangable. In addition, if you use an invalid string or reference value,
Morrowind will crash; this is especially something you need to watch out for when games are loaded, as
string and reference variables are not saved with the game.
MWEdit does not provide the full functionality of the Construction Set, and may have other issues. We recommend using MWEdit only
to edit and compile your scripts; use the Construction Set for all other tasks. In addition, loading only the plugin with the scripts you need to compile seems to
help. If you have problems, you can always ask someone else to compile them for you.
The New String and Reference Variable Types
The MWSE functions make use of two new variable types, string and reference. Both are actually declared in the scripts
using the "long" type. In the sample scripts, the 'invitem' varible is treated as a string by the extended
functions. The 'invref' and 'pcref' are both reference types. (The 'invcount' really is a long variable.)
Strings and references are returned by some of the extended functions. The descriptions of the extended functions
explain which type they expect. Be careful because the compiler doesn't verify that you are using the correct type.
The REF, reference, variables provide a way to keep track of specific objects in the game world. They are most
commonly used on the left side of the -> operator with other functions (new or old) to affect that object.
Reference values and strings become invalid each time the game is loaded or reloaded.
Assignment with the New 'setx' Command
Unfortunately, the new functions can't be easily integrated with the standard script functions and commands. A
'setx' command is provided as a substitute for 'set' when you are using a new function. You can only put one
function or one string value on the right side of 'setx' but it does allow more than one variable on the left
for functions like 'xInventory' that return multiple values (just separate the list with commas like the example
above).
Again, the compiler doesn't do enough error checking, so if you use a function like xInventory that returns three
items, be sure you put three variables on the left side to accept the results. Be sure you don't put too many either.
Flow Control Blocks with 'ifx' and 'whilex'
The standard Morrowind script if and while commands do not work when the body of the block contains extended
commands, instead use ifx and whilex. The ifx and whilex do not currently support a full syntax, I would just
use a single value or function for now. The ifx/whilex will be performed if the value is not zero. You can
use 'else' with 'ifx' but not 'elseif' and there isn't an 'elseifx'.
If you have a multiple stage if/elseif section it's frequently possible to isolate the new functions to only
one or two sections, so check all of the others first then use statements like the following.
OLD VERSION | NEW VERSION |
if ( state == 5 )
; section for 5
else
; section for not 5
endif
|
set temp to ( state - 5 )
ifx ( temp )
; section for not 5
else
section for 5
endif
|
It's OK to leave the first section blank, so this also works:
OLD VERSION | NEW VERSION |
if ( state == 5 )
; section for 5
endif
|
set temp to ( state - 5 )
ifx ( temp )
else
section for 5
endif
|
The Functions
Types listed as STRING and REF are really stored in long
variables. Functions listed with
ref->
operate on a target which might be provided by the ->
operator, might be provided by the xSetRef
function, or could be the target of the script.
|
References |
xSetRef, xRefType, xGetRef,
xGetCombat, xGetPCTarget,
xFirstNPC, xFirstItem,
xFirstStatic, xNextRef
|
|
Math |
xDistance, xSqrt, xHypot,
xDegRad, xRadDeg,
xCos, xSin, xTan,
xArcCos, xArcSin, xArcTan
|
|
AI and Movement |
xAITravel, xPlace, xPosition,
xPositionCell, xStartCombat
|
|
Inventory |
xInventory, xNextStack,
xContentList,
xAddItem, xRemoveItem,
xHasItemEquipped,
xEquip,
xDrop,
xAddSpell,
xRemoveSpell
|
|
Attributes |
xGetBaseStr, xGetBaseInt,
xGetBaseWil, xGetBaseAgi,
xGetBaseSpe, xGetBaseEnd,
xGetBasePer, xGetBaseLuc
|
|
NPC Properties |
xIsFemale, xIsTrader,
xIsTrainer, xIsProvider,
xGetService, xSetService,
xModService,
xGetBaseGold, xGetGold,
xSetBaseGold, xSetGold
|
|
Item Properties |
xGetValue, xGetOwner, xGetWeight,
xGetEncumb, xGetQuality,
xGetCondition, xGetMaxCondition,
xGetCharge, xGetMaxCharge,
xSetValue, xSetWeight,
xSetQuality, xSetCondition,
xSetMaxCondition,
xSetCharge, xSetMaxCharge
|
|
Keyboard Input |
xKeyPressed, xTextInput,
xTextInputAlt
|
|
File I/O |
xFileRewind, xFileSeek,
xFileReadText, xFileWriteText,
xFileReadShort, xFileReadLong,
xFileReadFloat, xFileReadString,
xFileWriteShort, xFileWriteLong,
xFileWriteFloat, xFileWriteString
|
|
Strings |
xPCCellID, xRefID, xMyCellID,
xGetName, xSetName,
xGetBaseID,
xStringCompare, xStringLength,
xStringParse,
xStringBuild, xStringMatch,
xLogMessage,
xMessageFix
|
- xSetRef reference (long)
-
This function provides a way of calling object
functions where the syntax does not allow for it, e.g.
set myalchemyskill to myobject->GetAlchemy
does not work because the original set statement does not allow the use of variables as objects,
in this case you should use:
xSetRef myobject
set myalchemyskill to GetAlchemy
- type (long): ref->xRefType
- Gets the object type of the reference and is literally
the four byte of the type name as a number.
- 1230259009 = ACTI (Activator)
- 1212369985 = ALCH (Alchemy/Potion)
- 1095782465 = APPA (Alchemy Apparatus)
- 1330467393 = ARMO (Armour)
- 1263488834 = BOOK (Book/Scroll)
- 1414483011 = CLOT (Clothing)
- 1414418243 = CONT (Container)
- 1095062083 = CREA (Creature)
- 1380929348 = DOOR (Door)
- 1380404809 = INGR (Ingredient)
- 1129727308 = LEVC (Levelled Creature)
- 1230390604 = LEVI (Levelled Item)
- 1212631372 = LIGH (Light)
- 1262702412 = LOCK (Lockpick)
- 1129531725 = MISC (Misc. Item)
- 1598246990 = NPC_ (NPC)
- 1112494672 = PROB (Probe)
- 1095779666 = REPA (Repair Tool)
- 1414546259 = SCPT (Script)
- 1195658835 = SNDG (Sound Generator)
- 1413567571 = STAT (Static)
- 1346454871 = WEAP (Weapon)
- reference (long): ref->xGetRef object_id (string)
- Returns a reference to one of the active objects matching
the objectid or a 0 if no active object is found. Active objects are in one of the loaded cells or are
persistent like NPCs. This is most useful to locate NPCs and unique objects. If you try to find a mudcrab you
could either find none (if you are far from the coast) or one of the many nearby (if you are near the coast).
-
reference (long): ref->xGetCombat
- Returns a reference to this NPC/creature's combat target
or 0 if the NPC/creature is not in combat.
-
reference (long): xGetPCTarget
- Returns a reference to the object in the player's crosshair
or 0 if the player is not looking at anything that can be manipulated by the player.
-
reference (long): xFirstNPC
- Returns a reference to one of the NPCs or Creatures in the
players cell or 0 if there are none. The reference is simply the one on the top of a list of all NPCs and
Creatures in the cell and you can use the xNextRef function to find the rest.
-
reference (long): xFirstItem
- Returns a reference like FirstNPC except this one is the top
of a list of ordinary objects the player can activate (and usually carry).
-
reference (long): xFirstStatic
- Returns a reference like FirstNPC except this one is the top
of a list of static objects (the non-carriable, non-interactive ones).
-
reference (long): xNextRef current (reference, long)
- Returns the 'next' reference in one of the three lists of
objects in the current cell (NPC, Item, and Static) after the current one. If the player is outside, the list
will cycle through all 9 loaded exterior cells which may be too much to do in a single frame.
-
distance (float): ref
->
xDistance target (reference)
- Similar to the original GetDistance function but takes a
reference variable as the target instead of an objectid string. Like the original, it uses the editor position
not the current position for non-persistent objects.
-
root (float): xSqrt x (float)
- Returns the square root of the value. (Use Tribunal's
GetSquareRoot instead.)
-
hypotenuse (float): xHypot a (float), b (float)
- Returns the hypotenuse for sides a and b, c = sqrt(a*a + b*b).
Unlike xSqrt this is more efficient than calculating the formula inside the script.
-
radians (float): xDegRad degrees (float)
- Converts a value from degrees to radians.
-
degrees (float): xRadDeg radians (float)
- Converts a value from radians to degrees.
-
cosine (float): xCos radian (float)
- Returns the cosine of the angle (which given in radians).
-
sine (float): xSin radian (float)
- Returns the sine of the angle (which given in radians).
-
tangent (float): xTan radian (float)
- Returns the tangent of the angle (which given in radians).
-
radians (float): xArcCos cosine (float)
- Returns the arc cosine (in radians) of the value.
-
radians (float): xArcSin sine (float)
- Returns the arc sine (in radians) of the angle.
-
radians (float): xArcTan tangent (float)
- Returns the arc tangent (in radians) of the angle.
-
ref
->
xAITravel x (float), y (float), z (float)
- A wrapper function for the original AiTravel to allow
variables.
-
new_object (reference): xPlace objectid (string)
- Places an object of type objectid behind the player
and returns a reference to the new object.
-
ref
->
xPosition x (float), y (float), z (float), rotation (float)
- A wrapper function for the original Position to allow
variables.
-
ref
->
xPositionCell x (float), y (float), z (float), rotation (float), cellname (string)
- A wrapper function for the original PositionCell to
allow variables.
-
ref
->
xStartCombat target (reference)
- A wrapper for the original StartCombat to take variables.
-
objectid (string), count (long), next (reference): ref
->
xInventory
- Returns three values based on the inventory of the
current container, NPC, or creature. The first is the objectid of one of the items in inventory. The
second is the number of that particular item found in the inventory. The third is a reference that can
be passed to the xNextStack function to find the rest of the items in the inventory. All three results
will be 0 if there are no items in the inventory (and just the third will be zero if there is only one
item in the inventory). (It is not possible to get a normal reference to objects inside an inventory.
The reference returned by this function is of a unique type and should only be used with xNextStack.)
-
objectid (string), count (long), next (reference): xNextStack next (reference)
- Returns the next item in the inventory stack. The
parameter to this function is the third result from either xInventory or this function. Attempts to pass
any other kind of reference to this function or use this reference with other functions will result in
errors and possibly crash the game. If the inventory of the current NPC, creature, or container is
changed (items added or removed) it will make the current stack reference invalid and you should get a
new stack reference with xInventory.
-
objectid (string), count (long), type (long), value (long), weight (float), name (string), next (reference):
ref
->
xContentList next (reference)
- An alternative to both the xInventory and xNextStack
functions, which returns seven values based on the inventory of the current container, NPC, or creature
rather than three. If the input parameter value is 0, the first item in the current container, NPC, or
creatures is returned (like xInventory). The seventh (last) value returned can also be used as the input
parameter to access the next item in the inventory (like xNextStack). Whenever the items in the container
change, the next reference may be invalid and you should start again with a value of 0 for the input
parameter.
The first return value is the objectid of one of the items in inventory. The second is the number of that
particular item found in the inventory. The third is the type of that item using the codes listed for
the xRefType function. The next three parameters are the value, weight, and printable name of the item
unless the object is of the Levelled Item type. For LEVI objects, the value and weight will be listed
as 0 and the name field will contain a randomly selected object id for one random item selected from the
levelled list. The normal levelled list rules aren't followed and lower level items are always more
likely than higher level items. (In the future, the selection of random items may be improved.)
-
ref
->
xAddItem objectid (string), count (long)
- A wrapper for the original AddItem to take variables.
-
ref
->
xRemoveItem objectid (string), count (long)
- A wrapper for the original RemoveItem to take variables.
-
equipped (long): ref
->
xHasItemEquipped objectid (string)
- Returns 1 if the npc or creature has the object
equipped or 0 otherwise.
-
ref
->
xEquip objectid (string)
- A wrapper for the original Equip to take variables.
-
ref
->
xDrop objectid (string), count (long)
- A wrapper for the original Drop to take variables.
-
ref
->
xAddSpell spellid (string), count (long)
- A wrapper for the original AddSpell to take variables.
-
ref
->
xRemoveSpell spellid (string), count (long)
- A wrapper for the original RemoveSpell to take variables.
-
strength (float): ref
->
xGetBaseStr
- Returns the base (unmodifed) strength for the NPC.
-
intelligence (float): ref
->
xGetBaseInt
- Returns the base (unmodifed) intelligence for the NPC.
-
will (float): ref
->
xGetBaseWil
- Returns the base (unmodifed) willpower for the NPC.
-
agility (float): ref
->
xGetBaseAgi
- Returns the base (unmodifed) agility for the NPC.
-
speed (float): ref
->
xGetBaseSpe
- Returns the base (unmodifed) speed for the NPC.
-
endurance (float): ref
->
xGetBaseEnd
- Returns the base (unmodifed) endurance for the NPC.
-
personality (float): ref
->
xGetBasePer
- Returns the base (unmodifed) personality for the NPC.
-
luck (float): ref
->
xGetBaseLuc
- Returns the base (unmodifed) luck for the NPC.
-
female (long): ref
->
xIsFemale
- Returns 1 if the NPC is female and 0 otherwise.
-
trader (long): ref
->
xIsTrader
- Returns a 0 if the NPC/creature doesn't barter
for items, otherwise it is a value that represents the combination of items the merchant will trade.
New functions for each individual type are needed.
-
trainer (long): ref
->
xIsTrainer
- Returns a 1 if the NPC/creature is a Trainer and 0
otherwise.
-
provider (long): ref
->
xIsProvider
- Returns a non-zero value if the NPC/creature sells
spells, repairs armor and weapons, or is an enchanter or spell maker. Otherwise it returns a 0.
-
service_mask (long): ref
->
xGetService service_mask (long)
- Combines the features of xIsTrader, xIsTrainer, and
xIsProvider in a single function with one return value. The service values are shown in the following
table and if an NPC offers more than one service the sum of the service numbers will be returned. The
mask parameter can be used as a filter to limit the return value to only consider the services indicated.
Value | Service |
1 | Barters for Weapons |
2 | Barters for Armour |
4 | Barters for Clothing |
8 | Barters for Books |
16 | Barters for Ingrediants |
32 | Barters for Lockpicks |
64 | Barters for Probes |
128 | Barters for Lights |
256 | Barters for Alchemical Apparatus |
512 | Barters for Repair Tools |
1024 | Barters for Miscellaneous Items |
2048 | Sells Spells |
4096 | Barters for Enchanted Items |
8192 | Barters for Potions |
16384 | Provides Training |
32768 | Provides Spellmaking Service |
65536 | Provides Enchanting Service |
131072 | Repairs Armor and Weapons |
Use a mask of 16384 to see if the NPC is a trainer and the function will either return 16384 or 0.
Use a mask of 96 (32+64) to see if the NPC sells thieving equipment. The value returned could be
0, 32, 64, or 96, but won't any other values even if the NPC provides other services too.
-
ref
->
xSetService service_mask (long)
- Uses the value parameter to change the NPC to
offer the set of services represented by the number. The service number values are used and any old
services are ignored, so using a value of 8 will make the NPC a bookseller and a value of 131587
(1+2+512+131072) is typical for smiths. The values changed by this function are not permanent and
may be reset after 72-hours or a game reload.
-
ref
->
xModService service_mask (long)
- Uses the value parameter to modify the services
offered by an NPC. A positive value adds that service (or set of services) to those already offered.
A negative value will remove a service or service. The changes are not permanent.
-
gold (long): ref
->
xGetBaseGold
- Returns the base amount of barter gold assigned to
the NPC (or creature) in the Construction Set. This is the value that resets automatically each day.
-
gold (long): ref
->
xGetGold
- Returns the current amount of barter gold possessed by
the NPC (or creature). The base gold amount is used if you haven't bartered with the NPC/creature recently.
-
ref
->
xSetBaseGold gold (long)
- Changes the base amount of barter gold assigned to
the NPC (or creature). Unfortunately this change won't be saved with the save game so you will need to
reset it after each game reload or after the "72-hour bug" affects the merchant.
-
ref
->
xSetGold gold (long)
- Changes the current amount of barter gold possessed
by the NPC (or creature). This value is stored in save game files so it will survive a game reload.
Setting this will have no effect if you haven't recently bartered with the NPC/creature. (But setting
both this and the base gold amount at the same time will likely do what you want.)
-
value (long): ref
->
xGetValue
- Returns the gold value of the object. Objects that
can't be sold return 0.
-
owner (string): ref
->
xGetOwner
- Returns a 0 if the object is not owned, the objectid
of the owner of the item if it is owned by a specific NPC or the string "unknown" if it is owned by a
faction or controlled by a variable.
-
weight (float): ref
->
xGetWeight
- Returns the weight of the object for carriable objects.
Returns the maximum capacity of a container and 0 for all other objects. (When the player places multiple
copies of one item on the ground the stack is considered one item and this function will calculate the value
for the group not just a single item of that type.)
-
encumberance (float): ref
->
xGetEncumb
- Returns the total weight of all objects in the inventory
of a container, NPC, or creature. Levelled list items don't have a weight but they are assigned a weight
of 0.001 by this fnction. If any of the items in the group are respawning items then the resulting weight
will be negative.
-
quality (float): ref
->
xGetQuality
- Returns the quality of alchemical apparatus, lockpick,
probe, and repair tool items.
-
condition (long): ref
->
xGetCondition
- Returns the current condition for armor and weapons
and remaining uses for lockpicks, probes, and repair tools.
-
condition (long): ref
->
xGetMaxCondition
- Returns the maxium condition for armor and weapons
and maximum uses for lockpicks, probes, and repair tools.
-
charge (float): ref
->
xGetCharge
- Returns the current charge on a 'cast when used' or
'cast when strikes' enchanted item. Constant effect and non-enchanted items return 0.
-
charge (float): ref
->
xGetMaxCharge
- Returns the maximum charge on an enchanted item.
-
success (long): ref
->
xSetValue value (long)
- Sets the gold value of the object. Returns 1 if succesful,
0 if failed.
-
success (long): ref
->
xSetWeight weight (float)
- Sets the weight of the object. Returns 1 if succesful,
0 if failed.
-
success (long): ref
->
xSetQuality quality (float)
- Sets the quality of alchemical apparatus, lockpick,
probe, and repair tool items. Returns 1 if succesful, 0 if failed.
-
success (long): ref
->
xSetCondition condition (long)
- Sets the current condition of armor and weapons.
Armor must not be at 100% or this function will fail. It must have already sustained some damage.
Returns 1 if succesful, 0 if failed.
-
success (long): ref
->
xSetMaxCondition condition (long)
- Sets the maxium condition for armor and weapons
and maximum uses for lockpicks, probes, and repair tools. Returns 1 if succesful, 0 if failed.
-
success (long): ref
->
xSetCharge charge (long)
- Sets the current charge on a 'cast when used' or
'cast when strikes' enchanted item. May not work if the item has never been used. Returns 1 if succesful, 0 if failed.
-
success (long): ref
->
xSetMaxCharge charge (long)
- Returns the maximum charge on an enchanted item.
Returns 1 if succesful, 0 if failed.
-
code (long): ref
->
xKeyPressed code (long)
- Monitors the status of the keyboard (and mouse buttons).
This can be similar to GetPCSneaking, but actually detects whether a particular key is really being pressed.
If input parameter code is a Virtual Key Code (between 1 and 254) the return value will indicate the status
of that key and a non-zero value means the key is being pressed. If the input code is 0, then on each call,
the function will return the key code for the key (or one of the keys) currently being pressed. The specific
values for the virtual key codes can be found in the Microsoft documentation at
http://msdn.microsoft.com. Some of the codes match different keys
on different keyboard layouts.
-
length (long), text (string): ref
->
xTextInput message (string), endcode (long)
- This allows you to directly read keyboard input from
the user and the results will be returned as a string. Pass a string and a virtual key code to the function.
The function will wait for a key to be pressed and then take one of three actions. If the key pressed
matches the endcode parameter, the string and its length are returned. If the key pressed is a printable
ASCII character, the character is added to the string and the string and the number 0 are returned. If the key is
RETURN or BACKSPACE, a new line is started or one character is removed from the string, and the modifed
string and a 0 are returned. The function returns after each key press so that the current value of the
string can be shown with xMessageFix and MessageBox but the string should only be used normally after the
length is returned. Player controls should be disabled while this function is used.
Example:
long endchar
long message
long length
ifx ( endchar )
else ; Initialization needed when endchar == 0
DisablePlayerControls
set endchar to 13 ; RETURN key
setx message to xStringBuild "" ; Empty string to start
set length to 0
return
endif
ifx ( length )
else ; Actual string edit while length == 0
setx length message to xTextInput message endchar
; Three boxes, makes it appear as if there is one set that changes.
MessageBox ""
; Spaces and trailing % hide old characters while using Backspace.
xMessageFix "%s %" message
MessageBox " "
MessageBox "Enter a message and press ENTER when it is complete."
return
endif
EnablePlayerControls ; The message is complete now
-
length (long), text (string): ref
->
xTextInputAlt message (string), endcode (long)
- This function is identical to xTextInput except that
the function simply checks the status of keys and returns immediately rather than waiting for a key to be
pressed.
-
xFileRewind filename (string)
- Moves the current reading position to the start of
the file. Call this or xFileSeek at the start of any script which uses file reading or writing functions,
otherwise you will have problems with the current file position not being as expected.
-
xFileSeek filename (string), offset (long)
- Moves the current reading position to the specified
offset in the file. You should call this or xRewind every frame before using other file functions.
(This function isn't very useful if the file contains string data.)
-
matches (long), ...: xFileReadText filename (string), pattern (string)
- Read a text string from from the file at the current
reading position. The current position is then advanced. The pattern string is then used to extract data
from the string just read; the first return value indicates how much of the pattern is matched. The values
matched by the pattern are also returned. The patterns and return values are the same as for the
xStringParse function with one addition: placing a single % sign at the end of the pattern will cause the
read routine to stop when it gets to the end of a line (CR/LF) allowing you to use this to read a normal
text file instead of a binary file. Without the trailing % sign on the pattern this will read up to the
first NULL character or to the end of the file if it doesn't find a NULL character.
-
xFileWriteText filename (string), format (string), ...
- Writes formatted string to the file at the current
position and advances. The file is then truncated at the current position (just after the end of the
new value), so you cannot use this to modify the values in the middle of an existing file. The formatting
rules are the same as for the xStringBuild function with one addition. Placing a % at the end of the
pattern will suppress the NULL that is normally printed, so a format string ending with "%N%" can be
used to create a normal text file.
-
count (long), ...: xFileReadShort filename (string), count (long)
- Reads the number of SHORTS (2 bytes) requested
from the file at the current reading position. The current position is then advanced. Returns the
number of values actually read followed by the values.
-
count (long), ...: xFileReadLong filename (string), count (long)
- The same as xFileReadShort but reads LONGS (4 bytes).
-
count (long), ...: xFileReadFloat filename (string), count (long)
- The same as xFileReadShort but reads FLOATS (4 bytes).
-
text (string): xFileReadString filename (string)
- Similar to xFileReadShort but reads a single 'C'-style NUL ('\0')
terminated string from the file. If a string cannot be read it returns a 0.
-
xFileWriteShort filename (string), value (short)
- Writes a (2 byte) SHORT value to the file at the current
position and advances. The file is then truncated at the current position (just after the end of the new
value), so you cannot use this to modify the values in the middle of an existing file.
-
xFileWriteLong filename (string), value (long)
- The same as for xFileWriteShort but stores a (4 byte)
LONG value.
-
xFileWriteFloat filename (string), value (float)
- The same as for xFileWriteFloat but stores a (4 byte)
FLOAT value.
-
xFileWriteString filename (string), text (string)
- The same as for xFileWriteShort but stores a 'C'-style
null terminated string to the file.
-
cellid (string): xPCCellID
- Returns a string containing the name of the current
cell.
-
objectid (string): ref
->
xRefID
- Returns the objectid string of the object.
-
cellid (string): ref
->
xMyCellID
- Returns a string containing the name of the cell
the object (intended to be used with references to unique NPCs) inhabits. So fargoth"->xMyCellID
would return "Seyda Neen" unless you've lured him into the wilderness for some reason. Useful for
locating that missing companion. Can't locate items stored in containers or inventory.
-
name (string): ref
->
xGetName
- Returns a string containing the name (suitable
for display, not the objectid) for the object or 0 if the object doesn't have a name. The NPC who
falls from the sky near Seyda Neen has an object id of "agronian guy" but his name is "Tarhiel" when
you look at his corpse.
-
ref
->
xSetName new_name (string)
- Uses the value parameter to change the NPC's name.
The values changed by this function are not permanent and may be reset after 72-hours or a game reload.
Currently only works for NPCs.
-
objectid (string): ref
->
xGetBaseID
- Returns the base part of of the objectid for the
object. This is really intended for use with NPCs. There are 36 diseased Dreamers who share the object
id "dreamer" but if you use the xRefID function on one of them you will get an id that is unique to that
particular NPC such as "dreamer000002", this function would only return "dreamer".
-
order (long): xStringCompare s1 (string), s2 (string)
- Compares the two strings based on alphabetical
order and returns 0 if they are equal, a negative number if the first string would appear first, and
a postive number if the second string would appear first.
-
length (long): xStringLength text (string)
- Returns the number of characters in the input string.
-
count (long), ...: xStringParse pattern (string), source (string)
- Identifies and extracts data from the source
string based on the pattern string. The first return value is a long indicating how much of the
pattern matched successfully. The values matched by the pattern will then be returned in order.
For example, the following statement will put value of 37 in the long variable lval, a value of 2.4
in the float variable fval, the string "Golden Egg" in the string variable sval, and the value 4 into
matches to indicated that all of the pattern successfully matched. For example:
set matches lval fval sval to xStringParse "%d %f %s" "37 2.4 Golden Egg"
In the pattern string, all of the special features begin with a % symbol. Some, simply match special
characters that can't otherwise be typed in the pattern string.
%% | matches a single % sign. |
%n | matches the new line marker, CR/LF. |
%q | matches the " quotation mark. |
The rest return the values matched so they can be stored in variables with setx.
%d | matches a decimal integer and the value is returned as type long. |
%h | matches a hexadecimal integer and the value is returned as type long. |
%f | matches a real number and the value is returned as type float. |
%s | matches the rest of the string and returns it as type string. |
%l | matches exactly four characters and returns them as type long. |
The uppercase forms %N, %Q, %D, %H, %F, %S, and %L also work. Only one of these takes a precision
specifier, and it is best explained by examples:
set matches sval lval to xStringParse "%.0s_%d" "gold_001"
In this case, the special pattern "%.0s" is followed by a "_" character, so only "gold" will be
stored in the string sval, a value of 1 will be in lval, and matches will be 3. Matches is normally
one more than the number of values returned to indicated that in addition to filling all of the
variables the entire pattern was matched successfully. You could use a pattern simply for string
comparison.
set matches lval to xStringParse "%d Apples" somestring
If the somestring variable really holds the string "43 Apples" then matches will be 2 to indicate
that the pattern was matched completely. If somestring were "47 Pears" then matches will be 1 to
indicate that the first variable was filled (with 47) but that the rest of the pattern failed to match.
If somestring were "Hello" then matches will be 0 to indicate that not even the first variable was
filled correctly.
-
result (string): xStringBuild format (string), ...
- Returns a new string that is constructed based
on the format string and any other variable values as needed. The format string is similar to those
for MessageBox with % indicating some special character or variable substitution. Some patterns
can be used to place special characters into the string:
%% | a single % sign is placed in the string. |
%n | a new line marker (CR/LF) is placed in the string. |
%q | a " quotation mark is placed in the string. |
The rest are used to insert values from the remaining parameters into the output string.
%d | a short or long value is inserted as a decimal integer. |
%h | a short or long value is inserted as a hexadecimal integer. |
%f | a float value is inserted as real decimal number. |
%s | a string value is inserted. |
%l | a long value is inserted as a four character string. |
The uppercase forms %N, %Q, %D, %H, %F, %S, and %L also work. The float specifier takes a precision
specifier just like the MessageBox command. The format "%.3f" will print a floating point value with
three digits after the decimal point. The string specifier can take two numbers in its specifier.
%2s | skips the first two characters of the string, but inserts the rest. |
%.3s | inserts only three characters of the string. |
%4.5s | skips 4 characters, then inserts the next 5 characters of the string. |
To put "World, Hello!" into str, you could use the following statement.
set str to xStringBuild "%7S%5.2s%.5S!" "World, Hello
The compiler doesn't currently support more than 12 parameters at a time.
-
match (long): xStringMatch source (string), pattern (string)
- Performs a Regular Expression (R.E.) match
on source using the pattern in pattern. Regular expressions
are pattern matching expressions. MWSE uses the RE library from the Boost C++ library, from
www.boost.org. The regular expression style is the Perl syntax;
please see the Boost documentation
for full documentation. However, here is a partial quick summary:
In regular expressions, a number of characters have special meanings:
. | Matches any one character. |
^ | Matches the beginning of the string. |
$ | Matches then end of the string. |
( and ) | Groups a sub-expression (see below). |
* | Makes the preceeding item or group match zero or more times. |
? | Makes the preceeding item or group match zero or once. |
+ | Makes the preceeding item or group match one or more times. |
{ integer} | Makes the preceeding item or group match exactly
integer times. |
{ int1, int2} | Makes the preceeding item or group
match from int1 to int2 times. |
| | Alternation; makes the pattern match either the item on the left of the
| or the item on the right. |
[ character set] | Matches a single character from the set character
set. The set can contain individual characters, or ranges of the form a- b,
which matches all characters between a and b, including a and b. (For example,
[A-Z] will match upper case letters.) If the character set begins with ^ , then
it will match any character except those in the character set. |
[[: name:]] | Matches a single character from the pre-defined set
name. |
\ character | Matches the character; that is, removes the special meaning, if any,
from character. (For example, "." matches any single character, but "\." matches
the period character.) |
\d | Match a digit (0-9). |
\l | Match a lower case letter (a-z). |
\s | Match whitespace (space, tab). |
\u | Match an upper case letter (A-Z). |
\w | Match a word (a string of letters, digits, and underscores) |
\D | Match anything but a digit. |
\L | Match anything but a lower case letter (a-z). |
\S | Match anything but whitespace (space, tab). |
\U | Match anything but an upper case letter (A-Z). |
\W | Match anything but a word. |
\< | Match the start of a word. |
\> | Match the end of a word. |
\b | Match the end or start of a word. |
\B | Match anything but the end or start of a word. |
Examples:
"(^Mage's Guild)|(, Guild of Mages$)" This will match any string
that starts with "Mage's Guild", or ends with ", Guild of Mages".
"( Tomb(, level \d+)?)|( Barrow)$" This will match any string ending
with " Tomb", " Tomb, level digits", or " Barrow" - in other words, just about any
tomb/barrow type location.
-
xLogMessage format (string), ...
- Writes out formatted strings to the log file
(MWScriptExtender.log) Works much like MessageBox but with the additional formatting options
described for xStringBuild. A trailing % in the format string will suppress the printing of the
new line sequence allowing a single line of text to be created with two or more xLogMessage calls.
The number of parameters specified in the formatstring MUST match those supplied or there will be
trouble.
-
xMessageFix message_format (string), ...
- This function allows you to use strings from variables
with the MessageBox function with a few restrictions. First, the MessageBox command must immediately
follow this one. Second, the number of strings for this function must match the number of strings for
the MessageBox. Third, the MessageBox can have buttons but it can't use variables. And finally, the
values of the strings used on the MessageBox will be replaced with the values from xMessageFix,
but the MessageBox strings set a maximum size for each of the xMessageFix strings (it's OK if the
MessageBox strings are longer than the MessageFix ones). Using aMessageFix can take both the STRING
variable and literal string types and each string acts as a format string as described for the
xStringBuild function. If a string ends in a single % and the formated string takes less space than
the matching string from MessageBox, the remaining characters of the MessageBox string will be used.
While it is possible to use formatted messages and buttons, it is best to format strings with
xStringBuild if there are buttons involved because of the limit of 12 parameters per function.
Example:
long thiscell
setx thiscell to xPCCellID
xMessageFix "Teleport Fargoth Where?" thiscell "Seyda Neen" "Red Mountain"
MessageBox "Send Fargoth to Location" "My Cell" "His Original Location" "Vos"
If you are in Caldera, the Arena in Vivec, or Ald-Ruhn the MessageBox would show:
Teleport Fargoth Where?
Caldera
Seyda Neen
Red
|
Teleport Fargoth Where?
Vivec,
Seyda Neen
Red
|
Teleport Fargoth Where?
Ald-Ruh
Seyda Neen
Red
|
Sample Scripts
Below are three sample scripts that show the structure of the extended scripts. You should also look at
the example scripts in the test ESP files in the Advanced folder.
The following script finds the weight of the item currently in the player's crosshair. It could be called
from a spell monitoring script to create a scripted "Get Weight" spell.
begin getweight_of_pctarget
long pctarget
float weight
; Ensure the script only runs once.
StopScript getweight_of_pctarget
setx pctarget to xGetPCTarget ; Returns a 0 if there isn't a target.
if ( pctarget == 0 ) ; No target, so warn and quit.
MessageBox "You don't have anything targeted."
return
endif
setx weight to pctarget->xGetWeight
MessageBox "The item had weight %f" weight
end
This script will cause all of the male NPCs except Fargoth to run to the player's current position.
You could call this script from the console, dialog, or another script.
begin siren_call
short call ; status variable - should this NPC be called?
long prospectref ; reference to an NPC (or creature)
long prospectid ; string holding the NPC's id
long temp ; used to control ifx statements
float px ; the current player's position
float py
float pz
; this only needs to run for one frame
stopscript siren_call
set px to player->GetPos X
set py to player->GetPos Y
set pz to player->GetPos Z
; loop through each of the NPCs and creatures in the cell
setx prospectref to xFirstNPC
whilex ( prospectref )
; start by assuming we want to call this one
set call to 1
; check the type because we don't want creatures (Non-NPCs)
setx temp to prospectref->xRefType
if ( temp != 1598246990 ) ; it's not an NPC
set call to 0
endif
; check to see if it's a female, we only want the males
setx temp to prospectref->xIsFemale
if ( temp != 0 ) ; it's not a male
set call to 0
endif
; get this NPCs id and see if it's fargoth
setx prospectid to prospectref->xGetBaseID
setx temp to xStringCompare prospectid "fargoth"
if ( temp == 0 ) ; it's Fargoth
set call to 0
endif
; if call is still 1 we want to call this NPC to the player
ifx ( call ) ; we use extended functions inside so need ifx
xSetRef prospectref ; substitute for prospect->ForceRun
ForceRun
prospect->xAITravel px py pz
endif
setx prospectref to xNextRef prospect
endwhile
end
This sample script is meant to be placed on a container. When the player activates the container, it
takes all of the player's posessions and places them in the container unless the trap has been been disabled.
NOTE: What is actually placed in the container is copies of the player's items. For the most part this doesn't
matter; however, it means that weapons and armour will have damage reset, and charged enchanted items will have their charges reset.
begin take_player_items
short trapdisabled
long invitem ; name of the item (i.e. gold_001, ingred_ruby_01, etc.)
long invcount ; amount of the item (i.e. 327 gold_001, etc.)
long invref ; pointer to next item (unused in this script)
long pcref
if ( OnActivate == 0 ) ; Nothing to do until player tries to open it.
return
endif
if ( trapdisabled == 1 ) ; This would be changed by some external script
Activate ; to allow the player to retrieve the items.
endif
; If we get here, the trap is active, take everything the player carries.
setx pcref to xGetRef "player"
setx invitem,invcount,invref to pcref->xInventory ; get first item
whilex ( invcount )
xAddItem invitem invcount ; add to container
pcref->xRemoveItem invitem invcount ; take from player
setx invitem,invcount,invref to pcref->xInventory ; get another item
endwhile
end