Making event occur based on distance. Compiles but broken.

Post » Wed Sep 14, 2016 10:22 pm

So my whole "Door locking idea" I suppose requires so many conditions that may not even exist nobody could even make a script for it. However as an alternative here is something I managed to put together.



The way it works is a spell similar to throw voice which uses an explosion to spawns an activator, that disables the two Kmarkers the Skyrim zombies and Solstheim zombies use as an enable parent, and the activator also spawns another activator that acts as both the visual and the distance measuring point. The first activator the script is on also uses null textures so you don't see two objects being spawned, and the activator it spawns has no script on it, it's only there to measure distances/be a visual cue.



The only script I'd ever put on the second activator would be an on activate to simulate picking up a lantern, where the "static" activator is sent back to it's unreachable interior cell, and a vanilla lantern is added to the players inventory, but that is much simpler than this other script, and unrelated to my current issues. It is a power that can only be used once every 24 hours, and will require a lantern to be successfully casted, and of course I'll provide a way to craft lanterns as well though that's again another subject.



Scriptname AAAWardOffZombersScript extends ObjectReference

Actor Property PlayerRef Auto
Spell Property AKWardOffZombersSpell Auto
ObjectReference Property ZeCandleActivaitor Auto
ObjectReference Property KMarker Auto
ObjectReference Property KMarkerSolstheim Auto
ObjectReference Property ZeCandleActivatorMarker Auto


Event OnLoad()
Debug.MessageBox("This lantern will ward off the undead so long as you don't travel too far from it")
ZeCandleActivaitor.Moveto(PlayerRef)
kMarker.Disable()
kMarkerSolstheim.Disable()
EndEvent

Event OnUpdate()
if PlayerRef.GetDistance(ZeCandleActivaitor) > 4096
kMarker.Enable()
kMarkerSolstheim.Enable()
Debug.MessageBox("You have walked past the boundaries of safety the lantern provided and the Undead are likely to search for you now.")
ZeCandleActivaitor.Moveto(ZeCandleActivatorMarker)
self.delete()
Endif
Endevent


Scriptname AAAWardOffZombersScript extends ObjectReference

Actor Property PlayerRef Auto
Spell Property AKWardOffZombersSpell Auto
ObjectReference Property ZeCandleActivaitor Auto
ObjectReference Property KMarker Auto
ObjectReference Property KMarkerSolstheim Auto
ObjectReference Property ZeCandleActivaitorMarker Auto


Event OnLoad()

If PlayerRef.GetDistance(ZeCandleActivaitor) > 4096
Debug.MessageBox("This lantern will ward off the undead so long as you don't travel too far from it")
ZeCandleActivaitor.Moveto(PlayerRef)
kMarker.Disable()
kMarkerSolstheim.Disable()
ElseIf PlayerRef.GetDistance(ZeCandleActivaitor) < 4096
kMarker.Enable()
kMarkerSolstheim.Enable()
Debug.MessageBox("You have walked past the boundaries of safety the lantern provided and the Undead are likely to search for you now.")
ZeCandleActivaitpr.Moveto(ZeCandleActivaitorMarker)
self.delete()
Endif
EndEvent


Again I experimented with a much smaller distance of 10 units and it didn't work either. I first tried to use the first script and when it didn't work I tried the second script which has the same problems.



Now- it seems like it is ALMOST perfect- or at least the FIRST part of the script, only problem is, when I walk past 4096 units, the second script function never occurs. No debug messages of the second debug message at all, and the lantern then follows me around. I also experimented with a distance of 40 units instead and that didn't work any better.



Can someone please explain what I did wrong with my script, and how I can add the secondary function after "Event OnUpdate()" to my script? Was event on Update the wrong thing to begin with or something? I also made an extremely similar script that won't quite work the right way either.






User avatar
TASTY TRACY
 
Posts: 3282
Joined: Thu Jun 22, 2006 7:11 pm

Post » Wed Sep 14, 2016 9:18 am

Event OnUpdate() will not work unless you register for one first.



Then you need to register for it again inside the Event OnUpdate() event. Do NOT ever do any Event OnUpdate() other than a SINGLE OnUpdate. You will bloat the system.



Using OnUpdate is a bad idea anyway unless you make each one take a long duration to repeat like 5 seconds. AND then be sure to shut it off as soon as you get the results needed.



