dizietemblesssma Posted July 26, 2020 Share Posted July 26, 2020 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 targetItBurnsActiveEffect.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 More sharing options...
Evangela Posted July 27, 2020 Share Posted July 27, 2020 (edited) 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 July 27, 2020 by Rasikko Link to comment Share on other sites More sharing options...
dizietemblesssma Posted July 27, 2020 Author Share Posted July 27, 2020 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 More sharing options...
ReDragon2013 Posted July 28, 2020 Share Posted July 28, 2020 (edited) 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 July 28, 2020 by ReDragon2013 Link to comment Share on other sites More sharing options...
dizietemblesssma Posted July 28, 2020 Author Share Posted July 28, 2020 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 More sharing options...
dizietemblesssma Posted July 28, 2020 Author Share Posted July 28, 2020 i think I know what I've done wrong vis a vis visual effects, I didn't have skyrim.esm loaded in the CK, just my little esp with the mcm quest and spells and ther effects. Link to comment Share on other sites More sharing options...
dizietemblesssma Posted August 5, 2020 Author Share Posted August 5, 2020 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 More sharing options...
Recommended Posts