Jump to content

[LE] Script to remove item on spell cast


Cameron1990

Recommended Posts

Hello everyone! I'm trying to make a mod that adds spells that require soul gems to cast them. Ive gone through all the walkthorughs and tutorials and have managed to get this script:

Scriptname SomeScript Extends ReferenceAlias

Spell Property SpellCasted Auto
SoulGem Property GemToTake Auto
Actor Property PlayerRef Auto
Int Property QtyToTake Auto

Event OnSpellCast(Form akSpell)
If akSpell == SpellCasted
PlayerRef.RemoveItem(GemToTake,QtyToTake)
EndIf
EndEvent

The only problem is that the spells will still cast even when I dont have the required items.
If anyone can help I would greatly appreciate it. Thank you for your time <3

Link to comment
Share on other sites

Instead, you can put a condition on your spells magic effect. GetItemCount GemToTake >= 1. You can change 1 to more, if you want the spell to take more gems. Then, you can put a script on your spell's magic effect, instead of reference alias:

 

Scriptname MyMagicEffectScript extends ActiveMagicEffect 

SoulGem Property GemToTake Auto
Int Property QtyToTake Auto

Event OnEffectStart(Actor akTarget, Actor akCaster) 
    akCaster.RemoveItem(GemToTake, QtyToTake)
EndEvent
Link to comment
Share on other sites

Ok so this is what I got so far:

 

Scriptname SageSoulFireScript extends ActiveMagicEffect
SoulGem Property SoulGemCommonFilled Auto
Int Property QtyToTake = 1 Auto
Event OnEffectStart(Actor akTarget, Actor akCaster)
akCaster.RemoveItem(SoulGemCommonFilled, 1, true)
EndEvent
It works in a sense, however the soul gem is only removed when a target is hit and you can still cast it without needing soul gems. I want it to remove the soul gem whenever you cast it even if it hits nothing and not be able to be cast without the gem. I tried the OnSpellCast event but it doesnt work for some reason.
Link to comment
Share on other sites

what you can try (don't know if its the best solution):

create a perk, add an ability to the perk and one perk entry point

let the EP mod the magic cost of the spell

set cost to something really high like 100000 or so and then put in the contition with GetItemCount == 0.

this will make you unable to cast the spell when you dont have the gem because the spell cost is too high.

also add a keyword to your spell and use the EPMagic_SpellHasKeyword condition so it only tracks you spell

 

for the ability add a script that extends activemagiceffect and then use OnSpellCast to track when the spell is fired.

you will propably want a good amount of optimizations here because this could get resource intensive otherwise.

maybe there is an easier solution for this or you can dump this if you are willing to live with removing the gem only when a target is hit

Link to comment
Share on other sites

Update: So after some research I found that you can't use the OnSpellCast condition with ActiveMagicEffects. I read the best thing to do is to create a dummy quest (Blank except Start Game Enabled checked, reference alias - specific reference - Ref: 'PlayerRef'). I compiled the following script attached to the quest in the scripts tab and recieve no errors or warnings.

 

Scriptname SageSoulFireScript extends ReferenceAlias  
SoulGem Property SoulGemCommonFilled Auto
Int Property QtyToTake = 1 Auto
Event OnSpellCast(Form SageSoulFire)
      If GetActorRef().GetItemCount(SoulGemCommonFilled)<1
               Debug.Notification("You are out of Soul Gems, spell failed.")
      ElseIf GetActorRef().GetItemCount(SoulGemCommonFilled)>0
                GetActorRef().RemoveItem(SoulGemCommonFilled, 1)
                GetActorRef().AddItem(SoulGemCommonFilled, 1)
                         Debug.Notification("Spell cast successful! Your Common Soul Gem returns to you.")
    
      EndIf
EndEvent  

Im very new to modding and even more so to scripting, only been at this a couple days, but I'm geting there! But the Spell or script just doesn't do anything. I checked with the console command to see if the quest was active (sqv QuestID) and it said it was. You can still cast the spell without Soul Gems, the debug.notifications do not show and Soul Gems are not consumed. What im trying to achieve is making a bunch of new spells that require soul gems to use. With the Destruction spells (which is where im starting) I want them to consume a soul gem on spell cast. If it hits a target it will return the soul gem to you. if you hit nothing you lose the soul gem. I want all my mods spells to not be able to be casted at all unless you have the required item for the spell is in the players inventory. I know this is alot, however I think this could be a very cool idea for a mod. I appreciate the help so far, I wouldn't have even gotten this far without dylbill. Thank you again for your time and any and all help is appreciated! -some noob

Edited by Cameron1990
Link to comment
Share on other sites

So, I've been doing a lot of research and have tried a few different scripts but nothing seems to work how I want it to. The main thing I'm stuck on is making the spell unable to be cast if you dont have the required items. Hoping to get this figured out in the next couple days so I can go through the long process of creating a bunch of spells that will use the script. Will be posting the mod to nexus once its finished. Have a good day everyone! <3

Link to comment
Share on other sites

Another solution I can think of is, instead of prevent the spell to be cast, prevent it from being equipped. Still use a reference alias pointing to the player, and to check for multiple spells you can use Arrays. Make sure when you fill the array properties in the CK, the index's line up. The script would look something like this:

 

Actor Property PlayerRef Auto
Spell[] Property akSpells Auto 
MiscObject[] Property akGems Auto 
Int[] Property akSpellGemAmounts Auto 

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference) 
    If akBaseObject as Spell ;player is equipping a spell
    
        Int Index = akSpells.Find(akBaseObject as spell) 
        If Index > -1 ;player is equipping a spell in the akSpells array list. 
            If PlayerRef.GetItemCount(akGems[Index]) < akSpellGemAmounts[Index] ;player doesn't have enough gems 
                If PlayerRef.GetEquippedSpell(0) == akSpells[Index] ;player has spell equipped in left hand.
                    PlayerRef.UnEquipSpell(akSpells[Index], 0) ;unequip the spell in the left hand
                Else 
                    PlayerRef.UnEquipSpell(akSpells[Index], 1) ;unequip the spell in the right hand
                Endif 
                Debug.Notification("You don't have enough soul gems to use this spell.")
            Endif 
        Endif
    Endif