You could instead dynamically place a trigger box around the light, then when the actor leaves the trigger box area this would shut it down. Or instead use a cloak spell around the light. Or use a one off event to check the distance such as onkey up for the forward button using SKSE.



No offence man, but I have a feeling you may need to do some scripting tutorials if you have not done so already.




Edit: OK I see that you have other posts that indicate that you have completed several mods (you are not a beginner), so I do not get why you did not include the onupdate register in your script.


Maybe you just had a very late night (that has happen to me a few times). Maybe I am misunderstanding your post. If so I apologize.





Example


Function SomeFunction()

RegisterForSingleUpdate(5.0) ; Before we can use OnSingleUpdate() we must register.

EndFunction



Event OnUpdate() ; This event occurs in five seconds from when it is registered.

If ; whatever you are checking

; do something

else

RegisterForSingleUpdate(5.0) ; in another 5 seconds this will loop again.

EndIf


EndEvent
User avatar
Kim Bradley
 
Posts: 3427
Joined: Sat Aug 18, 2007 6:00 am

Post » Wed Sep 14, 2016 9:06 pm


Most of my scripts are relatively simple, and from what I remember none of them have ever used the OnUpdate Register function... The vast majority of my scripts are either spell casted scripts, spell add scripts, on strike scripts, on equip scripts, or onactivate scripts. Hence my lack of understanding something quite simple. I did finally figure out a script though, or rather two combined scripts to solve this dilemma.



Thank you for telling me about Register for update btw it was the key to making the right script. I needed a nights sleep to restore full thinking function and a few hours of experimental scripts but I finally figured it out. Also I now just use one activator not bothering with the second at all. For anyone who wants to make a mod using similar script mechanics to this one here are the two scripts that combined together work...



First the primary script.



Scriptname AAAWardOffZombersScript extends ObjectReference

Actor Property PlayerRef Auto
Spell Property AKWardOffZombersSpell Auto
ObjectReference Property ZeCandleActivaita Auto
ObjectReference Property KMarker Auto
ObjectReference Property KMarkerSolstheim Auto
ObjectReference Property ZeCandleActivaitaMarker Auto

Event OnLoad()
Debug.MessageBox("This lantern will ward off the undead so long as you don't travel too far from it")
kMarker.Disable()
kMarkerSolstheim.Disable()
RegisterForSingleUpdate(1)
EndEvent

This disables the markers which disables the characters which use them as parent enablers, on load makes it automatic when the activator is in the same cell as a player, and an empty explosion spawn script ref magic effect spawns the activator.



Then the secondary script...



Scriptname AAAAWardOfZombersScriptSCnd extends ObjectReference

Actor Property PlayerRef Auto
ObjectReference Property KMarker Auto
ObjectReference Property KMarkerSolstheim Auto


Event OnLoad()
Self.RegisterForUpdate(10)
Self.RegisterForSingleUpdateGameTime(24.0)
EndEvent

Event OnUpdate()

if PlayerRef.GetDistance(Self) <= 400
Debug.MessageBox("You still bask in the safety of the lantern!!!")
Self.RegisterForSingleUpdate(10)


ElseIf PlayerRef.GetDistance(Self) >= 400
Debug.MessageBox("You have walked past the boundaries of safety the lantern provided and the Undead are likely to search for you now.")
Self.UnregisterForUpdate()
kMarker.Enable()
kMarkerSolstheim.Enable()
self.delete()
Endif
EndEvent

Event OnUpdateGameTime()
Self.RegisterForSingleUpdateGameTime(24.0)
Debug.Notification("The Lantern needs to be fixed")
kMarker.Enable()
kMarkerSolstheim.Enable()
self.delete()
Self.UnregisterForUpdate()
EndEvent


Because of the SELF reference system built into every script my tired foolish "Use a secondary activator thing" was entirely pointless and a waste of data. The second script re-enables said enemies/characters, undead stalkers in this case. When near the lantern by 4096 units about one cell in size, the second script endlessly repeats itself, but once you walk one cell or 4096 units away the script stops repeating itself, and the function that deletes the lantern and re-enables said characters activates.



I might be making a few modifications but the basic framework of the script is now functioning properly. The debug messages will also be removed of course.

User avatar
CSar L
 
Posts: 3404
Joined: Fri Nov 09, 2007 9:36 pm


Return to V - Skyrim