Jump to content

[LE] Script malfunction, why ?


Recommended Posts

( I had posted this in one previous topic, but the topic had different subject, and i had no answer, so i made it as a stand alone topic with hope that someone can show me a solution. )


<..... :: .....>


I'm facing an issue with a simple script.

It's a increment COUNTER OnMagicEffectApplyDoOnce Script, is been added as a SECONDARY script to the activator.



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 only thing that stays constant is that it never reacts upon been hit with the wrong school of magic.


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 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
{Assign the school to react upon}

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 !!!


Edited by maxarturo
Link to comment
Share on other sites

Maybe yes, maybe not.. it is not clear what do you want to do here! It could be also possible you forgot to set the keyword property, or your link was wrong set inside the CK.

 

aXMDincrementOnMagicApplyDoOnce01

 

Scriptname aXMDincrementOnMagicApplyDoOnce01 extends ObjectReference  
{Increment Link Ref COUNTER OnMagicApply with Correct School of Magic}

; use next instead of defaultCounter
  GlobalVariable PROPERTY myGlobalCounter auto    ; your new created counter

; Assign the school to react upon
  Bool PROPERTY isDestruction auto
  Bool PROPERTY isAlteration  auto
  Bool PROPERTY isRestoration auto
  Bool PROPERTY isIllusion    auto
  Bool PROPERTY isConjuration auto

  Bool PROPERTY done auto


; -- EVENT --
 
EVENT OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)
;  debug.trace("hit by "+akCaster+" with "+akEffect)

IF (akCaster as Actor) && (akEffect)
ELSE
    RETURN    ; - STOP -    no actor, no test
ENDIF
;---------------------
    IF ( isDestruction )
        IF (akEffect.GetAssociatedSkill() == "Destruction")
        ELSE
            RETURN    ; - STOP -
        ENDIF
    ENDIF

    IF ( isAlteration )
        IF (akEffect.GetAssociatedSkill() == "Alteration")
        ELSE
            RETURN    ; - STOP -
        ENDIF
    ENDIF

    IF ( isRestoration )
        IF (akEffect.GetAssociatedSkill() == "Restoration")
        ELSE
            RETURN    ; - STOP -
        ENDIF
    ENDIF

    IF ( isIllusion )
        IF (akEffect.GetAssociatedSkill() == "Illusion")
        ELSE
            RETURN    ; - STOP -
        ENDIF
    ENDIF

    IF ( isConjuration )
        IF (akEffect.GetAssociatedSkill() == "Conjuration")
        ELSE
            RETURN    ; - STOP -
        ENDIF
    ENDIF

    done = TRUE                ; **  try out
    SolveMe()
ENDEVENT


; -- FUNCTION --

;-----------------
FUNCTION SolveMe()
;-----------------
    myGlobalCounter.Mod(1)        ; increase the counter by one, threadsafe

    IF (myGlobalCounter.GetValue() >= 5)
        ; solved by all magic effects
;;;        done = TRUE            ; ** try out
    ENDIF
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

I want the script to increment the COUNTER only when the correct school of magic is applied to all 4 Activators.


* I forgot to mention that, if i remove the PRIMARY script the SECONDARY script works fine. ( i tested it last night ).


* I created a custom keyword just for this, and checked multiple times that everything it Linked correctly. And if i remove this script and replace it with the simpler version of it, all Linked activators respond correctly.


* GlobalVariable won't work here because the "defaultcounter" is responsible for activating the Master Activator & also handles xMarker activators.


.................................................


This last puzzle is becoming a complete nightmare to make it work correctly and correctly put together.

Edited by maxarturo
Link to comment
Share on other sites

So after a lot of testing and experimentation, i concluded that :


If you add 2 script that share the same scripting logic - structure even if they have different functions, malfunction will occur at least in one of them, usually in the script that has been added localy (secondary script).

Link to comment
Share on other sites

