-
Notifications
You must be signed in to change notification settings - Fork 37
Usage Examples
Suppose you want to store some actor related information (let it be player’s 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)
endfunctionYou wish to have all your mod config values to be stored somewhere (for ex. 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. JSON formatted file contains 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
}
}It contains root map containing two maps - two standard presets your mod provides - classicPreset & winterHorkerPreset. 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")
endfunctionThis is a script that smoothly changes PC's expression from a one to another. It's simple script, so there are two states only, a value scale describes emotional state, 0.0 is the first emotional state, 1.0 is the second. Anything in between is mix of both.
It's achieved by modifying model's bone scales. We need configuration data to be imported from a file Data/emotionInterpolation.txt. The file contents:
[
["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 model bone name, minimum and maximum scale. Then a script would 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)
endfunctionThe same as 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 JDB database.
We will store all per-actor information in following structure:
{
"mood": 0,
"anger": 0,
"victims": []
}Here you can see a map that contains 3 key-value associations: mood and angler (both values are zeros initially) and "victims": [] association ([] means empty array).
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
endfunctionSign into GitHub and press Edit at the top to add any missing information or fix typos and errors. Thanks!