Night Eye Bug

Post » Tue Jun 19, 2012 3:42 pm

I'm having an interesting problem. I've created a perk that adds the Night Eye effect to the character while sneaking in dark areas. But as it turns out, the Night Eye effect itself has an issue with it's script that causes it to break and stay on permanently if you toggle the effect on and then back off again before that initial fade-in effect can finish.
Something as simple as double-tapping Sneak with this perk will trigger the issue.
For reference, I'll post the script. I don't know Papyrus very well yet, so I'd really like some help figuring out how this can be fixed:
Spoiler
scriptName magicNightEyeScript extends ActiveMagicEffect
{Scripted effect for the Night Eye Spell}

import GlobalVariable

;======================================================================================;
; PROPERTIES /
;=============/

float property fDelay = 0.83 auto
{time to wait before switching to constant Imod}
ImageSpaceModifier property IntroFX auto
{IsMod applied at the start of the spell effect}
ImageSpaceModifier property MainFX auto
{main isMod for spell}
ImageSpaceModifier property OutroFX auto
{IsMod applied at the end of the spell effect}
Float Property fImodStrength = 1.0 auto
{IsMod Strength from 0.0 to 1.0}
sound property IntroSoundFX auto ; create a sound property we'll point to in the editor
sound property OutroSoundFX auto ; create a sound property we'll point to in the editor
GlobalVariable Property NightEyeTransitionGlobal auto
;MagicEffect Property NightEyeEffect auto
;Spell Property NightEyeDispelEffectSpell auto
; Obtain the target of the active fire effect

;Actor CasterActor
;======================================================================================;
; EVENTS /
;=============/

Event OnEffectStart(Actor Target, Actor Caster)
;CasterActor = Caster

; IntroFX.remove()
; MainFX.remove() ;Kill Imods from another cast, if running.
; OutroFX.remove()

if NightEyeTransitionGlobal.GetValue() == 0.0
NightEyeTransitionGlobal.setValue(1.0)
int instanceID = IntroSoundFX.play((target as objectReference)) ; play IntroSoundFX sound from my self
introFX.apply(fImodStrength) ; apply isMod at full strength
utility.wait(fDelay) ; NOTE - neccessary?
;MainFX.apply()
if NightEyeTransitionGlobal.GetValue() == 1.0
introFX.PopTo(MainFX,fImodStrength)
NightEyeTransitionGlobal.setValue(2.0)
endif
elseif NightEyeTransitionGlobal.GetValue() == 1.0
introFX.PopTo(MainFX,fImodStrength)
NightEyeTransitionGlobal.setValue(2.0)
self.dispel()
else
self.dispel()
endif

EndEvent

; Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect NightEyeEffect)
; NightEyeDispelEffectSpell.Cast(CasterActor)
; endEvent

Event OnEffectFinish(Actor Target, Actor Caster)
; if NightEyeTransitionGlobal.GetValue() == 1.0
; utility.wait(fDelay)
; endif
; ;debug.trace (self + ": We are killing the spell. The Globale is: " + NightEyeTransitionGlobal.GetValue())
if NightEyeTransitionGlobal.GetValue() == 2.0
NightEyeTransitionGlobal.setValue(3.0)
; ;debug.trace (self + ": This is a valid outro play, see because 2.0 = " + NightEyeTransitionGlobal.GetValue())
int instanceID = OutroSoundFX.play((target as objectReference)) ; play OutroSoundFX sound from my self
;MainFX.remove()
MainFX.PopTo(OutroFX,fImodStrength)
introFX.remove()
NightEyeTransitionGlobal.setValue(0.0)
endif

endEvent

I tried the simple approach of just making the effect a self-refreshing duration-based effect by setting it as Fire and Forget and giving it a duration of a couple seconds, but somehow it behaves in exactly the same way as when it's just Constant.
I think the simplest way to fix this would be to find a way to stop the script from attempting to disable itself at any point less than a couple seconds before it was originally activated.
User avatar
Ludivine Dupuy
 
Posts: 3418
Joined: Tue Mar 27, 2007 6:51 pm

Post » Tue Jun 19, 2012 4:06 pm

Since the behavior of the effect is controlled by the script what you set in the magic effect record, simply doesn't matter.
Also the script should handle subsequent re-casts just fine, it finishes the intro and then disable the effect.

Well, since the effect stays, that means you enter the else-clause in OnEffectStart which effectively does nothing -- it could just as well not be there. And that means, the re-cast is happening before the second line of OnEffectStart has run, that's bad.
I don't think there is anything that can be done.
User avatar
Wayland Neace
 
Posts: 3430
Joined: Sat Aug 11, 2007 9:01 am

Post » Tue Jun 19, 2012 4:36 am

looks like its the
Utility.Wati(fDelay)

that .83 seconds is long enough for you to sneak/unsneak
Whats happening: You enter sneak, the OnEffectStart Event starts, the wait .83 seconds starts, you exit sneak before that .83 seconds is over (which breaks the script because its stuck in wait when the OnEffectFinish should be triggering)

I'm just guessing here, but I'd say the .83 second wait is just for aesthetics (makes it look pretty as its applying the various effects to you)
Try commenting out that Utility.Wait line by putting a ";" in front of it
User avatar
Jeff Tingler
 
Posts: 3609
Joined: Sat Oct 13, 2007 7:55 pm

Post » Tue Jun 19, 2012 3:20 pm

Awesome, you were right, cscottydont.
It creates a rather jarring and immediate start to the effect, but at least it doesn't break anymore.
User avatar
Ashley Campos
 
Posts: 3415
Joined: Fri Sep 22, 2006 9:03 pm


Return to V - Skyrim