Jump to content

Script works but can it be better?


Recommended Posts

I have had great help from IsharaMeridan and dylbill on my scripts, they work great now but I wonder if I am doing something naive in the parts I was not having trouble with; things that a newbie like me might not realise can be done differently to increase performance/ memory usage/ avoid persistemce etc.

 

My scripts are very simiilar top each other, here are the two more complicated ones:

 

 

 

Scriptname dz_skse_ver2_nakedactivator extends ObjectReference

spell property dz_naked_spell_ver2 auto

Actor Property PlayerRef Auto

;define variable for camera state
int iCameraState

;define variables for weapons in each hand
Weapon equippedleft
Weapon equippedright

;define variable for player shield
Armor player_shield

;define arrays for armour and spells
Armor[] Armor_1

Armor[] Armor_2

Spell[] Spell_1

Event OnInit()
Armor_1 = new Armor[20]
Armor_2 = new Armor[10]
Spell_1 = new Spell[4]
endEvent

Ammo player_ammo

;;;;;;;;;;;;;;wip for arrows/quivers

Ammo Function GetEquippedAmmo(Actor Ref) Global
    ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE
    ;Ammo Entry = NONE
    Int Z = Ref.GetNumItems()
While Z > 0
        Z -= 1
        Form Entry = Ref.GetNthForm(Z)
        If Entry as Ammo && Ref.IsEquipped(Entry)
            Return Entry as ammo
   ;Z = 0
  ;Else
   ;Entry = NONE
   ;Return Entry as ammo
        EndIf
    EndWhile
EndFunction

Event OnTriggerEnter(ObjectReference triggerRef)
;debug.notification("found something!")

Actor akactionRef = triggerRef as Actor
if (akActionRef != game.getplayer() && !akActionRef.isincombat())
;debug.notification("effect applied")
dz_naked_spell_ver2.cast(akactionref,akactionref)
else
  if (SKSE.GetVersionRelease() > 0)
  ;find camera state
  iCameraState = Game.GetCameraState() ; this is an skse function
 
  ;;test getammo function
  player_ammo = NONE
  ;debug.messagebox("Ammo is "+GetEquippedAmmo(PlayerRef))
  player_ammo = GetEquippedAmmo(PlayerRef)
  ;debug.messagebox("Player Ammo is "+player_ammo)
 
  endif

  ;change to third person if not already
  If(iCameraState == 0)
  Game.ForceThirdPerson()
  Endif
 
  ;get weapons
  equippedleft = PlayerRef.GetEquippedWeapon(true)
  equippedright = PlayerRef.GetEquippedWeapon()

  ;get shield
  player_shield = PlayerRef.GetEquippedShield()


  ;fill the spell_1 array
  Int spell_no = spell_1.length
  While spell_no
   spell_no -= 1
   spell_1[spell_no] = PlayerRef.GetEquippedSpell(spell_no)
  endWhile
  
  ;fill the first armour array,
  Int slot1 = armor_1.length + 30
  Int index1 = armor_1.length
  While index1
   index1 -= 1
   armor_1[index1] = PlayerRef.GetEquippedArmorInSlot(slot1)
   slot1 -= 1
  endWhile
 
  ;fill the second armour array
  Int slot2 = armor_2.length + 52
  Int index2 = armor_2.length
  While index2
   index2 -= 1
   armor_2[index2] = PlayerRef.GetEquippedArmorInSlot(slot2)
   slot2 -= 1
  endWhile

  akActionRef.unequipall()
endif
endEvent

Event OnTriggerLeave(ObjectReference triggerRef)
Actor akactionRef = triggerRef as Actor
if (akActionRef != PlayerRef)

  ;debug.notification("effect removed")
  akActionRef.dispelspell(dz_naked_spell_ver2)
 
