dizietemblesssma Posted March 30, 2021 Share Posted March 30, 2021 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 More sharing options...
ReDragon2013 Posted March 30, 2021 Share Posted March 30, 2021 (edited) 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 March 30, 2021 by ReDragon2013 Link to comment Share on other sites More sharing options...
dizietemblesssma Posted March 30, 2021 Author Share Posted March 30, 2021 Thankyou,I'm assuming that:4: Sitting, wants to standas on the CK page means that the actor is beginning to stand up, or that the player - while sitting - has just pressed a movement key? diziet Link to comment Share on other sites More sharing options...
dylbill Posted March 30, 2021 Share Posted March 30, 2021 I tend to avoid polling whenever possible because it can bog down the script engine. There's an event OnGetUp: https://www.creationkit.com/index.php?title=OnGetUp_-_Actor for actors. So, you could use the OnActivate event to add a spell ability to the actor that has a script with the OnGetUp event, Or you could use a reference alias with ForceRefTo. Link to comment Share on other sites More sharing options...
maxarturo Posted March 30, 2021 Share Posted March 30, 2021 (edited) 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 March 30, 2021 by maxarturo Link to comment Share on other sites More sharing options...
dylbill Posted March 30, 2021 Share Posted March 30, 2021 Nice, I didn't know if the OnActivate event would fire for getting up from furniture too. That's good to know. Link to comment Share on other sites More sharing options...
maxarturo Posted March 30, 2021 Share Posted March 30, 2021 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 More sharing options...
dylbill Posted March 30, 2021 Share Posted March 30, 2021 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 EndEventI 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 More sharing options...
maxarturo Posted March 30, 2021 Share Posted March 30, 2021 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 More sharing options...
dizietemblesssma Posted March 30, 2021 Author Share Posted March 30, 2021 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 actorbut that made no difference,I had to add:Event OnSit(ObjectReference akFurniture)EndEventEvent 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 More sharing options...
Recommended Posts