DeviousFramework Samples - DeviousFramework/SkyrimDeviousFramework GitHub Wiki
A lot of places will tell you to setup a quest property of type dfwDeviousFramework
and give it a name,
e.g. _qDfw
. When selecting a value only the Devious Framework quest will be available for selection. Once this is done any of the interfaces from this mod can be accessed in the following way: _qDfw.GetMaster(_qDfw.MD_CLOSE)
This method has some benefits and some drawbacks. If you do not know what you are doing this is the best way to access the framework.
However, doing so creates a dependency on the Devious Framework mod.
To access this API while reducing dependency issues use the following:
; A reference to the main framework quest script. dfwDeviousFramework _qDfw Function UpdateScript() If (0.01 > _fCurrVer) _qDfw = Quest.GetQuest("_dfwDeviousFramework") As dfwDeviousFramework EndIf EndFunction Function SomeFunction() Actor aCurrentMaster = _qDfw.GetMaster(_qDfw.MD_CLOSE) ... Do something ... EndFunction
The problem with this method is the _qDfw
variable should be set once and once only. GetQuest()
is slow and it should not be called too many times. The best way to manage this is to set the _qDfw variable when the script is updated. Updating your script can be a little complicated, especially if you don't know what you are doing.
So you want to learn a good way to update your script, do you?
The best time to update a script is when the game loads during the Event OnPlayerLoadGame()
event. The trouble with this is quests do not receive OnPlayerLoadGame()
events. Only players do. In order for a quest to receive this event you must create a player alias for the quest, attach a script to it and have that script catch the event.
The devious framework does this with the dfwPlayerEvents.psc
attached to it's player alias. Inside this script you will find the following code:
Scriptname dfwPlayerEvents extends ReferenceAlias dfwDeviousFramework _qMainQuestScript Event OnPlayerLoadGame() ; Make sure we have a valid reference to the main devious framework script. If (!_qMainQuestScript) _qMainQuestScript = Self.GetOwningQuest() As dfwDeviousFramework EndIf ; Forward this event to the main devious framework script. _qMainQuestScript.UpdateScript() EndEvent
Since the player alias and the main quest script are part of the same quest we can use Self.GetOwningQuest()
instead of the slower GetQuest()
. This would only be called once each time the game is loaded and only if the _qMainQuestScript
variable hasn't been set yet.
Inside the main script we have a _fCurrVer
variable that keeps track of which version of script is stored with the game.
; A local variable to store a reference to the player for faster access. Actor _aPlayer Float _fCurrVer = 0.00 ; A reference to the ZAZ Animation Pack quests. zbfSlaveControl _qZbfSlaveControl ; A reference to the main framework quest script. dfwDeviousFramework _qDfw Function UpdateScript() Float fLatestVer = 0.03 If (fLatestVer == _fCurrVer) ; The game is up to date. Return. Return EndIf Debug.Notification("[DFW] Updating Script: " + _fCurrVer + " => " + fLatestVer) If (0.01 > _fCurrVer) _aPlayer = Game.GetPlayer() _qZbfSlaveControl = Quest.GetQuest("zbfSlaveControl") As zbfSlaveControl ... Initialize some variables created in version 1 ... EndIf If (0.02 > _fCurrVer) _qDfw = Quest.GetQuest("_dfwDeviousFramework") As dfwDeviousFramework EndIf If (0.03 > _fCurrVer) ... Initialize some variables created in version 3 ... EndIf _fCurrVer = fLatestVer EndFunction
In this example the _qDfw
variable was added to the script in version 2. It is initialized when a game is loaded that isn't running the latest version of the script. It can be initialized without changing any variables that were already set in version 1.
If your script registers for an OnUpdate()
event it can check the version number from that event rather than creating a player alias to catch the OnPlayerLoadGame()
event. GetCurrentRealTime()
is reset to zero each time "the game is launched". I'm not sure if launched means the current game is loaded or Skyrim is started from Windows. If the latter there may be some odd behaviour loading the game multiple times in a session without saving it but in general this may be a good way to detect if the game is loaded.
Function SomeFunction() Debug.Notification("The Devious Framework mod is version: " + \ _qDfw.GetModVersion()) EndFunction
The Devious Framework uses this function to end the conversation if the player's leash is being yanked.
Function YankLeash() If (_qDfw.GetPlayerTalkingTo()) ; Moving the player to her own location will end the conversation. _aPlayer.MoveTo(_aPlayer) EndIf ... EndFunction
Function SomeFunction() If (!_qDfw.IsPlayerCriticallyBusy(False)) ; Do something only if the player is not in a scene. ; This will happen even if the player is in bleedout since bIncludeBleedout is ; False. ... EndIf EndFunction
Function EnslavePlayer(Actor aNewMaster) If (_qDfw.IsAllowed(_qDfw.AP_ENSLAVE)) If (SUCCESS <= _qDfw.SetMaster(aNewMaster, "MyMod", _qDfw.AP_ALL - \ _qDfw.AP_ENSLAVE)) ; Block the player's stat regeneration while she is enslaved. _qDfw.BlockHealthRegen() _qDfw.BlockMagicaRegen() _qDfw.BlockStaminaRegen() ... EndIf EndIf EndFunction
Function ReleasePlayer(Actor aCurrMaster) ; Restore the player's stat regeneration after the enslavement has ended. _qDfw.RestoreHealthRegen() _qDfw.RestoreMagicaRegen() _qDfw.RestoreStaminaRegen() ... _qDfw.ClearMaster(aCurrMaster) EndFunction
Function HarassThePlayer() ; We don't want to harass the player if there she has a Master nearby. Actor aMaster = _qDfw.GetMaster(_qDfw.MD_CLOSE) If (!aMaster || (2000 < aMaster.GetDistance(_aPlayer))) ; Harass the player here. ... EndIf EndFunction
Function Safeword() ; Something is not working. Clean up the mod. ; If we have a Master registered clean him up now. If ("MyMod" == _qDfw.GetMasterMod(_qDfw.MD_CLOSE)) Actor aMaster = _qDfw.GetMaster(_qDfw.MD_CLOSE) _qDfw.ClearMaster(aMaster) ; Clean up our own mod. ... EndIf ; MD_ANY feature is not supported yet so we need to clean up distant masters too. If ("MyMod" == _qDfw.GetMasterMod(_qDfw.MD_DISTANT)) Actor aMaster = _qDfw.GetMaster(_qDfw.MD_DISTANT) _qDfw.ClearMaster(aMaster) ; Clean up our own mod. ... EndIf EndFunction
Function EnslavePlayer(Actor aNewMaster) If (_qDfw.IsAllowed(_qDfw.AP_ENSLAVE)) If (SUCCESS <= _qDfw.SetMaster(aNewMaster, "MyMod", \ _qDfw.AP_SEX + _qDfw.AP_RESTRAIN + \ _qDfw.AP_DRESSING_ALONE)) ; Block the player's stat regeneration while she is enslaved. _qDfw.BlockHealthRegen() _qDfw.BlockMagicaRegen() _qDfw.BlockStaminaRegen() ... EndIf EndIf EndFunction
; The player has escaped from a nearby Master. Function PlayerEscaped(Actor aNearbyMaster) _qDfw.ClearMaster(aNearbyMaster, True) ... EndFunction