Jump to content

Sit markers, end of animation question


Recommended Posts

I can make something happen when an actor uses a sit marker (presumably any other marker too) by adding a script to the marker instance and using the OnActivate() event. But what do I need to make something happen when the actor _stops_ sitting, i.e. stands up?

Do I have to register for an animation event - never done that before, or is there something simpler?

 

diziet

Link to comment
Share on other sites

maybe something like that

 

  Actor sitActor


EVENT OnActivate(ObjectReference akActionRef)
IF (akActionRef as Actor)
    gotoState("Waiting")            ; ### STATE ###
    sitActor = akActionRef as Actor
    RegisterForSingleUpdateGameTime(0.0)
ENDIF
ENDEVENT


;===================================
state Waiting
;============
    EVENT OnActivate(ObjectReference akActionRef)
    ENDEVENT

    EVENT OnUpdateGameTime()
        Utility.Wait(0.25)                    ; adjust the wait time, if required
        WHILE (TRUE)
            Utility.Wait(0.1)
            int i = sitActor.GetSitState()        ; https://www.creationkit.com/index.php?title=GetSitState_-_Actor
            IF (i == 4)
                sitActor = None
                gotoState("")        ; ### STATE ###
                RETURN    ; - STOP -    is still sitting, wants to stand up
            ENDIF
        ENDWHILE
    ENDEVENT
;=======
endState

 

 

 

Another way could be a distance check between xmarker and the actor by using GetDistance().

WHILE (TRUE)
    float f = sitActor.GetDistance(self)
    IF (f > 100)                              ; adjust the distance, if required
       Debug.Notification("Stand up")
       RETURN ; - STOP -
    ENDIF
    Utility.Wait(0.25)
ENDWHILE

 

Edited by ReDragon2013
Link to comment
Share on other sites

Here is a simple script i use for the "Throne" furniture, the 'wait()' may have to be adjusted if any other furniture uses longer or shorter animation.


The order of 'wait()' and 'State' must not be modify in order for it to work properly.

All 'Furnitures' will send 3 activation events depending on which keyboard key the player uses to sit and get up, so the "States" and "Wait()" order is absolutely crucial.




Auto State WaitingPlayer
Event OnActivate(ObjectReference akActionRef)
if akActionRef == Game.GetPlayer()
GoToState("Busy")
Utility.Wait(2.0) ; 2 sec is required for the 'Sit' animation to play & finish
Blessing.Cast(akActionRef, akActionRef)
BlessingMessage.Show()
GoToState("StandingUp")
EndIf
EndEvent
EndState


State StandingUp
Event OnActivate(ObjectReference akActionRef)
GoToState("Busy") ; We block any other activation event and we keep the 2 we're interested, the third activation event is send to an 'Empty State' / Busy State
if akActionRef == Game.GetPlayer()
Utility.Wait(1.5) ; 1,5 sec is required for the 'Get Up' animation to play & finish

; Do here whatever you need to do

EndIf
GoToState("WaitingPlayer")
EndEvent
EndState


State Busy
Event OnActivate(ObjectReference akActionRef)
;Do nothing.
EndEvent
EndState



Have a happy modding.

Edited by maxarturo
Link to comment
Share on other sites

Works also for beds as long as the "Fade To Sleep" is deactivated and the actors do actually lie in the bed.


There are mods that add this "lie On Bed" animation for the player, though don't ask me for a name of the mod, i've just seen them on Nexus and i've never use them.


I just know it works cause i helped a fellow modder in the past who wanted to do something with this "lie On Bed" thing.

Link to comment
Share on other sites

Ah cool, that's good to know too. Actually since OnActivate works for leaving furniture, and you only care about when an actor gets up, you can use the condition IsFurnitureInUse to check. Like so:

Event OnActivate(ObjectReference akActionRef)
    Utility.Wait(2)
    If Self.IsFurnitureInUse(True) == False 
        ;do stuff, an actor has left this furniture. 
    Endif
EndEvent

I tested and the wait is necessary. If checking right away, it will still return True because the get up animation is playing and the actor hasn't fully left the furniture yet.

Link to comment
Share on other sites

You need an "Empty State" right after the "OnActivate()" for getting up/standing up so that when you press "E" the second 'Activation' events from the 2 that the "E" sends will be in the "Empty" state, this way it will never get process.

 

* I added a few explanations on the script i posted to explain why the script is formed this way.

Link to comment
Share on other sites

I'm trying OnSit and OnGetUp, but I'm having problems with an error that:

"Unable to bind script dz_activate_test to (0C18E704) because their base types do not match"

after a bit of googling it seemed that I was wrongly extending Actor instead of ObjectReference in my script that was attached to a seat marker.