EndEvent
Link to comment
Share on other sites

If you like try this approach:

- create a new quest (should be already done)

- create a player alias inside and attach a script to them

- duplicate the (destruction) spells you are interested for

- tweak the magiceffect with a condition to check for soulgems ready and add a script to the effect

- create two formlists, one for vanilla spells and one for your duplicates (use the same order for both lists)

- create a third formlist for soulgems or use an already exsting vanilla list

- fill the script properties

 

came19MGEFSoulgemScript

 

Scriptname came19MGEFSoulgemScript ActiveMagicEffect
; https://forums.nexusmods.com/index.php?/topic/10454128-script-to-remove-item-on-spell-cast/
; this should be attched to magic effect in new created spells (the duplicates from vanilla)

  ReferenceAlias PROPERTY PlayerAlias auto        ; have to be filled


; -- EVENT

EVENT OnEffectStart(Actor akTarget, Actor akCaster)
    came19PlayerAliasSoulgemScript ps = PlayerAlias as came19PlayerAliasSoulgemScript

    IF ( ps )
        ps.myTarget = akTarget
    ENDIF

    Debug.Trace(" OnEffectStart() - target = " +akTarget+ ", caster = " +akCaster)        ; for debugging only
ENDEVENT

 

 

 

came19PlayerAliasSoulgemScript

 

Scriptname came19PlayerAliasSoulgemScript extends ReferenceAlias
; https://forums.nexusmods.com/index.php?/topic/10454128-script-to-remove-item-on-spell-cast/
; this is a player alias script

; both lists have to be new created with CK
; Keep in mind: the order of lists have to be the same for exchange
; ------------------------------------------
  FormList PROPERTY vanillaSpells auto        ; all vanilla spells you want to remove
  FormList PROPERTY mySpells      auto        ; the duplicate of spells from above


; list of available items that should be found and removed in players inventory
; ------------------------------------------
  FormList PROPERTY SoulGemList auto          ; filled with baseobject of vanilla soulgems


; will be filled by Effect script of your new Spell
; ------------------------------------------
  Actor PROPERTY myTarget auto Hidden         ; place holder


; -- EVENTs -- 3

EVENT OnInit()
    Debug.Trace(" OnInit() - has been reached.. " +self)
ENDEVENT


EVENT OnPlayerLoadGame()
    Debug.Trace(" OnPlayerLoadGame() - has been reached.. " +self)
ENDEVENT


EVENT OnSpellCast(Form akSpell)
    IF (akSpell as Spell)                    ; check for spells here, ignore scrolls and potions
        myF_Action(akSpell)
    ENDIF
ENDEVENT


; -- FUNCTIONs -- 3

;--------------------------------
FUNCTION myF_Action(Form akSpell)
;--------------------------------
    IF mySpells.HasForm(akSpell)
        myF_Soulgem()

    ELSEIF (vanillaSpells.Find(akSpell) > -1)
        myF_Change(akSpell)
    ENDIF
ENDFUNCTION


;--------------------------------
FUNCTION myF_Change(Form akSpell)  ; helper
;--------------------------------
    actor aRef = self.GetActorReference()        ; get it once

; -1-
    spell spL = aRef.GetEquippedSpell(0)    ; left hand
    IF (spL == akSpell as Spell)
        aRef.UnEquipSpell(sp, 0)
    ENDIF
    spell spR = aRef.GetEquippedSpell(1)    ; right hand
    IF (spR == akSpell as Spell)
        aRef.UnEquipSpell(sp, 1)
    ENDIF
;-2-
    aRef.RemoveSpell(akSpell)                    ; remove vanilla spell
    spell sp = mySpells.GetAt(i) as Spell
    aRef.AddSpell(sp)                            ; and change with new created spell (a duplicate)

;-3-
    IF (spL == akSpell as Spell)
        aRef.EquipSpell(sp, 0)              ; new spell to left
    ENDIF
    IF (spR == akSpell as Spell)
        aRef.EquipSpell(sp, 1)              ; new spell to right
    ENDIF
ENDFUNCTION


;--------------------------
Form FUNCTION myF_Soulgem()  ; helper
;--------------------------
    actor aRef = self.GetActorReference()        ; once again here

IF (aRef.GetItemCount(SoulGemList) < 1)
    Debug.Notification("You are lack of soulgems..")
    RETURN    ; - STOP -
ENDIF
;---------------------
    int iMax = SoulGemList.GetSize()

int i = 0
    WHILE (i < iMax)                             ; BottomUp -- from GetAt(0) .. to GetAt(iMax-1)
        form fm = SoulGemList.GetAt(i)
        IF (aRef.GetItemCount(fm) > 0)
            aRef.RemoveItem(fm, 1)
            i = iMax
        ENDIF
        i = i + 1
    ENDWHILE

    IF ( myTarget )            ; valid target
        myTarget = None                          ; remove actor persistent instantly
        IF (i == iMax)
            aRef.AddItem(fm, 1)
            Debug.Notification("Spell cast successful! A soulgem returns to you.")
        ENDIF
    ENDIF
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

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