else

  if (SKSE.GetVersionRelease() > 0 && iCameraState == 0)
   ;return to first person if necessary
   ;if (iCameraState == 0)
   Game.ForceFirstPerson()
   ;Endif
  endif

  ;if the trigger is the player then equip all weapons, spells and armor

  if (SKSE.GetVersionRelease() > 0)
  
   ;re-equip the first armour array ,
   int index1 = armor_1.length
   while index1
    index1 -= 1
    PlayerRef.EquipItemEx(armor_1[index1],0,false,true)
   endWhile
  
   ;re-equip the second armour array ,
   int index2 = armor_2.length
   while index2
    index2 -= 1
    PlayerRef.EquipItemEx(armor_2[index2],0,false,true)
   endWhile
  
   ;re-equip weapons
   PlayerRef.EquipItemEx(equippedleft,2,true) ;this is an skse function
   PlayerRef.EquipItemEx(equippedright,1)  ;this is an skse function
  
   ;re-equip shield
   PlayerRef.EquipItemEx(player_shield)
  
   ;re-equip ammo
   PlayerRef.EquipItemEx(player_ammo)
 
  else
   ;re-equip weapons
   PlayerRef.EquipItem(equippedleft)
   PlayerRef.EquipItem(equippedright)
  
   ;re-equip shield
   PlayerRef.EquipItem(player_shield)
  
   ;re-equip the first armour array
   int index1 = armor_1.length
   while index1
    index1 -= 1
    PlayerRef.EquipItem(armor_1[index1],false,true)
   endWhile
  
   ;re-equip the second armour array
   int index2 = armor_2.length
   while index2
    index2 -= 1
    PlayerRef.EquipItem(armor_2[index2],false,true)
   endWhile
 
  endif
 
  ;re-equip spells
  int spell_no = spell_1.length
  while spell_no
   spell_no -=1
   PlayerRef.EquipSpell(spell_1[spell_no],spell_no)
  endWhile
 
;debug.messagebox("Leave Triggered")
endif
endEvent

 

 

 

 

 

 

Scriptname dz_mcm_ver2_nakedactivator extends ObjectReference
spell property dz_naked_spell_ver2 auto
dz_mcm_ver2_undressing_script property mcm auto
Actor Property PlayerRef Auto
;define variable for disrobing

bool disrobed
;define variable for combat check

bool noCombatCheck
;define variable for camera state

int iCameraState
;define variables for weapons in each hand

Weapon equippedleft

Weapon equippedright
;define variable for player shield

Armor player_shield
;define arrays for armour and spells

Armor[] Armor_1
Armor[] Armor_2
Spell[] Spell_1
Event OnInit()

Armor_1 = new Armor[20]

Armor_2 = new Armor[10]

Spell_1 = new Spell[4]

endEvent
Ammo player_ammo
;;;;;;;;;;;;;;wip for arrows/quivers
Ammo Function GetEquippedAmmo(Actor Ref) Global

    ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE

    ;Ammo Entry = NONE

    Int Z = Ref.GetNumItems()

While Z > 0

        Z -= 1

        Form Entry = Ref.GetNthForm(Z)

        If Entry as Ammo && Ref.IsEquipped(Entry)

            Return Entry as ammo

   ;Z = 0

  ;Else

   ;Entry = NONE

   ;Return Entry as ammo

        EndIf

    EndWhile

EndFunction
Event OnTriggerEnter(ObjectReference triggerRef)

;debug.notification("found something!")

Actor akactionRef = triggerRef as Actor
disrobed = mcm.disrobes

If (mcm.ignoreCombat == true)

noCombatCheck = true

elseif (mcm.ignoreCombat == false && !PlayerRef.isincombat())

noCombatCheck = true

else

noCombatCheck = false

endif
;debug.notification("disrobed = "+mcm.disrobes)

if (akActionRef != game.getplayer() && noCombatCheck == true)

;debug.notification("effect applied")

dz_naked_spell_ver2.cast(akactionref,akactionref)

else
;find camera state only if trigger is player

iCameraState = Game.GetCameraState() ; this is an skse function

  ;check for skyui

  if (Game.GetFormFromFile(0x00000814, "SkyUI_SE.esp") == None)

  debug.notification("You have installed the SkyUI version of this mod but no SkyUI was found.")
  ;change to third person if not already if mcm specifies

  elseif (iCameraState == 0 && mcm.third_person == true)

  Game.ForceThirdPerson()
  ;otherwise stay in first person if already there

  elseif (mcm.third_person == false)

  endif
  if (disrobed == true && akActionRef == PlayerRef && noCombatCheck == true)

  ;get weapons

  ;debug.messagebox("Filling weapons")

  equippedleft = PlayerRef.GetEquippedWeapon(true)

  equippedright = PlayerRef.GetEquippedWeapon()
  ;get shield

  player_shield = PlayerRef.GetEquippedShield()
 

  ;;test getammo function

  player_ammo = NONE

  ;debug.messagebox("Ammo is "+GetEquippedAmmo(PlayerRef))

  player_ammo = GetEquippedAmmo(PlayerRef)

  ;debug.messagebox("Player Ammo is "+player_ammo)

 
  ;fill the spell_1 array

  Int spell_no = spell_1.length

  While spell_no

   spell_no -= 1

   spell_1[spell_no] = PlayerRef.GetEquippedSpell(spell_no)

  endWhile

  

  ;fill the first armour array

  Int slot1 = armor_1.length + 30

  ;ebug.messagebox("initial slot1 = "+slot1)

  Int index1 = armor_1.length

  ;debug.messagebox("initial index1 ="+index1)

  While index1

   ;debug.messagebox("Filling " +index1)

   index1 -= 1

   armor_1[index1] = PlayerRef.GetEquippedArmorInSlot(slot1)

   slot1 -= 1

  endWhile

 

  ;fill the second armour array

  Int slot2 = armor_2.length + 52

  Int index2 = armor_2.length

  While index2

   index2 -= 1

   armor_2[index2] = PlayerRef.GetEquippedArmorInSlot(slot2)

   slot2 -= 1

  endWhile
  akActionRef.unequipall()
  endif
