DeviousFramework Samples - DeviousFramework/SkyrimDeviousFramework GitHub Wiki

Samples: General

Accessing Quest Scripts

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.

Updating Your Script

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.

GetModVersion()

Function SomeFunction()
   Debug.Notification("The Devious Framework mod is version: " + \
                      _qDfw.GetModVersion())
EndFunction

GetPlayerTalkingTo()

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

IsPlayerCriticallyBusy()

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

BlockXxxRegen()

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

RestoreXXXRegen()

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

Samples: Masters

GetMaster()

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

GetMasterMod()

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

SetMaster()

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

ClearMaster()

; The player has escaped from a nearby Master.
Function PlayerEscaped(Actor aNearbyMaster)
   _qDfw.ClearMaster(aNearbyMaster, True)
   ...
EndFunction

ChangeMasterDistance()

IsAllowed()

Samples: Player Status

Samples: Nearby Actors

Samples: Leash

Samples: Outgoing Events

⚠️ **GitHub.com Fallback** ⚠️