Jump to content

Removing an ability


Recommended Posts

I'm having a little difficulty with removing an ability that is gievn to an NPC by the player casting a spell (the player will also cast this on themselves), so far I have:

 

 

Function dz_activate_changing(Bool var)

spell my_spell

spell my_ability

my_ability = dz_outfits_ability

my_spell = dz_grant_outfits_ability_spell

ShowMessage("my spell = "+my_spell,False)

If var == True

   ShowMessage("var is true, casting spell, teammate is "+teammate_ref_slot[index],False)

   my_spell.cast(PlayerRef,teammate_ref_slot[index])

ElseIf var == False

   ShowMessage("var is false, dispelling spell, teammate is "+teammate_ref_slot[index],False)

   teammate_ref_slot[index].RemoveSpell(my_spell)

   ;dz_outfits_ability.dispel().teammate_ref_slot[index]

EndIf

EndFunction

 

 

This successfully gives the ability to the targeted NPC or player - at least the ability now shows up in the players magic menu, not sure how to test the NPC.

But the spell that gives the ability seems to disappear immediately, which makes sense, as in the CK it has a duration of 0.

However if the spell is no longer on the NPC I don't see how I can remove it:)

I have tried direcly removing the ability - see commented line; but this didn't work, I used various permutations of the elements in this line, all the CK help page says is:

 

; Dispel the 'it burns!' magic effect from the target
ItBurnsActiveEffect.Dispel()

 

which is not very helpful since it doesn't say where I reference the actorref that has the magic effect!

 

Since the ability will be for an indefinite time I'm not sure changing the duration of the granting spell will help.

 

diziet

Link to comment
Share on other sites

Dispel works for magic effects that are applied to targets, this is different from abilities, which are applied to targets that are meant to be continuous and therefore immune to dispel.

 

Make sure the spell is designated as an ability.

Edited by Rasikko
Link to comment
Share on other sites

Dispel works for magic effects that are applied to targets, this is different from abilities, which are applied to targets that are meant to be continuous and therefore immune to dispel.

 

Make sure the spell is designated as an ability.

The ability effect is marked as an ability in CK if that is what you mean?

The spell that grants the ability is not.

 

So how does one remove an ability?

 

diziet

 

Link to comment
Share on other sites

Maybe something like this.

 

Normally an ability has been casted to themself, which means player casts a cloak(-effect) to protect himself.
You want to cast the ability with spell of type "fire and forget" to an npc. How to?

Note: Do not forget to fill the script properties within CK !!
You need three spells and every has an own magic effect with a script.

Create a magic effect with nice visual effects to display ingame and a script as follow:
Use this effect to make a spell of type "ability" with zero duration (ability for ever).

 

Scriptname xyzAbilityEffect extend ActiveMagicEffect
; https://forums.nexusmods.com/index.php?/topic/8952558-removing-an-ability/

  GlobalVariable PROPERTY myGlobal auto        ; [default= g.GetValue()==0.0], new globalVar to control dispel


; -- EVENT --

EVENT OnMagicEffectStart(Actor akTarget, Actor akCaster)
    WHILE (myGlobal.GetValue() > 0.0)
        Utility.Wait(1.0)                    ; wait for 1.0 second and check again
        myGlobal.Mod(-1.0)                    ; decrease the value of globalVar by one
    ENDWHILE
    self.Dispel()                            ; remove the ability now
ENDEVENT

 

 

(For NPCs) Make a spell of type "fire and forget" and use/create a very simple magic effect (for this spell).
Attach to the effect a script as follow:

 

Scriptname xyzNPCTriggerAbilityScript extend ActiveMagicEffect
; https://forums.nexusmods.com/index.php?/topic/8952558-removing-an-ability/

  GlobalVariable PROPERTY myGlobal auto        ; [default= g.GetValue()==0.0], create new globalVar to control dispel

  Spell       PROPERTY mySpell   auto        ; this is the second spell, which has the ability
  MagicEffect PROPERTY myEffect  auto        ; this is the effect within the second spell        (1.choice)
;;Keyword     PROPERTY myKeyword auto        ; this is a keyword which has the effect from above (2.choice)

  Float PROPERTY fTimer = 30.0 auto            ; set to 30.0 seconds as default duration


; -- EVENTs -- 2

EVENT OnMagicEffectStart(Actor akTarget, Actor akCaster)
    IF akTarget.HasMagicEffect(myEffect)
        RETURN    ; - STOP -
    ENDIF
;    ----------------------
;;    IF akTarget.HasMagicEffectWithKeyword(myKeyword)
;;        RETURN    ; - STOP -
;;    ENDIF
;    ----------------------
    myGlobal.SetValue(ftimer)                ; globalVar which controls the while loop in the other script

    mySpell.Cast(akCaster as ObjectReference, akTarget as ObjectReference)        ; player gives the npc the ability
    Debug.Notification("Ability attached to NPC")
ENDEVENT


EVENT OnMagicEffectFinish(Actor akTarget, Actor akCaster)
ENDEVENT

 

 