endif

endEvent
Event OnTriggerLeave(ObjectReference triggerRef)

Actor akactionRef = triggerRef as Actor

if (akActionRef != PlayerRef)

;debug.notification("effect removed")

akActionRef.dispelspell(dz_naked_spell_ver2)

endif
;return to first person if necessary

if (iCameraState == 0 && mcm.third_person == true && akActionRef == PlayerRef)

Game.ForceFirstPerson()

endif

 

;if trigger is the player

if (akActionRef == PlayerRef && disrobed == true)
  ;debug.messagebox("Re-equipping armour")

  ;re-equip the first armour array

  int index1 = armor_1.length

  while index1

   ;debug.messagebox("Re-equip "+index1)

   index1 -= 1

   PlayerRef.EquipItemEx(armor_1[index1],0,false,true)

  endWhile

 

  ;re-equip the second armour array

  int index2 = armor_2.length

  while index2

   index2 -= 1

   PlayerRef.EquipItemEx(armor_2[index2],0,false,true)

  endWhile

 

  ;re-equip weapons

  PlayerRef.EquipItemEx(equippedleft,2,true) ;this is an skse function

  PlayerRef.EquipItemEx(equippedright,1)  ;this is an skse function
  ;re-equip shield

  PlayerRef.EquipItemEx(player_shield)
  ;re-equip ammo

  PlayerRef.EquipItemEx(player_ammo)

 

  ;re-equip spells

  int spell_no = spell_1.length

  while spell_no

   spell_no -=1

   PlayerRef.EquipSpell(spell_1[spell_no],spell_no)

  endWhile

 

endif  
;debug.messagebox("Leave Triggered")

endEvent


 

 

 

The latter references a quest for an MCM menu, I can post that if useful.

This is not an urgent thing, my scripts are now working and this is just a thought about fine tuning.

 

diziet

Link to comment
Share on other sites

You wrote: ".. my scripts are now working and this is just a thought about fine tuning."

I had a look inside and I doubt that any script version you posted here is really working as intend!

 

An activator (as Trigger) which has such kind of script attached will be triggered by every objectReference and actor (player included).

Every time an actor came across with the trigger your script variables could be changed unexpected.

 

Its always a good idea to keep the papyrus code inside events as small as possible. Its better to use functions instead for overview, maintenance and stack management.

 

dz_mcm_ver2_nakedactivator

 

Scriptname dz_mcm_ver2_nakedactivator extends ObjectReference
; https://forums.nexusmods.com/index.php?/topic/8502938-script-works-but-can-it-be-better/

  dz_mcm_ver2_undressing_script PROPERTY mcm auto       ; the mcm quest script

  Spell       PROPERTY dz_naked_spell_ver2      auto    ; the spell
  MagicEffect PROPERTY dz_naked_spell_ver2_MGEF auto    ; an unique spell effect (from spell above) or use a unique keyword

  Form[]  Fight
    ; [0] .. [3] spells
    ; [4] shout
    ; [5] Weapon equippedleft
    ; [6] Weapon equippedright
    ; [7] Armor  player_shield
    ; [8] Ammo   player_ammo

  Armor[] Armor_1
  Armor[] Armor_2

  Actor player             ; make player script persistence
  Bool disrobed            ; to track player naked
  Bool bSkyUI              ; to track SkyUI present


; -- EVENTs -- 3

EVENT OnInit()
;===========
    Armor_1 = new Armor[20]
    Armor_2 = new Armor[10]
    Fight   = new Form[9]
ENDEVENT


EVENT OnCellAttach()
    player = Game.GetPlayer()
    bool bSkyUI = Game.GetFormFromFile(0x00000814, "SkyUI_SE.esp") as Bool