TELEPORTATION ISSUE
PLEASE HELP !!!!!......
Is there a way to PAUSE the teleport ability of an NPC when an activator gets triggered (Triggered = TRUE) then added it back when triggered again (Triggered = FALSE).
I thought that if i disable the "teleport Points" (Teleport Markers) for that 30 seconds that i need him to not have the teleport ability he wouldn't be able to teleport, but the NPC keeps teleporting to the teleport points (Teleport Markers) even if the Markers are in a disable state.
The NPC is using the "Ab Teleportation" spell combine with the "default teleport ability" Script.
I tried with this 2 scripts but :
- With the first, once the spell is remove the NPC won't teleport again even if the spell is added again.
- With the second, it will stop the teleportation just for a few seconds, around 4 sec and not for the 30 sec that the activator is set to activate and deactivate. (it's on a timer - controled by another activator - the activator is supposed to do a disrupt teleportation FX to the NPC for 30 sec)


Scriptname aXMDremoveSpellSCRIPT01 extends ObjectReference  
{Script to remove spell from actor}
 
 
Spell Property Spell01 Auto
{Spell to remove - add}
 
Actor Property ActorREF Auto
{Actor to apply the remove spell}
 
bool Property isTriggered = false auto hidden
 
 
Event OnActivate(ObjectReference akActionRef)
               If (isTriggered != TRUE)
                  isTriggered = TRUE
                  ActorREF.RemoveSpell(Spell01)
         elseif (isTriggered != FALSE)
                   isTriggered = FALSE
                   ActorREF.AddSpell(Spell01)
         EndIf
ENDEVENT


Scriptname aXMDremoveSpellSCRIPT01 extends ObjectReference  
{Script to remove spell from actor}
 
 
Spell Property Spell01 Auto
{Spell to unequip - equip}
 
Actor Property ActorREF Auto
{Actor to apply the remove spell}
 
bool Property isTriggered = false auto hidden
 
 
Event OnActivate(ObjectReference akActionRef)
               If (isTriggered != TRUE)
                  isTriggered = TRUE
                  ActorREF.UnEquipSpell(Spell01, 1)
         elseif (isTriggered != FALSE)
                   isTriggered = FALSE
                   ActorREF.EquipSpell(Spell01, 1)
         EndIf
ENDEVENT

 

 

 

 

I built this whole cell and puzzle just to do this... and now is not working... OMFG... why does he keeps teleporting to DISABLE TELEPORT POINT MARKERS !!!!......
Edited by maxarturo
Link to comment
Share on other sites

At first a bit knowledge about conditions, all have the same effect but different runtime and codelines.

 

your code

If (isTriggered != TRUE)
    isTriggered = TRUE
elseif (isTriggered != FALSE)
    isTriggered = FALSE
EndIf

first evolution

If ( !isTriggered )
    isTriggered = TRUE
elseif ( isTriggered )
    isTriggered = FALSE
EndIf

second evolution

If ( isTriggered )
    isTriggered = False
else
    isTriggered = TRUE
EndIf

But I believe such construct is not needed for your purpose. States are the best method here.

aXMD_SpellSCRIPT

 

Scriptname aXMD_SpellSCRIPT extends ObjectReference  
{to handle teleport spell for specific actor}

; https://forums.nexusmods.com/index.php?/topic/7560366-script-malfunction-why/


  Spell PROPERTY mySpell  auto        ; spell to use for removing/adding
  Actor PROPERTY ActorREF auto        ; Actor to apply the spell


; -- EVENTs --

EVENT OnUnLoad()
    UnRegisterForUpdate()            ; just in case
ENDEVENT


;============================================
auto state Active                                              ; EDIT: 2019/04/14
;===========
EVENT OnActivate(ObjectReference akActionRef)
;IF (ActorRef) && (mySpell)
;ELSE
;    RETURN ; - STOP - missing property
;ENDIF
;;--------------------
    gotoState("Waiting")            ; ### STATE ###    and wait for thirty seconds
    RegisterForSingleUpdate(30.0)

IF ActorREF.RemoveSpell(mySpell)
    RETURN    ; - STOP -    actor had the the spell, now removed
ENDIF
;---------------------
    ActorREF.AddSpell(mySpell)
ENDEVENT
;=======
endState


;============================================
state Waiting
;============
;EVENT OnActivate(ObjectReference akActionRef)
;    Debug.Notification("Cannot activate for a while..")
;ENDEVENT

EVENT OnUpdate()
    gotoState("Active")                ; ### STATE ###    activation is possible again
ENDEVENT
;=======
endState

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

The script for the teleport ability that Orchendor uses doesn't care about enabled or disabled states. Regardless of whether they are enabled or not, objects have a position in the world, and therefore you can move to them. You can test this out for yourself in the console by disabling an NPC and then moving to them, for example.

 

Easiest way to solve the problem, I think, would be to copy the teleport ability and then, in the effects list for the spell, put in a condition check against a global variable you create. Then just set it appropriately when you want to turn the ability on or off.

 

Alternatively, if you want to reuse this for multiple NPCs and/or have them be able to be set independently, you can make the check against a faction, and modify that.

Link to comment
Share on other sites

The script for the teleport ability that Orchendor uses doesn't care about enabled or disabled states. Regardless of whether they are enabled or not, objects have a position in the world, and therefore you can move to them. You can test this out for yourself in the console by disabling an NPC and then moving to them, for example.

 

Easiest way to solve the problem, I think, would be to copy the teleport ability and then, in the effects list for the spell, put in a condition check against a global variable you create. Then just set it appropriately when you want to turn the ability on or off.

 

Alternatively, if you want to reuse this for multiple NPCs and/or have them be able to be set independently, you can make the check against a faction, and modify that.

I'll give it a try "copy the teleport ability", although i've never made or modified a spell before, i'm quite experienced with CK and i know the program well, i think i can make this work.
Thanks for the TIP !!....
Link to comment
Share on other sites

At first a bit knowledge about conditions, all have the same effect but different runtime and codelines.

 

your code

If (isTriggered != TRUE)
    isTriggered = TRUE
elseif (isTriggered != FALSE)
    isTriggered = FALSE
EndIf

first evolution

If ( !isTriggered )
    isTriggered = TRUE
elseif ( isTriggered )
    isTriggered = FALSE
EndIf

second evolution

If ( isTriggered )
    isTriggered = False
else
    isTriggered = TRUE
EndIf

But I believe such construct is not needed for your purpose. States are the best method here.

aXMD_SpellSCRIPT

 

Scriptname aXMD_SpellSCRIPT extends ObjectReference  
{to handle teleport spell for specific actor}

; https://forums.nexusmods.com/index.php?/topic/7560366-script-malfunction-why/


  Spell PROPERTY mySpell  auto        ; spell to use for removing/adding
  Actor PROPERTY ActorREF auto        ; Actor to apply the spell


; -- EVENTs --

EVENT OnUnLoad()
    UnRegisterForUpdate()            ; just in case
ENDEVENT


;============================================
state Active
;===========
EVENT OnActivate(ObjectReference akActionRef)
;IF (ActorRef) && (mySpell)
;ELSE
;    RETURN ; - STOP - missing property
;ENDIF
;;--------------------
    gotoState("Waiting")            ; ### STATE ###    and wait for thirty seconds
    RegisterForSingleUpdate(30.0)

IF ActorREF.RemoveSpell(mySpell)
    RETURN    ; - STOP -    actor had the the spell, now removed
ENDIF
;---------------------
    ActorREF.AddSpell(mySpell)
ENDEVENT
;=======
endState


;============================================
state Waiting
;============
;EVENT OnActivate(ObjectReference akActionRef)
;    Debug.Notification("Cannot activate for a while..")
;ENDEVENT

EVENT OnUpdate()
    gotoState("Active")                ; ### STATE ###    activation is possible again
ENDEVENT
;=======
endState

 

 

Thanks ReDragon for replying.

 

The "remove spell" from NPC has the negative side effect that the NPC will stop using the Teleport Spell after it's been remove permanently no matter if it's been added back afterwards.
Thank you very much & for the lesson.
* As i have mentioned in previous posts, i'm a self teach scripter, 90% of the knowledge i have is from studying - seeing Vanilla Scripts.
Yes i know, you have mentioned this to me before, that Vanilla Scripts are not the most well done - written, but i have no other source to study from.
Edited by maxarturo
Link to comment
Share on other sites

  • Recently Browsing   0 members

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