Cameron1990 Posted September 4, 2021 Share Posted September 4, 2021 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 ReferenceAliasSpell Property SpellCasted AutoSoulGem Property GemToTake AutoActor Property PlayerRef AutoInt Property QtyToTake AutoEvent OnSpellCast(Form akSpell)If akSpell == SpellCastedPlayerRef.RemoveItem(GemToTake,QtyToTake)EndIfEndEventThe 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 More sharing options...
dylbill Posted September 4, 2021 Share Posted September 4, 2021 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 More sharing options...
Cameron1990 Posted September 4, 2021 Author Share Posted September 4, 2021 I am going to try that later tonight, thank you very much! Link to comment Share on other sites More sharing options...
dylbill Posted September 5, 2021 Share Posted September 5, 2021 No problem. Link to comment Share on other sites More sharing options...
Cameron1990 Posted September 5, 2021 Author Share Posted September 5, 2021 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 More sharing options...
testiger2 Posted September 5, 2021 Share Posted September 5, 2021 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 pointlet the EP mod the magic cost of the spellset 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 More sharing options...
Cameron1990 Posted September 5, 2021 Author Share Posted September 5, 2021 (edited) 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 September 5, 2021 by Cameron1990 Link to comment Share on other sites More sharing options...
Cameron1990 Posted September 6, 2021 Author Share Posted September 6, 2021 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 More sharing options...
dylbill Posted September 6, 2021 Share Posted September 6, 2021 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 More sharing options...
ReDragon2013 Posted September 7, 2021 Share Posted September 7, 2021 (edited) 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 September 7, 2021 by ReDragon2013 Link to comment Share on other sites More sharing options...
Recommended Posts