ENDEVENT

EVENT OnCellDetach()
    player = None
ENDEVENT


EVENT OnTriggerEnter(ObjectReference triggerRef)
;===================
IF (triggerRef as Actor)
ELSE
    RETURN    ; - STOP -    no actor, no action
ENDIF
;---------------------
IF (triggerRef as Actor == player)
    myF_ENTER()
    RETURN    ; - STOP -
ENDIF
;--------------------- NPCs only
    IF (mcm.ignoreCombat) || !triggerRef.IsInCombat()
        dz_naked_spell_ver2.Cast(triggerRef, triggerRef)    ; cast the spell, actor "should ignore combat" or "is not in combat"
    ENDIF
ENDEVENT


EVENT OnTriggerLeave(ObjectReference triggerRef)
;===================
IF (triggerRef as Actor)
ELSE
    RETURN    ; - STOP -    no actor, no action
ENDIF
;---------------------
IF (triggerRef as Actor == player)
    myF_LEAVE()
    RETURN    ; - STOP -
ENDIF
;--------------------- NPC only
    IF (triggerRef as Actor).HasMagicEffect(dz_naked_spell_ver2_MGEF)                    ; effect
;;;    IF (triggerRef as Actor).HasMagicEffectWithKeyword(dz_naked_spell_ver2_Keyword)   ; or keyword
        (triggerRef as Actor).DispelSpell(dz_naked_spell_ver2)
    ENDIF
ENDEVENT


; -- FUNCTIONs -- 3

;----------------------------------------
Ammo FUNCTION GetEquippedAmmo(Actor aRef)
;----------------------------------------
; returns the ammo equipped by the passed in actor, otherwise it returns NONE
;;;;;;;;;;;;;;wip for arrows/quivers

IF (SKSE.GetVersion() > 0)
ELSE
    RETURN None        ; SKSE not found!
ENDIF
;---------
int i                              ; i = Z
    IF ( aRef )                    ; actor is valid?
        i = aRef.GetNumItems()                                ; SKSE required!
    ENDIF

WHILE (i)                          ; (i > 0)
    i = i - 1
    ammo AM = aRef.GetNthForm(i) as Ammo                      ; SKSE required!

    IF (AM) && aRef.IsEquipped(Ammo as Form)
        RETURN AM        ; OK!
    ENDIF
ENDWHILE
        RETURN None      ; no ammunition
ENDFUNCTION


;-------------------
FUNCTION myF_ENTER()
;-------------------
IF (SKSE.GetVersion() > 0)
ELSE
    RETURN    ; - STOP - SKSE not found!
ENDIF
;---------------------
; check for skyui
    IF ( !bSkyUI )
        debug.notification("You have installed the SkyUI version of this mod, but "SkyUI_SE.esp" was not found!")

    ELSEIF Game.IsCamSwitchControlsEnabled()
    ; switch cam is possible for player

        if ( mcm.third_person )
        ; change to third person if not already if mcm specifies
        
            IF (Game.GetCameraState() == 0)                   ; SKSE required!
                Game.ForceThirdPerson()            ; 3rd
            ENDIF
        else
        ; otherwise stay in first person if already there

            IF (Game.GetCameraState() == 0)                   ; SKSE required!
            ELSE
                Game.ForceFirstPerson()            ; 1th
            ENDIF
        endif
    ENDIF

IF ( mcm.disrobes )
    ; == TRUE
ELSE
    RETURN    ; - STOP -    do not disrobe the player
ENDIF
;---------------------
IF ( mcm.ignoreCombat )
    ; == TRUE
ELSE
    IF player.IsInCombat()
        RETURN    ; - STOP -    player is in combat, but combat is not ignored
    ENDIF
;    ----------------------
ENDIF

IF ( disrobes )
    RETURN    ; - STOP -    threadLock active, do not make player naked more than once at same time
ENDIF
;---------------------
    disrobes = TRUE            ; *T*

;fill the spell_1 array
    ; 0: Left hand
    ; 1: Right hand
    ; 2: Other
    ; 3: Instant

int i = 4               ; spell_1.Length
    WHILE (i)
        i = i - 1
        Fight[i] = player.GetEquippedSpell(i)            ; [3] downto [0]
    ENDWHILE

; get shout
    shou sh = player.GetEquippedShout()
    IF ( sh )
        Fight[4] = sh as Form
        player.UnequipShout(sh)
    ELSE
        Fight[4] = None
    ENDIF