I've made many mistakes as I've been learning to do scripts, many of them around extending the right thing, but that just resulted in a script that didn't work, as opposed to a script that doesn't attach. I don't even know what a base type is, if it is something that a marker can have.

 

Anyway, the reason I was extending actor in my script was that I got the compile error:

function onsit cannot be defined in state mcm_installed without also being defined in the empty state,

instead of extending actor i extended objectreference and added:

import actor

but that made no difference,

I had to add:

Event OnSit(ObjectReference akFurniture)
EndEvent

Event OnGetUp(ObjectReference akFurniture)
EndEvent

 

in the empty state, but if I understand correctly, that just defines my own empty versions of OnSit and OnGetUp

 

current state of whole script is here:

 

 

ScriptName dz_activate_test Extends ObjectReference


Actor sitActor
dz_undress_MCM_menu_script Property mcm  Auto         ;the quest script that holds the MCM menu
Actor  Property PlayerRef    Auto         ;this allows us to use the fast PlayerRef reference

Spell  Property dz_undress_spell  Auto            ;this is the spell that will undress NPCs

MagicEffect Property dz_undress_magic_effect  Auto        ;this is the magic effect from the spell
Form[]  Items                   ;this will store all equipped items except spells

Spell[] Spell_1                   ;to store equipped spells

Armor[] Slots
Weapon Lefthand                   ;we need to store the weapons in each hand separately

Weapon Righthand
Bool disrobed                            ;to track player undressed status
;;;define variable for camera state;;;

int iCameraState
Event OnLoad()

debug.messagebox("loading script")

If !(SKSE.GetVersion() > 0)

  debug.notification("SKSE64 was not found, please install SKSE64 for Diziet's Undressing mod")

  Return

EndIf

If !(Game.GetFormFromFile(0x00000814, "SkyUI_SE.esp"))        ;check if SkyUI is installed

  GoToState("no_mcm")                ;if not use the no-mcm state

Else

  GoToState("mcm_installed")              ;otherwise use the mcm installed state

EndIf

EndEvent
;ObjectReference Property dz_container Auto

;Actor Property NPC1 Auto
State no_mcm
Event OnActivate(ObjectReference akActionRef)

  sitActor = akActionRef as Actor

EndEvent

 

Event OnSit(ObjectReference akFurniture)

  debug.notification("sitting!")

  If sitActor == PlayerRef && !PlayerRef.isincombat()       ;checks to see if the trigger is the player and also not in combat

   dz_undress_player_F()              ;if so call the function to undress the player

  ElseIf (!(sitActor).isincombat())         ;is the trigger an actor (NPC)?

   dz_undress_NPC_F(sitActor)          ;then undress the NPC

  EndIf

EndEvent



Event OnGetUp(ObjectReference akFurniture)

  debug.notification("standing!")

  If sitActor == PlayerRef            ;checks to see if the actor is the player

     dz_redress_player_F()            ;if so call the function to re-dress the player

    ElseIf sitActor            ;is the actor an NPC?

     dz_redress_NPC_F(sitActor)         ;then re-dress the NPC

    EndIf

    sitActor = None

EndEvent



Function dz_undress_player_F()              ;define the function to undress the player

If ( disrobed )

  Return                      ;if the player is already undressed exit the function

EndIf

disrobed = True                           ;set the player is undressed variable
  iCameraState = Game.GetCameraState()           ;skse function

  If ( iCameraState == 0)

  ; change to third person

    Game.ForceThirdPerson()                      ;3rd Person

  Else

  EndIf
Lefthand = PlayerRef.GetEquippedWeapon(True)          ;store the left hand weapon - if any

Righthand = PlayerRef.GetEquippedWeapon(False)          ;store the righthand weapon - if any

Items = PO3_SKSEFunctions.AddAllEquippedItemsToArray(PlayerRef)      ;store all equipped items in an array using https://www.nexusmods.com/skyrimspecialedition/mods/22854
int i                    ;define this variable for use in arrays

Spell_1 = new Spell[4]                ;create the spells array

i = spell_1.Length                 ;size of spells array (should be 4)

While (i)

  i = i - 1

  spell_1[i] = PlayerRef.GetEquippedSpell(i)          ;fill the spells array

EndWhile
PlayerRef.UnEquipAll()                ;all stored, strip the player

EndFunction



Function dz_undress_NPC_F(Actor NPCRef)

  If (NPCRef as Actor).HasMagicEffect(dz_undress_magic_effect)

   Return                  ;then we are done, exit the function

  EndIf

  dz_undress_spell.Cast(NPCRef, NPCRef)              ;cast the undress spell on the NPC

EndFunction


Function dz_redress_player_F()              ;define the function to re-dress the player

If ( disrobed == true )                ;is the player undressed

Else

  Return                      ;the player is not undressed, exit the function

