maxarturo Posted April 7, 2019 Share Posted April 7, 2019 (edited) This is a simple Script that refuses to do what i want !!... The script is attached to a "trigger box Activator" that when it gets Activated - Triggered by an "xMarker Activator" is suppose to be doing the following but it is not : 1) Is suppose to cast Thunderbolts in a "random time" between & every 4 & 6 sec. * Now it's only casting the spell one time when it gets activated and one when it gets deactivated. 2) Is suppose to cast the spell to a chain of linked xMarkers. The "Trigger Box Activator" is Linked Ref to > xMarker A, the xMarker A is Linked to > xMarker B, the xMarker B is linked to > xMarker C, the xMarker C is linked to > xMarker D. It should cast the spell first to A, then to B, then C, then D. Now it's casting exactly in the middle of the four Linked xMarkers. * If i remove the Link Ref from the "Trigger Box" it will cast it in random places. This is my working Script, my other scripting attempts to rectify those issues resulted in very weird things. Scriptname aXMDRandomLightningStrikeTrigSCRIPT01 extends ObjectReference {Casts Random LightningBolt - Spell OnActivate} import utility import game Float Property WaitForCastMax = 10.0 Auto {Max time between strikes. DEFAULT = 10} Float Property WaitForCastMin = 8.0 Auto {Min time between strikes. DEFAULT = 8} Spell Property LightningSpell Auto {Lightning spell that randomly gets cast} Bool ShouldCastLightning = FALSE bool Property isTriggered = false auto hidden Int MaxLightningPoints ; Max link ref points counted Int CurrentCastPoint ; Current point we are casting too Event onActivate(ObjectReference akActionRef) Wait(RandomFloat(WaitForCastMin, WaitForCastMax)) MaxLightningPoints = GetLinkedRef().CountLinkedRefChain() (GetNthLinkedRef(CurrentCastPoint).Is3dLoaded()) ShouldCastLightning = TRUE Utility.wait(1.0) LightningSpell.Cast(self, GetNthLinkedRef(CurrentCastPoint)) ENDEVENT Function HandleLightning() While(ShouldCastLightning == TRUE) Wait(RandomFloat(WaitForCastMin, WaitForCastMax)) ; If this trigger is unloaded don't bother casting the spell at all if(GetParentCell().IsAttached()) LightningSpell.Cast(self, GetNthLinkedRef(CurrentCastPoint)) endif EndWhile EndFunction PS : I don't really care about the spell's damage, the damage is handled by another activator, this is just for the visual FX. This last puzzle is really giving me a headache to correctly put together. Thank you very much in advance to whomever might takes a look at this !!!. Edited April 7, 2019 by maxarturo Link to comment Share on other sites More sharing options...
foamyesque Posted April 7, 2019 Share Posted April 7, 2019 (edited) Well, for the first part, you never actually call the HandleLightning function, so it never runs, which means you never enter the while loop. You get the one cast you ask for in the OnActivate event and that's it. You also have, as far as I can tell, nothing that's going to set it to stop casting, but perhaps that's a future problem... I would, instead of a while loop with a long latency, register for a single update. In that update, check if ShouldCastLightning is true, fire your cast, then register for another update within the bounds you've set for the interval between casts. That way any changes to ShouldCastUpdate (i.e. setting it to false because the player did something, the cell detached, etc) will immediately stop the loop. It doesn't target because you never set or update the CurrentCastPoint integer. With it set to zero, the default integer initialization, GetNthLinkedRef() will return the ObjectReference it is being called on. That leads to the game being told to cast an aimed spell on the thing casting it, which makes it discard the targeting parameter and fire it in the reference's heading instead. In the aforementioned OnUpdate() block, add a check to set it to 0 if it is at MaxLightningPoints, and then, after the if block, a CurrentCastPoint+=1 incrementor. Should fix it. Edited April 7, 2019 by foamyesque Link to comment Share on other sites More sharing options...
ReDragon2013 Posted April 7, 2019 Share Posted April 7, 2019 (edited) Maybe something like that with OnUpdate(), HandleLightning() and ShouldCastLightning + CurrentCastPoint as foamyesque explained to you: aXMDLightningTriggerSCRIPT Scriptname aXMDLightningTriggerSCRIPT extends ObjectReference {to cast random LightningBolts} ; attached to a "trigger box Activator", which gets activated by "xMarker Activator" ; https://forums.nexusmods.com/index.php?/topic/7546526-i-have-two-issues-with-a-simple-script/ Spell PROPERTY LightningSpell auto {Lightning spell that is randomly casted} Float PROPERTY WaitForCastMax = 10.0 auto ; 10.0, Max time between strikes. Float PROPERTY WaitForCastMin = 8.0 auto ; 8.0, Min time between strikes. Int iCurrentPoint ; [default=0], used with "GetNthLinkedRef(x)" ;Bool PROPERTY isTriggered auto Hidden ; [default=False] Bool ShouldCastLightning ; -- EVENts -- EVENT OnActivate(ObjectReference akActionRef) ;;;IF (akActionRef == Game.GetPlayer() as ObjectReference) gotoState("Waiting") ; ### STATE ### triggerBox has been activated ShouldCastLightning = TRUE ; *T* RegisterForSingleUpdateGameTime(0.0) ;;;ENDIF ENDEVENT EVENT OnCellDetach() IF ( ShouldCastLightning ) ShouldCastLightning = False ; *** UnRegisterForUpdate() ENDIF ENDEVENT ;============================================= state Waiting ;============ EVENT OnActivate(ObjectReference akActionRef) ; protect activation, while waiting for lights ENDEVENT EVENT OnUpdateGameTime() float f = Utility.RandomFloat(WaitForCastMin, WaitForCastMax) ; calculate random wait time IF ( ShouldCastLightning ) RegisterForSingleUpdate(f) ; register the other update event for lightning ENDIF ENDEVENT EVENT OnUpdate() HandleLightning() ENDEVENT ;======= endState ; -- FUNCTION -- ; https://www.creationkit.com/index.php?title=GetNthLinkedRef_-_ObjectReference ; self.GetNthLinkedRef(0) == self ; "Trigger Box Activator" ; self.GetNthLinkedRef(1) == self.GetLinkedRef() ; returns xMarker A ; self.GetNthLinkedRef(2) == self.GetLinkedRef.GetLinkedRef() ; returns xMarker B ; .. ;------------------------- FUNCTION HandleLightning() ;------------------------- objectReference oRef ;;; Utility.Wait(1.0) ; for what ?? IF ( ShouldCastLightning ) oRef = self.GetNthLinkedRef(iCurrentPoint) ; first time, it runs with GetNthLinkedRef(0) ENDIF IF ( oRef ) iCurrentPoint += 1 ; set for next linkedRef ELSE iCurrentPoint = 0 ; reset this variable EDIT: 2019/04/14 gotoState("") ; ### STATE ### leave current state, wait for next activation RETURN ; - STOP - no more points /or/ mod has been uninstalled ENDIF ;--------------------- IF ( ShouldCastLightning ) LightningSpell.Cast(self, oRef) RegisterForSingleUpdateGameTime(0.0) ENDIF ENDFUNCTION Edited April 14, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
maxarturo Posted April 7, 2019 Author Share Posted April 7, 2019 For start, thank you both !!. I'm not a professional Scripter or the most experienced, what i've manage to learn is from a lot of research and experimentation and although i've only asked for help for the 20% of the scripts i've made, sometimes like in this case, my scripting logic does not applyes ! foamyesque Your explanation is detailed enough to make me understand that my scripting logic is all wrong. I'll try again... ReDragon I'll try first doing it by myself now that i know what the problems are (i don't think i'll succeed because i've never used before this scripts functions - it's the first time i'm doing something like this). Then i'll look at your script for help, after the frustration, disappointment and headache strikes me again... Thank you both very much !!! Link to comment Share on other sites More sharing options...
maxarturo Posted April 9, 2019 Author Share Posted April 9, 2019 (edited) So, i wasted three days and i end up failing miserably in trying to make this work !. Then i went on using ReDragon's script and found out that this too has problems, and throught all my attempts to rectify it... i failed again !!. By that time i've already reached my boiling point. This is over my current scripting capabilities.... So i went for a simpler solution, i made a simple script that does exactly what i want. 1) Casts 4 ThounderBolts at 4 xMarkers in a predefined time. 2) Casts the ThounderBolts every time the activator gets activated and stops when deactivated, then repeats the same sequence every time it gets triggered. (the Thunder casting activator is controlled by another activator which is controlled by another activator with a script that activates - deactivates things on a timer - period of 30sec). DONE Scriptname aXMDRandomLightningStrikeTrigSCRIPT01 extends ObjectReference {Casts 4 LightningBolt to xMarker targets OnActivate in a period between them of 7sec - stops casting LightningBolts OnDeactivate - then repeats each time the sequence again OnActivate} Spell Property LightningSpell Auto {Lightning spell that gets cast} ObjectReference property xMarker01 auto {Casting target 01} ObjectReference property xMarker02 auto {Casting target 02} ObjectReference property xMarker03 auto {Casting target 03} ObjectReference property xMarker04 auto {Casting target 04} objectReference property castPoint01 auto {Source where to cast the spell from} bool Property isTriggered = false auto hidden Event onActivate(ObjectReference akActionRef) if (isTriggered != TRUE) isTriggered = TRUE Utility.wait(5.0) LightningSpell.Cast(castPoint01, xMarker01) Utility.wait(7.0) LightningSpell.Cast(castPoint01, xMarker02) Utility.wait(7.0) LightningSpell.Cast(castPoint01, xMarker03) Utility.wait(7.0) LightningSpell.Cast(castPoint01, xMarker04) elseif (isTriggered != FALSE) isTriggered = FALSE Self.InterruptCast() EndIf ENDEVENT Event OnCellDetach() self.Delete() EndEvent .............................................................................................................. Now i'm facing an other issue with an other simple script. It's a increment COUNTER OnMagicEffectApplyDoOnce Script, is been added as a SECONDARY script. Is supposed to increment the COUNTER only when the activator gets hit with the correct school of magic. For some weird reason is not working correctly and i have the suspicion that is connected to the fact that the PRIMARY script of the Activators (custom made activators - custom made script) has the same scripting logic (but more complicated). The PRIMARY script has the function to react only uppon hit with the correct school of magic, and then do a bounch of stuffs, and then do them again every time it gets triggerd - hit. (the primary script works like a clock - perfectly). Symptoms of the malfunction : - It increments the COUNTER (and when the counter's set value is reached activates the Master Activator, but...) sometime in 2 hits (2 different activators been hit), others in 3 hits (3 different activators been hit) but never in 4 hits, which is the targeted value set in the counter (4). The script is attached to 4 activators. Each activator that the secondary script is attached is suppose to add 1 value to the COUNTER. The only thing that stays constant is that it never reacts uppon hit with the wrong school of magic. * The COUNTER hasn't been touched in any way and it's using a vanilla "defaultcounter". * I've made a second version of the same script that react only OnMagicApply without the requirement of getting triggered by the correct school of magic and everything works fine, so it has nothing to do with the counter. If anyone could shed some light to this.... Scriptname aXMDincrementOnMagicApplyDoOnce01 extends ObjectReference {Increment Link Ref COUNTER OnMagicApply with Correct School of Magic} bool property isDestruction auto bool property isAlteration auto bool property isRestoration auto bool property isIllusion auto bool property isConjuration auto Keyword property counterLinkedRefName Auto {The name of the LinkedRef to the Counter. Defaults to the unnamed linkedref.} bool property done auto EVENT OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect) ; debug.trace("hit by "+akCaster+" with "+akEffect) if (akEffect.getAssociatedSkill() == "Destruction") && isDestruction solveMe(akCaster) elseif (akEffect.getAssociatedSkill() == "Alteration") && isAlteration solveMe(akCaster) elseif (akEffect.getAssociatedSkill() == "Restoration") && isRestoration solveMe(akCaster) elseif (akEffect.getAssociatedSkill() == "Illusion") && isIllusion solveMe(akCaster) elseif (akEffect.getAssociatedSkill() == "Conjuration") && isConjuration solveMe(akCaster) EndIf ENDEVENT FUNCTION SolveMe(objectReference whoSolved) (Self.GetLinkedRef(counterLinkedRefName) As defaultCounter).Increment() done = TRUE EndFunction Many thanks in advance !!! PS : I'm so sorry ReDragon that i couldn't make your script work.... Edited April 9, 2019 by maxarturo Link to comment Share on other sites More sharing options...
Recommended Posts