(For player) duplicate an existing vanilla ability spell and use a duplicate of your ability effect.
Attach a script to this ability as follow:

 

Scriptname xyzPlayerAbilityEffect extend ActiveMagicEffect
; https://forums.nexusmods.com/index.php?/topic/8952558-removing-an-ability/

  MagicEffect PROPERTY myEffect  auto        ; this is the effect within the second spell        (1.choice)
;;Keyword     PROPERTY myKeyword auto        ; this is a keyword which has the effect from above (2.choice)

  Float PROPERTY fTimer = 60.0 auto          ; set to 60.0 seconds as default duration´


; -- EVENT --

EVENT OnMagicEffectStart(Actor akTarget, Actor akCaster)
    IF akTarget.HasMagicEffect(myEffect)
        self.Dispel()
        RETURN    ; - STOP -
    ENDIF
;    ----------------------
;;    IF akTarget.HasMagicEffectWithKeyword(myKeyword)
;;        self.Dispel()
;;        RETURN    ; - STOP -
;;    ENDIF
;    ----------------------
    WHILE (fTimer > 0.0)
        Utility.Wait(1.0)                    ; wait for 1.0 second and check again
        fTimer = fTimer - 1.0                ; decrease the value of globalVar by one
    ENDWHILE

    self.Dispel()                            ; remove the ability for the player now
ENDEVENT

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

Create a magic effect with nice visual effects to display ingame and a script as follow:

I do not know how to do this, I've looked at the 'visual effects' part of the CK dialogue and almost all of the options have only 'NONE'. It would be a good way to test if my MCM menu is successfullly giving NPCs the ability though.

 

I'm disappointed that papyrus doesn't allow to remove an ability the way one removes a spell, given that an ability is created using exaclty the same dialogue in the CK that one uses to make a spell.

In my ignorance using global vars and timers worries me, since a continuous poll would affect performance surely?

 

diziet

Link to comment
Share on other sites

Hi ReDragon2013,

 

Thanks for your script examples, I haven't as yet used the global variable idea, but I have tried the bit where you got the abiity effect to dispel itself! I didn't know you could do that.

I had a hiccup because originally my code said:

 

 

------snip---------
Event OnEffectStart(Actor Target, Actor Caster)

If dz_mcm.activate_toggle[dz_mcm.index] == False

  debug.messagebox("dispel_loop for "+this_npc_name+", activate_toggle = "+dz_mcm.activate_toggle[dz_mcm.index])

  self.dispel()

  Return

EndIf

;debug.messagebox("target = "+target+" caster = "+caster)

;debug.messagebox("abspell.ActorRef = "+abspell.ActorRef)

;debug.messagebox("dz_mcm.index = "+dz_mcm.index)

;debug.messagebox("dz_mcm.slots[5] = "+dz_mcm.slots[5])

;this_npc = Target

this_npc = dz_mcm.teammate_ref_slot[dz_mcm.index]

this_npc_name = this_npc.GetDisplayName()

debug.messagebox(this_npc_name+" has received the ability")

Int i

i = 0

While i < dz_mcm.Pages.Length

  If dz_mcm.teammate_ref_slot[i] == this_npc

   slot_index = i

  EndIf

  i = i + 1

EndWhile

EndEvent
-------snip---------

 

 

 

 

as you can see I'm using my mcm menu variables. This didn't work, and then I realised that the effect only started once so duh! :smile:

 

But, since the ability script also has location change events in, I changed the script to:

 

 

--------snip---------
Event OnEffectStart(Actor Target, Actor Caster)



;debug.messagebox("target = "+target+" caster = "+caster)

;debug.messagebox("abspell.ActorRef = "+abspell.ActorRef)

;debug.messagebox("dz_mcm.index = "+dz_mcm.index)

;debug.messagebox("dz_mcm.slots[5] = "+dz_mcm.slots[5])

;this_npc = Target

this_npc = dz_mcm.teammate_ref_slot[dz_mcm.index]

this_npc_name = this_npc.GetDisplayName()

debug.messagebox(this_npc_name+" has received the ability")

Int i

i = 0

While i < dz_mcm.Pages.Length

  If dz_mcm.teammate_ref_slot[i] == this_npc

   slot_index = i

  EndIf

  i = i + 1

EndWhile

EndEvent


Event OnLocationChange(Location akOldLoc, Location akNewLoc)

debug.notification(this_npc_name+" has changed location")

If dz_mcm.activate_toggle[dz_mcm.index] == False

  debug.messagebox("dispel_loop for "+this_npc_name+", activate_toggle = "+dz_mcm.activate_toggle[dz_mcm.index])

  self.dispel()

  Return

EndIf
If this_npc.IsInCombat()

Return

EndIf
-----------snip---------

 

 

 

 

and this works for me. Since the ability is only something that takes effect on a location change, checking for the variable and dispelling the ability at the top of the event does the trick.

It would be neater to dispel straight away, but I think avoiding runnng a while loop the whole time the ability is active is worth that liitle concession.

 

So thanks, I think I'm back on my way with this.:)

 

 

diziet

Link to comment
Share on other sites

  • Recently Browsing   0 members

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