EndIf
;;return to first person if necessary

  If ( iCameraState == 0 )              ; skse function

   ; change to first person as player was initially

   Game.ForceFirstPerson()                       ; 1st Person

  EndIf
;;https://www.creationkit.com/index.php?title=EquipItemEx_-_Actor

int i                    ;define this variable for use in arrays

i = 0

While i < items.length                ;loop through the stored items

  If Items[i] As Armor || Items[i] As Ammo ||  Items[i] As Light     ;if stored items are armour or ammo or torch

   PlayerRef.EquipItemEx(Items[i],0,False,True)        ;re-equip them

  EndIf

  i = i +1

EndWhile
PlayerRef.EquipItemEx(Righthand,1,False,True)          ;re-equip the righthand

PlayerRef.EquipItemEx(Lefthand,2,False,True)          ;re-equip the lefthand
i = spell_1.Length

While (i)                   ;loop through the stored spells

  i = i - 1

  spell sp = spell_1[i]               ;if that spell position exists

  If ( sp )

   PlayerRef.EquipSpell(sp,i)             ;fill it

  EndIf

EndWhile
Disrobed = False                 ;store the dressed state of the player

EndFunction



Function dz_redress_NPC_F(Actor NPCRef)

  If (NPCRef as Actor).HasMagicEffect(dz_undress_magic_effect)

   NPCRef.DispelSpell(dz_undress_spell)          ;dispell the undress spell on the NPC

  EndIf

  Utility.Wait(0.5)

  If (!Game.GetFormFromFile(0x00000804, "dz_auto_outfits.esp"))     ;is diziet's auto outfits installed?

   Return

  Else

   (Game.GetFormFromFile(0x00000804, "dz_auto_outfits.esp") As Spell).Cast(NPCRef,NPCRef)

  EndIf

EndFunction
EndState
State mcm_installed
Event OnActivate(ObjectReference akActionRef)

  sitActor = akActionRef as Actor

EndEvent



Event OnSit(ObjectReference akFurniture)

  debug.notification("sitting!")

  If sitActor == PlayerRef              ;checks to see if the trigger is the player

   dz_undress_player_F()              ;if so call the function to undress the player                 ;we are done,exit the function

  ElseIf sitActor               ;is the trigger an actor (NPC)?

   dz_undress_NPC_F(sitActor)          ;then call the function to undress the NPC

  EndIf

EndEvent



Event OnGetUp(ObjectReference akFurniture)

  debug.notification("standing!")

  If sitActor == PlayerRef            ;checks to see if the actor is the player

   dz_redress_player_F()            ;if so call the function to re-dress the player

  ElseIf sitActor            ;is the trigger an NPC?

   dz_redress_NPC_F(sitActor)         ;then re-dress the NPC

  EndIf

   sitActor = None

EndEvent



Function dz_undress_player_F()              ;define the function to undress the player

  iCameraState = Game.GetCameraState()           ;store whether first/third person

  If iCameraState == 0 && mcm.third_person == True

   Game.ForceThirdPerson()

  EndIf
  If mcm.disrobes == false || Disrobed == True         ;if the MCM menu has player undressing toggled off, or the player is already undressed

   Return                  ;then exit the function

  EndIf
  If mcm.ignoreCombat == True || !PlayerRef.IsInCombat()       ;MCM menu 'Ignore Combat is toggled on or the player is not in combat

  Else                   ;otherwise

   Return                  ;then exit the function

  EndIf
  Lefthand = PlayerRef.GetEquippedWeapon(True)         ;store the left hand weapon - if any

  Righthand = PlayerRef.GetEquippedWeapon(False)         ;store the righthand weapon - if any

  Items = PO3_SKSEFunctions.AddAllEquippedItemsToArray(PlayerRef)     ;store all equipped items in an array using https://www.nexusmods.com/skyrimspecialedition/mods/22854
  int i                   ;define this variable for use in arrays

  Spell_1 = new Spell[4]               ;create the spells array

  i = spell_1.Length                ;size of spells array (should be 4)

  While (i)

   i = i - 1

   spell_1[i] = PlayerRef.GetEquippedSpell(i)         ;fill the spells array

  EndWhile
  Slots = New Armor[32]

  If mcm.player_hair_slots == True || mcm.npc_hair_slots == True || mcm.all_slots == True

   Slots = dz_get_all_player_slots()

  EndIf
  If mcm.slow_unequip == True

   ;debug.messagebox("slower unequipping")

   dz_slow_unequip(PlayerRef)

   Else

   PlayerRef.UnEquipAll()              ;all stored, strip the player

  EndIf
  If mcm.player_hair_slots == True

   If mcm.ignorehair == True             ;re-equip problematic slots if enabled

   PlayerRef.equipitemex(slots[1],0,False,True)

   EndIf

   If mcm.ignorelonghair == True

   PlayerRef.equipitemex(slots[11],0,False,True)

   EndIf

   If mcm.ignorecirclet == True

   PlayerRef.equipitemex(slots[12],0,False,True)

   EndIf

  ElseIf mcm.all_slots == True

   dz_fill_player_slots()

  EndIf
  Disrobed = True                 ;store the undressed state of the player

