-
Notifications
You must be signed in to change notification settings - Fork 23
Usage Examples
Suppose you want to store some actor related information (let it be the Player followers and their mood):
function storeFolloverMood(form follower, float mood)
-- function creates "followers" storage and then creates
-- (follower, entry) associations
JFormDB.setFlt(follower, ".followers.mood", mood)
endfunction
float function followerMood(form follower)
-- fetch follower mood
return JFormDB.getFlt(follower, ".followers.mood")
endfunction
; method that gets called once user uninstalls your mod
function modUninstallMethod()
-- destroy association to not pollute game save and precious RAM
JDB.setObj("followers", 0)
endfunction
You wish to have all your mod config values to be stored somewhere (for example in
"Data/preset.txt"
file) so you could easy adjust them all by editing the file. Or you do not wish
to hardcode all these values. A JSON formatted file contains the following information:
{
"classicPreset" : {
"campfileLighting" : "Automatic",
"exposureRate" : 1.0,
"frigidWaterLethal" : 1,
"exposureIsLethal" : 1,
"axeDurability" : 1
},
"winterHorkerPreset" : {
"campfileLighting" : "nonAutomatic",
"exposureRate" : 0.5,
"frigidWaterLethal" : 0,
"exposureIsLethal" : 0,
"axeDurability" : 0
}
}
A root map containing two maps (two standard presets your mod provides) - classicPreset and winterHorkerPreset.
Then a config file reading may look like:
-- let it be .classicPreset or .winterHorkerPreset string
string currentPreset
-- use function each time you need re-read preset from a file
function parseConfig()
-- that’s all. presets are already in Skyrim
-- readFromFile returns root map container
-- it may return zero if file not exist or it can not be parsed (not JSON format or you have accidentally added extra coma)
int config = JValue.readFromFile("Data/preset.txt")
-- put config into DB - associate key and config
JDB.setObj("frostfall", config)
currentPreset = ".classicPreset"
endfunction
bool function axeDurabilityEnabled()
-- solveInt like any solve* function tries to find (solve) value for given path
-- current path is ".frostfall.classicPreset.axeDurability"
return JDB.solveInt(".frostfall" + currentPreset + ".axeDurability") != 0
endfunction
string function lightingType()
return JDB.solveStr(".frostfall" + currentPreset + ".campfileLighting")
endfunction
This is a script that smoothly changes Players expression from a one to another. It is simple
script, so there are two states only, a scale
describes the emotional state, where 0.0 is the
first emotional state, 1.0 is the second. Anything in between is mix of both states.
This is achieved by modifying the model bone scales. The need configuration data is imported from
a file Data/emotionInterpolation.txt
:
[
["hkPhoneme:f:DialogueFear", 0, -0.33],
["hkPhoneme:f:DialogueHappy", -0.133, -0.3],
["hkPhoneme:f:DialogueSad", 0, 0.433],
["hkPhonemes:f:LookLeft", -0.2, 0.0]
]
What you see here is one array that contains 4 sub-arrays and each sub-array contains bone name, minimum and maximum scales. Then a script may look like:
-- retrieve scale info
int getScaleInfo()
int info = JDB.solveObj(".emotionInterpolation")
if !info
info = JValue.readFromFile("Data/emotionInterpolation.txt")
-- cache emotionInterpolation data, so the next time we won't read it again
JDB.setObj("emotionInterpolation", info)
endif
return info
endfunction
function setEmotionScale(float scale)
objectreference plr = GetTargetActor()
-- retrieve config
int config = getScaleInfo()
-- iterate over array & calculate bone scale
int i = JArray.count(config)
while(i > 0)
i -= 1
-- fetch sub-array. it can be ["NPC Head [Head]", 0, -0.33] for instance
int data = JArray.getObj(config, i)
float nodeScale = 1.0 + JArray.getFlt(data,1) + (JArray.getFlt(data,2) - JArray.getFlt(data,1)) * scale
NetImmerse.SetNodeScale(plr, JArray.getStr(data, 0), nodeScale, False)
endWhile
endfunction
-- method that gets called once user uninstalls it via MCM
function modUninstallMethod()
-- remove the emotionInterpolation info to not pollute a save file
JDB.setObj("emotionInterpolation", 0)
endfunction
Similar to the first example, but now you need to store one more value - anger and list of victims
(both are per-actor data). Also you have decided to not associate followers with the JDB
database.
We will store all per-actor information in the following structure:
{
"mood": 0,
"anger": 0,
"victims": []
}
Here you can see a map that contains 3 key-value associations: mood and anger (both values are
zeros initially) and an empty array of victims: "victims": []
.
Actual code:
function storeFollowerMood(form follower, float mood)
-- get follower entry to write into it
int entry = getActorEntry(follower)
-- write mood into follower entry
JValue.solveFltSetter(entry, ".mood", mood)
endfunction
function addFollowerVictim(form follower, form victim)
-- get follower entry to write into it AND then get victims array
int victims = JValue.solveObj(getActorEntry(follower), ".victims")
-- add victim into array
JArray.addForm(victims, victim)
endfunction
float function followerMood(form follower)
-- get follower entry AND fetch mood
return JValue.solveFlt(getActorEntry(follower), ".mood")
endfunction
float function followerAnger(form follower)
return JValue.solveFlt(getActorEntry(follower), ".anger")
endfunction
-- find (or create new if not found) per-actor information containing mood, anger and array of victims
int function getActorEntry(form actor)
int entry = JFormMap.getObj(self.followers, follower)
-- if no entry found - create new from prototype-string
if !entry
entry = JValue.objectWithPrototype("{ \"mood\": 0, \"anger\": 0, \"victims\": [] }")
JFormMap.setObj(self.followers, follower, entry)
endif
return entry
endfunction
-- property hides all black magick - retains & releases object
-- see 'Object lifetime management rules' section for more of it
int property followers hidden
int function get()
return _followers
endFunction
function set(int value)
-- retainAndRelease releases previous _followers object
-- and owns (retains) a new
_followers = JValue.releaseAndRetain(_followers, value, "<myAwesomeMod>")
endFunction
endProperty
int _followers = 0
-- initial setup function where you usually do the things once mod gets installed
function modSetupMethod()
-- create and retain JFormMap container
self.followers = JFormMap.object()
endfunction
-- method that gets called once user uninstalls it via MCM
function modUninstallMethod()
-- release followers container to not pollute game save
self.followers = 0
endfunction