; get weapons
    Fight[5] = player.GetEquippedWeapon(TRUE) as Form    ; equippedleft
    Fight[6] = player.GetEquippedWeapon(False) as Form   ; equippedright

; get shield
    Fight[7] = player.GetEquippedShield() as Form        ; player_shield
 
; ##test## getammo function
    Fight[8] = GetEquippedAmmo(player) as Form           ; player_ammo

; fill the first armor array
    i = armor_1.length                                ; debug.messagebox("initial index1 ="+index1)
    WHILE (i)                                         ; debug.messagebox("Filling " +index1)
        i = i - 1
        armor_1[i] = player.GetEquippedArmorInSlot(i + 31)
    ENDWHILE

; fill the second armor array
    i = armor_2.length
    WHILE (i)
        i = i - 1
        armor_2[i] = player.GetEquippedArmorInSlot(i + 53)
    ENDWHILE

    player.UnEquipAll()        ; make player naked
ENDFUNCTION


;-------------------------------
FUNCTION myF_LEAVE(Actor player)
;-------------------------------
IF (SKSE.GetVersion() > 0)
ELSE
    RETURN    ; - STOP - SKSE not found!
ENDIF
;---------------------
;return to first person if necessary

    IF Game.IsCamSwitchControlsEnabled()
    ; switch cam is possible for player

        if ( mcm.third_person )
        ; change to third person if not already if mcm specifies
        
            IF (Game.GetCameraState() == 0)                   ; SKSE required!
            ELSE
                Game.ForceFirstPerson()            ; 1th
            ENDIF
        endif
    ENDIF

IF ( disrobed )                ; ***
;;    debug.messagebox("Re-equipping armour")
ELSE
    RETURN    ; - STOP -    player is not naked
ENDIF
;---------------------
; https://www.creationkit.com/index.php?title=EquipItemEx_-_Actor

    int i
    armor AR

;re-equip the first armor array
    i = armor_1.Length
    WHILE (i)
        i = i - 1
        AR = armor_1[i]
        IF ( AR )
            player.EquipItemEx(AR, 0, False, TRUE)            ; SKSE required!
        ENDIF
    ENDWHILE
 
;re-equip the second armor array
    i = armor_2.Length
    WHILE (i)
        i = i - 1
        AR = armor_2[i]
        IF ( AR )
            player.EquipItemEx(AR, 0, False, TRUE)            ; SKSE required!
        ENDIF
    ENDWHILE

;re-equip weapons
    IF ( Fight[5] as Weapon )        ; equippedLeft
        player.EquipItemEx(Fight[0],  2, False, TRUE)         ; SKSE required!
    ENDIF

    IF ( Fight[6] as Weapon )        ; equippedRight
        player.EquipItemEx(Fight[1], 1, False, TRUE)          ; SKSE required!
    ENDIF

;re-equip shield
    IF ( Fight[7] as Shield )        ; player_shield
        player.EquipItemEx(Fight[2], 0, False, TRUE)          ; SKSE required!
    ENDIF

;re-equip ammo
    IF ( Fight[8] as Ammo )          ; player_ammo
        player.EquipItemEx(Fight[3], 0, False, TRUE)          ; SKSE required!
      ENDIF

;re-equip shout
    shout sh = Fight[4] as Shout
    IF ( sh )
        player.EquipShout(sh)
    ENDIF

;re-equip spells
    i = 4                       ; spell_1.Length
    WHILE (i)
        i = i - 1
        spell sp = Fight[i] as Spell
        IF ( sp )    
            player.EquipSpell(sp, i)
        ENDIF
    ENDWHILE

    disrobed = False        ; ***
ENDFUNCTION

 

edited 20 March 2020

Edited by ReDragon2013
Link to comment
Share on other sites

You wrote: ".. my scripts are now working and this is just a thought about fine tuning."

I had a look inside and I doubt that any script version you posted here is really working as intend!

 

An activator (as Trigger) which has such kind of script attached will be triggered by every objectReference and actor (player included).

Every time an actor came across with the trigger your script variables could be changed unexpected.

 

Its always a good idea to keep the papyrus code inside events as small as possible. Its better to use functions instead for overview, maintenance and stack management.

 

dz_mcm_ver2_nakedactivator

 

