Jump to content

[LE] I have two issues with a simple Script....


Recommended Posts

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 by maxarturo
Link to comment
Share on other sites

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 by foamyesque
Link to comment
Share on other sites

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 by ReDragon2013
Link to comment
Share on other sites

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

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 by maxarturo
Link to comment
Share on other sites

  • Recently Browsing   0 members

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