Tutorial: String Variables 9

This is the ninth article in a tutorial series on string variables.


Breaking String Vars Down, Replacing Bits, and Reassembling ThemEdit

The most straightforward way of taking chunks out of a string var's string is by using Sv_Erase:

sv_erase stringvar StartPositionInt NumberofCharacterstoEraseInt
; StartPositionInt: if you leave that out we'll start at position 0
; NumberofCharacterstoEraseInt: if you leave that out we erase everything from the start position to the end

scn CensorshipScpt

let sv_stringvar := "I fucked up."
sv_erase sv_stringvar 2 6                --> 'I  up.'
sv_insert "messed" sv_stringvar 2

Or you can replace a chunk of a string with another with Sv_Replace:

sv_replace "texttoreplace|texttoreplacewith" FormatSpecVars SourceStringVar StartPositionInt SearchLengthFromStartPosInt CaseSensitiveBool NumberofOccurrencestoReplaceInt
; don't use what you don't need

sv_replace "fucked|messed" sv_stringvar

A bit more complicated version:

scn Variety
let sv_stringvar := "That motherfucking fuckhead fuckin' fucked me over. Fuck!"
sv_replace "fuck|dick" sv_stringvar 19 38 1 1  

The only 'fuck' that is replaced there is in 'fuckhead', and the same goes for

sv_replace "fuck|dick" sv_stringvar 19 4

If elements of a string are separated by a common character, like a space or backslash, Sv_Split can split them up for you and return them as string values to an array:

let sv_stringvar := "This is a sentence."
let somearray := sv_Split sv_stringvar " " ; the 'delimiter'

The 'delimiter' is what separates the string, in this case the 'space' that I stuck in that format string, you can have several characters be delimiters at once.

Then Ar_Dump somearray will return

[ 0.000000 ] : This
[ 1.000000 ] : is
[ 2.000000 ] : a
[ 3.000000 ] : sentence.

Each of those values being strings.


Example 1: Let's say you have clothing meshes for a particular body corresponding to some vanilla ones, and want to switch them out in-game through script:

if vanilla's have filepaths like these: armor\LegateArmor\LegateArmor.NIF and yours have filepaths like these: armor\MyModFolderName\LegateArmor\LegateArmor.NIF

then you'd go about it like this:

let sv_filepath := GetBiPedModelPath 0 ArmorLegate                                        --> 'armor\LegateArmor\LegateArmor.NIF'
let ar_paths := sv_Split sv_filepath "\"                                                  --> ar_paths[0] is "armor", ar_paths[1] is "LegateArmor", ar_paths[2] is "LegateArmor.Nif"
let sv_newfilepath := ar_paths[0] + "\MyModFolderName\" + ar_paths[1] + "\" + ar_paths[2] ; you'll probably need the compiler override on to add that up
SetBiPedModelPathEX $sv_newfilepath 0 ArmorLegate

Note that I used the 0 parameter to get the male mesh, and the 'object' calling convention rather than the reference calling convention (ArmorRef.GetBiPedModelPath 0), so that code switches out the filepaths for the base form. Maybe get in a TempCloneForm or something in between.


You may notice that at no point do I really need to know the specific filepaths, just that I need to insert a foldername after the first section ('armor'), so ArmorLegate can just as easily be a ref var holding whichever armor retrieved by GetEquippedObject or some such, as long as the new filepath is otherwise the same.



Example 2: A number of mods use the 'NX' extension plugin for NVSE, which adds amongst othert things, NX Variables, which take a format string for the function key:

let fSomeFloat := rSomeRef.NX_GetEVfl "Some key string"
rSomeRef.NX_SetEVfl "Some key string" fSomeFloatValue

Those keys being format strings, you can use the ToString symbol to force the nx functions to take a string variable as a key:

let fSomeFloat := rSomeRef.NX_GetEVFl $somestringvar

You'll probably build your keys like "MyModNameString:SomeKeyString:SomeOptionalSubKeyString" (and those colons would be a good delimiter for sv_split), but of course, typing is a drag, and sometimes you want to build nx keys dynamically, on the fly, without knowing how many you need.

Let's say we want to keep tabs on the specific combination of clothing items we have equipped, in order to store the combo:

let iNum := -1
while (iNum += 1) < 20 ; check equipment slots 0-19
    let rForm := playerref.GetEquippedObject iNum
    if rForm
        let sv_keystring := "OutfitMod:OutfitSet:" + "1:" + "Slot:" + $iNum
        playerref.NX_SetEVFo $sv_keystring rForm
    endif
loop

and equipping that later on would be something similar:

let iNum := -1
while (iNum += 1) < 20
    let sv_keystring := "OutfitMod:OutfitSet:" + "1:" + "Slot:" + $iNum
    let rForm := playerref.NX_GetEVfo $sv_keystring
    if rForm
        if playerref.getitemcount rForm
            playerref.EquipItem rForm
        endif
    endif
loop

And I could have different sets if I replaced this:

let sv_keystring := "OutfitMod:OutfitSet:" + "1:"

with

let sv_keystring := "OutfitMod:OutfitSet:" + $someInt + ":"

Depending on what you're wearing, and how many slots each item has flagged, you can have any number of those EVFo variables set on your character. The fact that you just don't know and would otherwise have to type that out in x elseif conditions, makes this another prime example of why string vars are so useful, being editable. Here's hoping someone revises MCM to use some of that, right?


Tutorial part 10: Switching between strings and other representations

External LinksEdit