Scriptname dz_mcm_ver2_nakedactivator extends ObjectReference
; https://forums.nexusmods.com/index.php?/topic/8502938-script-works-but-can-it-be-better/

  dz_mcm_ver2_undressing_script PROPERTY mcm auto       ; the mcm quest script

  Spell       PROPERTY dz_naked_spell_ver2      auto    ; the spell
  MagicEffect PROPERTY dz_naked_spell_ver2_MGEF auto    ; an unique spell effect (from spell above) or use a unique keyword

  Form[]  Fight
    ; [0] Weapon equippedleft
    ; [1] Weapon equippedright
    ; [2] Armor  player_shield
    ; [3] Ammo   player_ammo

  Armor[] Armor_1
  Armor[] Armor_2
  Spell[] Spell_1

  Bool disrobed            ; to track player naked


; -- EVENTs -- 3

EVENT OnInit()
;===========
    Armor_1 = new Armor[20]
    Armor_2 = new Armor[10]
    Spell_1 = new Spell[4]
    Fight   = new Form[4]
ENDEVENT


EVENT OnTriggerEnter(ObjectReference triggerRef)
;===================
IF (triggerRef as Actor)
ELSE
    RETURN    ; - STOP -    no actor, no action
ENDIF
;---------------------
IF (triggerRef == Game.GetPlayer() as ObjectReference)
    myF_ENTER(triggerRef as Actor)
    RETURN    ; - STOP -
ENDIF
;---------------------
    IF (mcm.ignoreCombat) || !triggerRef.IsInCombat()
        dz_naked_spell_ver2.Cast(triggerRef, triggerRef)    ; cast the spell, actor "should ignore combat" or "is not in combat"
    ENDIF
ENDEVENT


EVENT OnTriggerLeave(ObjectReference triggerRef)
;===================
IF (triggerRef as Actor)
ELSE
    RETURN    ; - STOP -    no actor, no action
ENDIF
;---------------------
IF (triggerRef == Game.GetPlayer() as ObjectReference)
    myF_LEAVE(triggerRef as Actor)
    RETURN    ; - STOP -
ENDIF
;---------------------
    IF (triggerRef as Actor).HasMagicEffect(dz_naked_spell_ver2_MGEF)                    ; effect
;;;    IF (triggerRef as Actor).HasMagicEffectWithKeyword(dz_naked_spell_ver2_Keyword)   ; or keyword
        (triggerRef as Actor).DispelSpell(dz_naked_spell_ver2)
    ENDIF
ENDEVENT


; -- FUNCTIONs -- 3

;----------------------------------------
Ammo FUNCTION GetEquippedAmmo(Actor aRef)
;----------------------------------------
; returns the ammo equipped by the passed in actor, otherwise it returns NONE
;;;;;;;;;;;;;;wip for arrows/quivers

IF (SKSE.GetVersion() > 0)
ELSE
    RETURN None        ; SKSE not found!
ENDIF
;---------
int i                               ; i = Z

    IF ( aRef )                    ; actor is valid?
        i = aRef.GetNumItems()                                ; SKSE required!
    ENDIF

WHILE (i)                        ; (i > 0)
    i = i - 1
    ammo AM = aRef.GetNthForm(i) as Ammo                      ; SKSE required!

    IF (AM) && aRef.IsEquipped(Ammo as Form)
        RETURN AM        ; OK!
    ENDIF
ENDWHILE
        RETURN None        ; no ammunition
ENDFUNCTION


;-------------------------------
FUNCTION myF_ENTER(Actor player)
;-------------------------------
IF (SKSE.GetVersion() > 0)
ELSE
    RETURN    ; - STOP - SKSE not found!
ENDIF
;---------------------
; check for skyui
    IF !Game.GetFormFromFile(0x00000814, "SkyUI_SE.esp")
        debug.notification("You have installed the SkyUI version of this mod, but "SkyUI_SE.esp" was not found!")

    ELSEIF Game.IsCamSwitchControlsEnabled()
    ; switch cam is possible for player

        if ( mcm.third_person )
        ; change to third person if not already if mcm specifies
        
            IF (Game.GetCameraState() == 0)                   ; SKSE required!
                Game.ForceThirdPerson()            ; 3rd
            ENDIF
        else
        ; otherwise stay in first person if already there

            IF (Game.GetCameraState() == 0)                   ; SKSE required!
            ELSE
                Game.ForceFirstPerson()            ; 1th
            ENDIF
        endif
    ENDIF

IF ( mcm.disrobes )
    ; == TRUE
ELSE
    RETURN    ; - STOP -    do not disrobe the player
ENDIF
;---------------------
IF ( mcm.ignoreCombat )
    ; == TRUE
ELSE
    IF player.IsInCombat()
        RETURN    ; - STOP -    player is in combat, but combat is not ignored
    ENDIF
