DevTheDev Posted April 9 Share Posted April 9 (edited) I've been working on a mod for a while now, trying to get back into understanding coding by working through Papyrus and modifying scripts. One of the issues that I have come across is within my OnSpellCast Event, as I am not too sure how I should go about detecting whether or not the caster is using a concentration spell. I'll drop the source down below: Scriptname MAS_PerkCastingFever_StacksCalc extends ActiveMagicEffect {How the perk "Casting Fever"'s stacks are calculated.} import Spell import PO3_SKSEFunctions ; Scripts that have been imported. SKSE and PO3 Extender required. GlobalVariable Property MAS_PerkCastingFever_Stacks Auto ; Actual stacks that determine the overall Magicka-reduction. Int iStackTime = 4 ; iStackTime is duration. ;------------------------------------------------------------------------------------------------ Event OnEffectStart (Actor akTarget, Actor akCaster) MAS_PerkCastingFever_Stacks.Value = 0 EndEvent ; When effect starts, stacks reset back down to zero. Event OnEffectFinish (Actor akTarget, Actor akCaster) MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndEvent ; When effect ends, stacks reset back down to zero. ;------------------------------------------------------------------------------------ Event OnSpellCast (Form akSpell) If (akSpell as Spell) Spell castedSpell = akSpell as Spell If (castedSpell.GetNthEffectMagicEffect(0).GetAssociatedSkill() == "Destruction") If (MAS_PerkCastingFever_Stacks.Value < 5) ; Does not increase stacks beyond 5. ;BOTCHED CODE If (IsCasting(akSpell) == true) While IsCasting(castedSpell) == true MAS_PerkCastingFever_Stacks.Value += 1 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) registerForSingleUpdate(iStackTime) EndWhile Else ;BOTCHED CODE MAS_PerkCastingFever_Stacks.Value += 1 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) registerForSingleUpdate(iStackTime) EndIf EndIf Else MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndIf EndIf EndEvent ; Whenever a casted Spell's first Magic Effect is from the Destruction school, the effect activates. It deactivates if it is from a different school. ; Next, if the Global Variable's value is lesser than 5, the stack is increased. The timer is also refreshed/triggered. ;-------------------------------------------------------------------------------------------------------- Event OnUpdate() MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndEvent ;------------------------------------------------------------------------------------------------------------- Besides the code inbetween ;BOTCHED CODE, everything else stacks as it should based off of every first initial cast. However, concentration spells only trigger the OnSpellCast Event once, which is normal but not wanted. How would I be able to achieve the while loop I am aiming for within an OnSpellCast, and if it cannot be achieved within the event, what would? Edited April 9 by DevTheDev Link to comment Share on other sites More sharing options...
dylbill Posted April 10 Share Posted April 10 My first thought would be to use animation events to detect when stopping casting. https://ck.uesp.net/wiki/Animation_Events 1 Link to comment Share on other sites More sharing options...
Sphered Posted April 11 Share Posted April 11 Answering the headline real quick since didnt see this mentioned Event OnSpellCast(Form akSpell) Int FirstEffectCastType = (akSpell as Spell).GetNthEffectMagicEffect(0).GetCastingType() ; Constant Effect 0 ; Fire And Forget 1 ; Concentration 2 So if the above Int = Two you know it is concentration so do whatever. Anything other than two do nada 1 Link to comment Share on other sites More sharing options...
DevTheDev Posted April 11 Author Share Posted April 11 (edited) 4 hours ago, Sphered said: Answering the headline real quick since didnt see this mentioned Event OnSpellCast(Form akSpell) Int FirstEffectCastType = (akSpell as Spell).GetNthEffectMagicEffect(0).GetCastingType() ; Constant Effect 0 ; Fire And Forget 1 ; Concentration 2 So if the above Int = Two you know it is concentration so do whatever. Anything other than two do nada Thank you so much, that's exactly what I needed to get this to work! I think I tried coding it in before, but didn't properly know how to format it. Right now I'll post the state the code is in right now, but it still has some hiccups with resetting the stack if the player is no longer casting the concentration spell. I'll probably make another post regarding that specific issue. Scriptname MAS_PerkCastingFever_StacksCalc extends ActiveMagicEffect {How the perk "Casting Fever"'s stacks are calculated.} import Spell import PO3_SKSEFunctions ; Scripts that have been imported. SKSE and PO3 Extender required. GlobalVariable Property MAS_PerkCastingFever_Stacks Auto ; Actual stacks that determine the overall Magicka-reduction. Int iStackTime = 4 ; iStackTime is duration. ;------------------------------------------------------------------------------------------------ Event OnEffectStart (Actor akTarget, Actor akCaster) MAS_PerkCastingFever_Stacks.Value = 0 EndEvent ; When effect starts, stacks reset back down to zero. Event OnEffectFinish (Actor akTarget, Actor akCaster) MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndEvent ; When effect ends, stacks reset back down to zero. ;------------------------------------------------------------------------------------ Event OnSpellCast (Form akSpell) If (akSpell as Spell) Spell castedSpell = akSpell as Spell If (castedSpell.GetNthEffectMagicEffect(0).GetAssociatedSkill() == "Destruction") If (MAS_PerkCastingFever_Stacks.Value < 5) ; Does not increase stacks beyond 5. If (castedSpell.GetNthEffectMagicEffect(0).GetCastingType() == 2) ; Stuck While loop While (castedSpell.GetNthEffectMagicEffect(0).GetCastingType() == 2) If (MAS_PerkCastingFever_Stacks.Value < 5) MAS_PerkCastingFever_Stacks.Value += 1 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) registerForSingleUpdate(iStackTime) ElseIf (MAS_PerkCastingFever_Stacks.Value == 5) registerForSingleUpdate(iStackTime) EndIf EndWhile ; Stuck While loop Else MAS_PerkCastingFever_Stacks.Value += 1 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) registerForSingleUpdate(iStackTime) EndIf ElseIf (MAS_PerkCastingFever_Stacks.Value == 5) registerForSingleUpdate(iStackTime) EndIf Else MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndIf EndIf EndEvent ; Whenever a casted Spell's first Magic Effect is from the Destruction school, the effect activates. It deactivates if it is from a different school. ; Next, if the Global Variable's value is lesser than 5, the stack is increases. The timer is also refreshed/triggered. ; Concentration spells work differently, stacking up to their max quickly. It's broken in it's current state though, causing the stack to permanetly stay at 5. ;-------------------------------------------------------------------------------------------------------- Event OnUpdate() MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndEvent ;------------------------------------------------------------------------------------------------------------- Before I make that post though... On 4/10/2024 at 1:57 AM, dylbill said: My first thought would be to use animation events to detect when stopping casting. https://ck.uesp.net/wiki/Animation_Events How would I go about implementing this within my OnSpellCast Event? When I was previously looking through other similar posts on the forums, almost all instances of this method being used were only using the OnAnimationEvent to detect concentration casting. I'm not too sure how to nest this event into the OnSpellCast Event, but if there are any references or ideas, I would love to know. EDIT: Just realized the while statement is a constantly true statement, somehow that didn't click in my head lmao Edited April 11 by DevTheDev Link to comment Share on other sites More sharing options...
dylbill Posted April 11 Share Posted April 11 Actually now that I think about it, using animation variable would be easier. You'd have to determine somehow which hand the spell is equipped in when cast, and also save the target actor onEffectStart. Then you can do for instance: while Target.GetAnimationVariableBool("IsCastingRight") https://ck.uesp.net/wiki/List_of_Animation_Variables Link to comment Share on other sites More sharing options...
DevTheDev Posted April 12 Author Share Posted April 12 (edited) So I actually was able to crack this after finally figuring out how to pull a variable from OnEffectStart (it was easy, I just didn't know squat lmao) I want to make sure that the spell works for NPCs once I find an apt subsitute for the GlobalVariable, but my final code ended up being this: Scriptname MAS_PerkCastingFever_StacksCalc extends ActiveMagicEffect {How the perk "Casting Fever"'s stacks are calculated.} import Spell import PO3_SKSEFunctions ; Scripts that have been imported. SKSE and PO3 Extender required. GlobalVariable Property MAS_PerkCastingFever_Stacks Auto ; Actual stacks that determine the overall Magicka-reduction. Int iStackTime = 4 ObjectReference spellCaster ; iStackTime is duration. spellCaster is used as a reference. ;------------------------------------------------------------------------------------------------ Event OnEffectStart (Actor akTarget, Actor akCaster) MAS_PerkCastingFever_Stacks.Value = 0 spellCaster = akCaster as ObjectReference EndEvent ; When effect starts, stacks reset back down to zero and grab the active actor as the spellCaster. Event OnEffectFinish (Actor akTarget, Actor akCaster) MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndEvent ; When effect ends, stacks reset back down to zero. ;------------------------------------------------------------------------------------ Event OnSpellCast (Form akSpell) If (akSpell as Spell) Spell castedSpell = akSpell as Spell If (castedSpell.GetNthEffectMagicEffect(0).GetAssociatedSkill() == "Destruction") If (MAS_PerkCastingFever_Stacks.Value < 5) ; Does not increase stacks beyond 5. If (castedSpell.GetNthEffectMagicEffect(0).GetCastingType() == 2) While (IsCasting(spellCaster, akSpell) == true) If (MAS_PerkCastingFever_Stacks.Value < 5) Stacker() ElseIf (MAS_PerkCastingFever_Stacks.Value == 5) registerForSingleUpdate(iStackTime) EndIf EndWhile Else Stacker() EndIf ElseIf (MAS_PerkCastingFever_Stacks.Value == 5) registerForSingleUpdate(iStackTime) EndIf Else MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndIf EndIf EndEvent ; Whenever a casted Spell's first Magic Effect is from the Destruction school, the effect activates. It deactivates if it is from a different school. ; Next, if the Global Variable's value is lesser than 5, the stacks increase. The timer is also refreshed/triggered on every cast if its stack is at 5. ; Concentration spells work differently, stacking up to their max quickly as long as the spell is active. ;-------------------------------------------------------------------------------------------------------- Event OnUpdate() MAS_PerkCastingFever_Stacks.Value = 0 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) EndEvent Function Stacker() MAS_PerkCastingFever_Stacks.Value += 1 debug.Notification("Casting Fever Stack: " + MAS_PerkCastingFever_Stacks.Value) registerForSingleUpdate(iStackTime) EndFunction ;------------------------------------------------------------------------------------------------------------- I used the IsCasting function from PO3's Extender to check if the spell was still active, getting the original Form akSpell found within OnSpellCast and the ObjectReference casted from OnEffectStart's Actor. Thank you though for all of your help, I'd say at this point my script's in a good state to finally add in a non-Global Variable way to distribute the bonuses, mainly so that other casters have their own incremental reductions in Magicka. EDIT: Changed the code with a function for better readability, mainly for other modders. Edited April 12 by DevTheDev Updated code for future reference if people are interested Link to comment Share on other sites More sharing options...
Recommended Posts