EndFunction



Function dz_undress_NPC_F(Actor NPCRef)

  If (mcm.ignorenpcCombat) || !(NPCRef as Actor).IsInCombat()      ;actor "should ignore combat" or "is not in combat"

   dz_undress_spell.Cast(NPCRef, NPCRef)             ;cast the undress spell on the NPC

  EndIf

EndFunction



Function dz_slow_unequip(Actor aRef)

  Form[] check_items = PO3_SKSEFunctions.AddAllEquippedItemsToArray(aRef)      ;store all equipped items in an array

  Int arr_length = check_items.Length

  Int i = 0

  String[] kwords = mcm.keywords_list

  Bool keep

  While i < arr_length

   Int j = 0

   keep = False

   While j < kwords.Length

   Keyword testKW = Keyword.GetKeyword(kwords[j])

    ;debug.messagebox("testKW is "+testKW)

    If check_items[i].HasKeyword(testKW) == True

    keep = True

    EndIf

   j += 1

   EndWhile

   If keep == False

   aRef.UnEquipitemEx(check_items[i])

   EndIf

  i += 1

  EndWhile

EndFunction



Armor[] Function dz_get_all_player_slots()

  Armor[] temp

  temp = New Armor[32]

  Int i

  i = 0

  While i < temp.Length

   temp[i] = PlayerRef.GetEquippedArmorInSlot(i + 30)

   i = i + 1

  EndWhile

  Return temp

EndFunction
Function dz_fill_player_slots()

  Int i

  i = 0

  While i < mcm.ignoremoreslots.Length

   If mcm.ignoremoreslots[i] == True

   PlayerRef.equipitemex(slots[i],0,False,True)

   EndIf

   i = i + 1

  EndWhile

EndFunction





Function dz_redress_player_F()              ;define the function to re-dress the player

  If mcm.third_person == true && iCameraState == 0        ;if the MCM menu to force third person on entry is toggled on and the player was originally in first person

   Game.ForceFirstPerson()              ;then force back to first person

  EndIf
  If Disrobed == False               ;the player is not undressed

   Return                  ;exit the function as re-dressing not needed

  EndIf
  PlayerRef.EquipItemEx(Righthand,1,False,True)         ;re-equip the righthand

  PlayerRef.EquipItemEx(Lefthand,2,False,True)         ;re-equip the lefthand
  int i                   ;define this variable for use in arrays
  i = 0

  While i < items.length               ;loop through the stored items

   If Items[i] As Armor || Items[i] As Ammo ||  Items[i] As Light    ;if stored items are armour or ammo or torch

    PlayerRef.EquipItemEx(Items[i],0,False,True)       ;re-equip them

   EndIf

   i = i +1

  EndWhile
  i = spell_1.Length

  While (i)                  ;loop through the stored spells

   i = i - 1

   spell sp = spell_1[i]              ;if that spell position exists

   If ( sp )

    PlayerRef.EquipSpell(sp,i)            ;fill it

   EndIf

  EndWhile
  Disrobed = False                ;store the dressed state of the player

EndFunction



Function dz_redress_NPC_F(Actor NPCRef)

  If (NPCRef as Actor).HasMagicEffect(dz_undress_magic_effect)     ;does the NPC have the spell on them?

   NPCRef.DispelSpell(dz_undress_spell)          ;dispell the undress spell on the NPC

  EndIf

  Utility.Wait(0.5)

  If (!Game.GetFormFromFile(0x00000804, "dz_auto_outfits.esp"))     ;is diziet's auto outfits installed?

   Return

  Else

   (Game.GetFormFromFile(0x00000804, "dz_auto_outfits.esp") As Spell).Cast(NPCRef,NPCRef)

  EndIf

EndFunction



EndState
;;;dummy functions to keep the compiler happy;;;

Function dz_undress_player_F()

EndFunction
Function dz_redress_player_F()

EndFunction
Function dz_undress_NPC_F(Actor NPCRef)

EndFunction
Function dz_redress_NPC_F(Actor NPCRef)

EndFunction
Armor[] Function dz_get_all_player_slots()

EndFunction
Function dz_fill_player_slots()

EndFunction
Function dz_slow_unequip(Actor aRef)

EndFunction
Event OnSit(ObjectReference akFurniture)

EndEvent
Event OnGetUp(ObjectReference akFurniture)

EndEvent

 

 

 

diziet

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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