;    ----------------------
ENDIF

IF ( disrobes )
    RETURN    ; - STOP -    threadLock active
ENDIF
;---------------------
    disrobes = TRUE            ; *T*

; get weapons
    Fight[0] = player.GetEquippedWeapon(TRUE) as Form    ; equippedleft
    Fight[1] = player.GetEquippedWeapon(False) as Form   ; equippedright

; get shield
    Fight[2] = player.GetEquippedShield() as Form        ; player_shield
 
; ##test## getammo function
    Fight[3] = GetEquippedAmmo(player) as Form           ; player_ammo

    int i

;fill the spell_1 array
    ; 0: Left hand
    ; 1: Right hand
    ; 2: Other
    ; 3: Instant

    i = spell_1.Length
    WHILE (i)
        i = i - 1
        spell_1[i] = player.GetEquippedSpell(i)
    ENDWHILE

; fill the first armor array
    i = armor_1.length                                ; debug.messagebox("initial index1 ="+index1)
    WHILE (i)                                         ; debug.messagebox("Filling " +index1)
        i = i - 1
        armor_1[i] = player.GetEquippedArmorInSlot(i + 31)
    ENDWHILE

; fill the second armor array
    i = armor_2.length
    WHILE (i)
        i = i - 1
        armor_2[i] = player.GetEquippedArmorInSlot(i + 53)
    ENDWHILE

    player.UnEquipAll()        ; make player naked
ENDFUNCTION


;-------------------------------
FUNCTION myF_LEAVE(Actor player)
;-------------------------------
IF (SKSE.GetVersion() > 0)
ELSE
    RETURN    ; - STOP - SKSE not found!
ENDIF
;---------------------
;return to first person if necessary

    IF Game.IsCamSwitchControlsEnabled()
    ; switch cam is possible for player

        if ( mcm.third_person )
        ; change to third person if not already if mcm specifies
        
            IF (Game.GetCameraState() == 0)                   ; SKSE required!
            ELSE
                Game.ForceFirstPerson()            ; 1th
            ENDIF
        endif
    ENDIF

IF ( disrobed )                ; ***
;;    debug.messagebox("Re-equipping armour")
ELSE
    RETURN    ; - STOP -    player is not naked
ENDIF
;---------------------
; https://www.creationkit.com/index.php?title=EquipItemEx_-_Actor

    int i
    armor AR

;re-equip the first armor array
    i = armor_1.Length
    WHILE (i)
        i = i - 1
        AR = armor_1[i]
        IF ( AR )
            player.EquipItemEx(AR, 0, False, TRUE)            ; SKSE required!
        ENDIF
    ENDWHILE
 
;re-equip the second armor array
    i = armor_2.Length
    WHILE (i)
        i = i - 1
        AR = armor_2[i]
        IF ( AR )
            player.EquipItemEx(AR, 0, False, TRUE)            ; SKSE required!
        ENDIF
    ENDWHILE

;re-equip weapons
    IF ( Fight[0] as Weapon )        ; equippedLeft
        player.EquipItemEx(Fight[0],  2, False, TRUE)         ; SKSE required!
    ENDIF

    IF ( Fight[1] as Weapon )        ; equippedRight
        player.EquipItemEx(Fight[1], 1, False, TRUE)          ; SKSE required!
    ENDIF

;re-equip shield
    IF ( Fight[2] as Shield )        ; player_shield
        player.EquipItemEx(Fight[2], 0, False, TRUE)          ; SKSE required!
    ENDIF

;re-equip ammo
    IF ( Fight[3] as Ammo)            ; player_ammo
        player.EquipItemEx(Fight[3], 0, False, TRUE)          ; SKSE required!
      ENDIF

;re-equip spells
    i = spell_1.Length
    WHILE (i)
        i = i - 1
        spell sp = spell_1[i]
        IF ( sp )    
            player.EquipSpell(sp, i)
        ENDIF
    ENDWHILE

    disrobed = False        ; ***
ENDFUNCTION

 

 

To clarify then, putting most of the logic in functions outside of events is better for performance etc.?

I didn't know you could do:

player.GetEquippedArmorInSlot(i + 53)

this avoids one more variable, cwl.

 

Not sure what the comment means here or why you did this:) did you mean !disrobes ?

IF ( disrobes )

RETURN ; - STOP - threadLock active

ENDIF

 

As for scripts not working, good job I posted, I've got tens of patches on my mod page using them:)

Query...can non-actors trigger a triggerbox then? A flying bucket or something?

