Jump to content

Make torch go out when player crouches in water?


Recommended Posts

As torches are important in my mod, waterfalls and large volumes of water dowse them and they are few and far between in a very dark world... (intake breath)... I've noticed an issue that I can either say "One of those things" and lose immersiveness or try to deal with. Torches stay lit when player crouches in water. I'm not at all sure how/if I can tackle this. Ideas welcome please.

 

 

Link to comment
Share on other sites

Listen for when the player goes into sneak mode while in the water and do the same trick that you worked out earlier for walking through waterfalls.

 

There is no such thing as an OnSneak event but you can monitor for the animation events. Or you can do an update loop when the player enters walk-able waterways that checks the IsSneaking function and deal with the torch at that point. There may be a delay depending upon update loop time and when the player starts sneaking.

Link to comment
Share on other sites

Right... I have no idea of how to "Listen for when player goes into sneak mode". The "same trick" as I did for waterfalls? You mean put a triggerbox on every body of water in my mod? How would this work for the world default water? An "update loop"... what?

Sorry but none of this helps me.

Link to comment
Share on other sites

OnAnimationEvent

RegisterForAnimationEvent

From https://www.creationkit.com/index.php?title=Animation_Events

 

Sneaking:

  • Non-combat:
    • Enter sneaking while standing: tailSneakIdle
    • Enter sneaking while moving: tailSneakLocomotion
    • Leave sneaking while standing: tailMTIdle
    • Leave sneaking while moving: tailMTLocomotion

 

  • During Combat:
    • Enter sneaking while standing: tailSneakIdle
    • Enter sneaking while moving: tailSneakLocomotion
    • Leave sneaking while standing: tailCombatIdle
    • Leave sneaking while moving: tailCombatLocomotion

 

  • Important: You'll need to track the player's Sneak state in your script, because the "enter sneaking" events will re-fire if the player jumps or falls and you may not want your script to react to every event. Relatedly, if the terrain is a bit irregular, the sneaking events may re-fire even if the character is standing still and the camera simply moves to the left/to the right.

 

That would get when the player is starting and stopping sneak.

 

But you have to know when they enter the water. The animation event system is able to track when the player starts and stops swimming. It is unable to determine if the player is in walk-able water areas. So that method is unfortunately out. Thus you'll need to place trigger boxes in the walk-able water areas of the game.

 

We discussed how to remove the torch when entering falling water or being submerged in this thread: https://forums.nexusmods.com/index.php?/topic/7743578-removing-an-equipped-item-how/

Same principle here, you just have to set it up first so that it will work.

Link to comment
Share on other sites

Right... I have no idea of how to "Listen for when player goes into sneak mode". The "same trick" as I did for waterfalls? You mean put a triggerbox on every body of water in my mod? How would this work for the world default water? An "update loop"... what?

Sorry but none of this helps me.

You can use the following guide to "listen" for when the player sneaks by using the IsSneaking condition function.

 

https://www.creationkit.com/index.php?title=Passing_Conditions_to_Papyrus

 

Edit:

 

As for detecting the water, the best way I can think of is spawning a tiny invisible actor at the player's feet using GetPositionZ(), and either using SKSE to check Actor.IsSwimming(), or the same method as above but using the IsSwimming condition function. Bear in mind that it will have a little delay.

 

That's how I detect if the player has placed an animal trap under water.

Link to comment
Share on other sites

If you use trigger boxes at the walk-able water areas, I would use the OnTriggerEnter event to see if they entered while sneaking with the IsSneaking function call. If they are, deal with the torch. If they are not, register for the appropriate animation events and deal with the torch once they do enter sneak. When they leave the trigger box whether they entered sneak or not, unregister for the animation events by using the OnTriggerLeave event.

 

Something else to consider, player can equip a torch while sneaking in the water. You would also need to use the trigger box to set a global variable so that a reference alias script on the player knows to unequip the torch immediately after the player equips it.

Link to comment
Share on other sites

IsharaMeradin way is the best approach to this.


My second suggestion is to create your own torch mesh and make you own CK torch, with the main difference been that the flame FX will be a phosphorus flame FX, a "Phosphorus Torch", this way there will be no visual issue with a torch been lit under water, and you can pre set the time in which the torch will last.


* This requires good knowledge of at least Nifskope.

Edited by maxarturo
Link to comment
Share on other sites

player based ReferenceAlias as follow, keep in mind to adjust the scriptname to make it unique, just an idea:

 

To detect water walking you could use spell ability like DLC2 water quest and activate a special effect to the player that will be detected.

 

xyzPlayerAliasScript

 

Scriptname xyzPlayerAliasScript extends ReferenceAlias
; https://forums.nexusmods.com/index.php?/topic/7783138-make-torch-go-out-when-player-crouches-in-water/

  MiscObject  PROPERTY Torch    auto    ; Torch you like to track

  Spell       PROPERTY WaterSpell auto
  MagicEffect PROPERTY Watering   auto    ; effect of selfmade cloak spell, to track if player is in water


; -- EVENTs --

; https://www.creationkit.com/index.php?title=List_of_Animation_Variables
; IF (player.GetAnimationVariableInt("iState") == 63)
; IF (player.GetAnimationVariableInt("SwimDirection") > 0)


EVENT OnInit()
    RegisterForSingleUpdateGameTime(0.0)        ; game check first time
ENDEVENT


EVENT OnUpdateGameTime()    ; see "Alias.psc"
    actor player = self.GetActorReference()
    WaterSpell.Cast(player as ObjectReference)

    IF (player.GetEquippedItemType(0) == 11) || (player.GetEquippedItemType(1) == 11)    ; 0 = left, 1 = right hand
        ; player already has a torch in hand
        myF_Register()
    ENDIF
ENDEVENT


EVENT OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
; received when this actor equips something - akReference may be None if object is not persistent (only if this alias points at an actor)
    IF (akBaseObject == Torch as Form)
        myF_Register()
    ENDIF
ENDEVENT



;========================
state Waiting
;============
EVENT OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
; received when this actor unequips something - akReference may be None if object is not persistent (only if this alias points at an actor)
    myF_UnRegister()
ENDEVENT


EVENT OnAnimationEvent(ObjectReference akSource, String asEventName)    ; see "Alias.psc"
; sent when an object we are listening to hits one of the events we are listening for
    gotoState("Sneaking")
    RegisterForSingleUpdate(0.5)
ENDEVENT
;=======
endState


;========================
state Sneaking
;=============
EVENT OnUpdate()
    actor player = self.GetActorReference()

IF player.IsSneaking()
    IF player.HasMagicEffect(Watering)
        player.UnequipItem(Torch)           ; sneaking into water
    ELSE    
        RegisterForSingleUpdate(1.0)        ; sneaking on dry terrain
    ENDIF
ENDIF
ENDEVENT
;=======
endState


; -- FUNCTIONs --

;----------------------
FUNCTION myF_Register()
;----------------------
    gotoState("Waiting")            ; ### STATE ###

    objectReference playerRef = self.GetReference()
    RegisterForAnimationEvent(playerRef, "tailSneakIdle")            ; enter sneaking while standing
    RegisterForAnimationEvent(playerRef, "tailSneakLocomotion")      ; enter sneaking while moving
ENDFUNCTION


;------------------------
FUNCTION myF_UnRegister()
;------------------------
    UnRegisterForUpdate()
    gotoState("")                    ; ### STATE ###

    objectReference playerRef = self.GetReference()
    UnRegisterForAnimationEvent(playerRef, "tailSneakIdle")
    UnRegisterForAnimationEvent(playerRef, "tailSneakLocomotion")
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

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