I had thought that only NPCs and the player would trigger the box, which is why I thought to check for if the the trigger was NPC or player but not otherwise.

 

This is also why I haven't got any check for magiceffect as you have, since I thought that checking for player versus NPC on leaving thevtrigger would be enough; as an NPC leaving the trigger would have to have entered the trigger and thus have the spell, also isn't it harmless to dispell a spell an NPC doesn't have? Is this an important thing to do? I'm assuming that the actual magic effect to put in the code would be the one used in the creation kit to make the spell?

 

This is interesting, I shall have to consider a full makeover of my scripts.

 

Thanks for responding

 

diziet

Link to comment
Share on other sites

FAQ: "Query...can non-actors trigger a triggerbox then? A flying bucket or something?"

no idea.. whether a flying bucket could trigger a triggerbox or not.. its a flying object

but maybe a sword from death actor, an animated creature or something similiar could trigger

 

 

FAQ: "Not sure what the comment means here or why you did this:) did you mean !disrobes ?"

make sure you do not equip items and the player is (in this time) running again in the triggerbox, which would make the player unequip all items

 

 

FAQ: "isn't it harmless to dispell a spell an NPC doesn't have?"

That's the question.. better check before.

 

your code ;fill the first armour array

    Int slot1  = armor_1.length + 30
    Int index1 = armor_1.length

    WHILE (index1)
        index1 -= 1

        armor_1[index1] = PlayerRef.GetEquippedArmorInSlot(slot1)

        slot1 -= 1
    ENDWHILE

You wrote: "I didn't know you could do:"

    int i

    i = armor_1.Length
    WHILE (i)
        i = i - 1
        armor_1[i] = player.GetEquippedArmorInSlot(i + 31)
    ENDWHILE

FAQ: "To clarify then, putting most of the logic in functions outside of events is better for performance etc.?"

as I wrote already its better for maintaining, not really faster (because of stack swapping for the function overhead)

Edited by ReDragon2013
Link to comment
Share on other sites

 

AQ: "Not sure what the comment means here or why you did this:) did you mean !disrobes ?"

I was also referring to the 'threadlock' mention, don't know what threadlock is :):

 

IF ( disrobes )

RETURN ; - STOP - threadLock active

ENDIF

 

Anyway, I've incorporated most of your ideas into a newer version of my script, undressing seems - subjectively - a little slower, but re-dressing is super fast from before, so thanks :)

 

diziet

Link to comment
Share on other sites

Hey, the fastest way to get equipped items on an actor would be to use Papyrus Extender: https://www.nexusmods.com/skyrimspecialedition/mods/22854 which has:

Form[] function AddAllEquippedItemsToArray(Actor akActor)

I remember suggesting this for getting equipped ammo, and I did test it. The function is really fast. You could still put a check for skse and Papyrus Extender, and use the function if it's installed.

Link to comment
Share on other sites

Please have a look to my last post I changed the script code a bit.. for better runtime and added "shout" equip

Ah, didn't notice the edit there, I don't th9nk the shout is not necessary for my particular patch mod since i'm concerned about the physical appearance of NPCs and the player in baths/pools etc. but it's a useful thing to have anyway.

And I've worked out what you mean by:

 

IF ( disrobes )
    RETURN    ; - STOP -    threadLock active, do not make player naked more than once at same time
ENDIF
;---------------------
    disrobes = TRUE            ; *T*

 

It's a typo:) For 'disrobes' read 'disrobed' ! Then of course if it is already true: IF ( disrobes ) yes? Then exit the function, else set the variable and carry on right?

And in the trigger leave function at the end set the 'disrobed' to false.

 

I admit that I can't see how in practice a player could trigger the entering of a box a second time without leaving, but I see the efficacy in planning for it anyway, because computers. :)

 

This has been very interesting and again, thankyou.

 

diziet

Link to comment
Share on other sites

Hey, the fastest way to get equipped items on an actor would be to use Papyrus Extender: https://www.nexusmods.com/skyrimspecialedition/mods/22854 which has:

Form[] function AddAllEquippedItemsToArray(Actor akActor)

I'll look this up, I don't want to ask users to download extra dependencies if the functionality can already be there, but a check to see if it is already there and using it seems a good idea if it will help performance etc. ?

 

diziet

Link to comment
Share on other sites

You don't need to add them as "extra dependencies", you just include in your mod (in their corresponding folders) the "scripts - pex - psc" and the "po3_papyrusextender.dll" in the skse plugins folder.

That's all...

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...