GSGlobe Posted July 30, 2017 Share Posted July 30, 2017 Hey guys, hopefully you'll be able to help me out here, been struggling for quite some time with limited time and experience been trying to fix the script by myself for personal use by randomly changing parts of it to no avail. :D The script come from a mod with open permissions but this will only be for personal use anyway. Spell in this mod works like this; *You cast the spell and it allows you to "store a spell" and set conditions to when the spell will be cast, on yourself or a target.Example: Cast spell, set condition to self & When health is below 50%, spell ask you to cast the spell you want to store, for this example we'll use Fast Healing. So when you're in combat and your health drops below 50% HP, you'll cast Fast Healing. The spell and script works perfectly, but after the spell is cast the spell is dispelled and it sets a cooldown for X amount of time until you're allow to cast the spell again and yet again set conditions and what spell to store. What I want to achieve is this; You cast the spell, set conditions, store a spell you want and then it stays on forever until the duration of the effect runs out, instead of dispelling alltogether when stored spell is cast. Tried to delete all the dispelling were it was appropriate and that stopped the magic effect from dissapearing after the the stored spell was casted, however it never casted the stored spell again even if you entered combat anew. Quick question; How would I go about to change the script below to 1. Store the spell forever or until the duration ran off and add for example 60 seconds until the stored spell was cast again? Thanks for all the help in advance and please explain indepth if you could as I'm a novice. Script here; Scriptname LFscrForesight extends activemagiceffect {Given choice of conditions then spell is cast.}; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; ------------------------------------------- Auto linked properties ---------------------------------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Actor Property PlayerRef Auto ; References the player.Formlist Property LFflPowers Auto ; The list of spells and powers not allowed to be stored.Formlist Property LFflPreparationSafe Auto ; The list of spells that are safe for casting with Preparation.Spell Property LFspForesight Auto ; Reference this spell + its effects.Spell Property LFspPreparation Auto ; Reference LF - Preparation Spell.Spell Property LFspContingency Auto ; Reference LF - Contingency Spell.Spell Property LFspPrecognition Auto ; Reference LF - Precognition Spell.Spell Property LFspSpellCoolDownII Auto ; Reference the Cool down spell.Spell Property LFspInCombatStarted Auto ; Reference the combat start spell.MagicEffect Property LFmeSpellCoolDown Auto ; Reference the Cool down Magic Effect.MagicEffect Property LFmeInCombatStarted Auto ; Reference the combat start spell, saves doing OnUpdate() all the time.Keyword Property LFkwInCombatDetect Auto ; Reference the keyword for special in combat spell effect.Message Property LFmsgForesightOpt Auto ; Message to ask player what condition to cast the stored spell.Message Property LFmsgReadyForSpell Auto ; Message to ask player to now cast spell.Message Property LFmsgSpellStored Auto ; Message to tell player the spell has been stored.Message Property LFmsgNotInCombat Auto ; Message to tell player the spell wont store spells while in combat.Message Property LFmsgForesightTO Auto ; Message to tell player the spell timed out.Message Property LFmsgNoPowers Auto ; Message to tell player powers and shouts and dual cast spells are not allowed.Message Property LFmsgMightNotCast Auto ; Message to tell player the spell might not cast properly.Message Property LFmsgStillInCoolDown Auto ; Message to tell player the cool down period is still in effect.Message Property LFmsgNoIngredientsOrPotions Auto ; Message to tell player they are not allowed to store ingredient or potion effects.LFscrQuestGlobalVar Property GlobalVars Auto ; Reference the Quest script with global variables, saves a lot of repeated code.Float Property flMaxTimeAllowed Auto ; Reference the time limit for the effects.; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; ------------------------------------------- Script Specific Variables ------------------------------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Spell spToCast ; Variable to store the spell to cast.Message msgResult ; Reference to hold the message that should be shown.Int inSpellsStored = 0 ; Variable to check the number of spells stored.Int intButton = 0 ; Variable for the button press in the option menu.Int intIngredientsEaten = 0 ; Number of Ingredients player has eaten to test against OnSpellCast().Int intPotionsTaken = 0 ; Number of Potions player has taken to test against OnSpellCast().Int intPoisonsUsed = 0 ; Number of Poisons player has used to test against OnSpellCast().Bool boWaitingSpell = FALSE ; True if waiting for a spell to be stored.Bool boSpellAllowed = FALSE ; True if the spell is allowed to be cast.Bool boCombatStart = FALSE ; True if option 1 was taken in the message box.Bool boOnHit = FALSE ; True if option 2 was taken in the message box.Bool boHealthWatch = FALSE ; True if option 3 was taken in the message box.Bool boMagickaWatch = FALSE ; True if option 4 was taken in the message box.Bool boStaminaWatch = FALSE ; True if option 5 was taken in the message box.Bool boASpell = FALSE ; True if last effect was likely a spell.Bool boSelfSafeList = FALSE ; True if spell is in a list of 'Self' safe spells.Float flGetCurrentTime = 0.0 ; Float to hold game hours passed converted to mins.Float flGetNewTime = 0.0 ; Float to help remove the effect incase it lasts too long.; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; ------------------------------------- Spell has been cast start configuring ------------------------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////EVENT OnEffectStart(Actor akTarget, Actor akCaster) GotoState("Busy") PlayerRef.DispelSpell(LFspPreparation) ; Make sure no other storage spells are still active. PlayerRef.DispelSpell(LFspContingency) ; This is just a double check as the magic effect themselves PlayerRef.DispelSpell(LFspPrecognition) ; Have a keyword which will dispel simalar spells. flGetCurrentTime = Game.GetRealHoursPassed() * 60 ; Get the players current real hours played in minutes. IF PlayerRef.HasMagicEffect(LFmeSpellCoolDown) ; If the cool down magic effect is on the player... LFmsgStillInCoolDown.Show() ; Show the player the cool down message. PlayerRef.DispelSpell(LFspForesight) ; Dispel this spell. RETURN ; Don't run any further in this event. ENDIF IF !BoWaitingSpell && inSpellsStored <= 0 ; Set us up for waiting for a spell. BoWaitingSpell = TRUE ELSE LFmsgForesightTO.Show() PlayerRef.DispelSpell(LFspForesight) RETURN ENDIF Utility.Wait(0.5) ; Just a tiny pause before showing the options. IF !PlayerRef.IsInCombat() intButton = LFmsgForesightOpt.Show() ; Show the Foresight options menu. ELSE PlayerRef.DispelSpell(LFspForesight) ; Remove the Foresight effect from the player. LFmsgNotInCombat.Show() ; Tell the player you cant use this spell in combat. RETURN ENDIF IF intButton != 0 ; If the player choose a button other then 0 or "X" FunctionGetForesightOption() ; Get the bool variables back for the type of condition to cast. ELSE PlayerRef.DispelSpell(LFspForesight) ; If the player chose option 0 cancel the spell. LFmsgForesightTO.Show() ; Show the player a message that the spell has been successfully cancelled. RETURN ENDIF IF intButton != 0 && !PlayerRef.IsInCombat() ; If player is not in combat... LFmsgReadyForSpell.Show() ; Ask player to now cast spell. intIngredientsEaten = Game.QueryStat("Ingredients Eaten") ; Store into a variable the current Ingredients, intPotionsTaken = Game.QueryStat("Potions Used") ; Potions and intPoisonsUsed = Game.QueryStat("Poisons Used") ; Posions the player has used. GoToState("WaitOnCast") ; Using a STATE so it wont run into the same event automaticaly. RETURN ELSE LFmsgForesightTO.Show() PlayerRef.DispelSpell(LFspForesight) RETURN ENDIFENDEVENT; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; ------------------------------ This state is only active when waiting for a spell to store ---------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////STATE WaitOnCast ; Only refer to this event once so it wont check all this every cast. EVENT OnSpellCast(Form akSpell) ; This can include spells, ingrediant eaten, potion drunk or scroll used. GotoState("Busy") ; Move away from this EVENT so any future casts wont interrupt flow. IF Game.QueryStat("Ingredients Eaten") == intIngredientsEaten && \ Game.QueryStat("Potions Used") == intPotionsTaken && \ Game.QueryStat("Poisons Used") == intPoisonsUsed boASpell = TRUE ; Ok pretty sure the lastest 'Cast' was a spell. ELSE LFmsgNoIngredientsOrPotions.Show() ; If not dispel and give the player a message. PlayerRef.DispelSpell(LFspForesight) RETURN ENDIF IF boWaitingSpell && !PlayerRef.IsInCombat() && inSpellsStored <= 0 && boASpell spToCast = akSpell As Spell ; Store the cast spell in this Variable. boWaitingSpell = FALSE ; Double check to make sure we don't catch any more spells. boSpellAllowed = GlobalVars.FunctionCheckNotAllowed(spToCast, FALSE) IF !boSpellAllowed ; Call function to make sure its a spell player is allowed to cast. LFmsgNoPowers.Show() ; Otherwise show a message and dispel. PlayerRef.DispelSpell(LFspForesight) RETURN ENDIF ELSEIF boWaitingSpell && PlayerRef.IsInCombat() ; If we are still waiting for a spell but the player is in combat... LFmsgNotInCombat.Show() ; Tell player the spell wont store spells while in combat. PlayerRef.DispelSpell(LFspForesight) ; Could not store spell so cancel effect. RETURN ENDIF IF !boWaitingSpell && boSpellAllowed && !PlayerRef.IsInCombat() && inSpellsStored <= 0 msgResult = LFmsgMightNotCast as Message ; By default the message to send to the player is it is "unstable". spToCast = GlobalVars.FunctionCheckSummon(spToCast) ; Call function to see if the spell is a summon spell. boSelfSafeList = GlobalVars.FunctionCheckPreparationSafe(spToCast, FALSE) IF boSelfSafeList ; Call function to see if spell is on the targetted "safe" list. msgResult = LFmsgSpellStored ; Set the message to show a safe spell was stored. ELSE msgResult = LFmsgMightNotCast ; Show message that spell may not cast properly. ENDIF inSpellsStored += 1 ; This may be used in future to store multiple spells for 1 contingency. msgResult.Show() ELSE ; As usual if something goes wrong just dispel. LFmsgForesightTO.Show() PlayerRef.DispelSpell(LFspForesight) RETURN ENDIF IF !boOnHit && boSpellAllowed ; Everything BUT On hit needs a constant update. GotoState("WaitingOnCombat") ; Going to special state for waiting on combat. ELSEIF boOnHit && boSpellAllowed GoToState("WaitOnHit") ; These results are better because no constant updating. ENDIF ; Shame there is no OnCombatStart Event for Player normally! ENDEVENTENDSTATE; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; ----------------------------- This state is only active when waiting to be hit to cast spell -------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////STATE WaitOnHit EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) GotoState("Busy") ; Make sure we don't catch any more OnHit() flGetNewTime = Game.GetRealHoursPassed() * 60 ; Get the players new real hours played in minutes. IF flMaxTimeAllowed <= flGetNewTime - flGetCurrentTime ; Oh oh timer has run out but spell still active so dispel. LFmsgForesightTO.Show() ; Tell player the spell timed out. PlayerRef.DispelSpell(LFspForesight) PlayerRef.DispelSpell(LFspInCombatStarted) ; Dispel the combat detection spell. RETURN ENDIF IF boOnHit && PlayerRef.IsInCombat() && akAggressor != PlayerRef spToCast.Cast(PlayerRef, PlayerRef) ; Cast the stored spell at the player from the player. boOnHit = FALSE ; Bool to stop running OnHit() again, another double check. PlayerRef.DoCombatSpellApply(LFspSpellCoolDownII, PlayerRef); Cast the cool down spell on the player, 15 mins? PlayerRef.DispelSpell(LFspForesight) PlayerRef.DispelSpell(LFspInCombatStarted) ELSE Utility.Wait(0.5) GotoState("WaitOnHit") ; Repeat process incase it was a trap or other non-enemy activator. ENDIF ENDEVENTENDSTATE; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; -------------------------------------------------- Waiting On Combat State -------------------------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////STATE WaitingOnCombat ; Wait for the Magic effect that detects when the player enters combat. EVENT OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect) GotoState("Busy") ; No threading for you. flGetNewTime = Game.GetRealHoursPassed() * 60 ; Get the players new real hours played in minutes. IF flMaxTimeAllowed <= flGetNewTime - flGetCurrentTime ; Oh oh timer has run out but spell still active so dispel. LFmsgForesightTO.Show() ; Tell player the spell timed out. PlayerRef.DispelSpell(LFspForesight) ; Dispel the Preparation spell now its served its purpose. PlayerRef.DispelSpell(LFspInCombatStarted) ; Dispel the combat detection spell. RETURN ENDIF IF akEffect == LFmeInCombatStarted ; If my super special magic effect applied... WHILE PlayerRef.HasMagicEffectWithKeyword(LFkwInCombatDetect) IF boCombatStart spToCast.Cast(PlayerRef, PlayerRef) ; If combat has started cast the spell. PlayerRef.DoCombatSpellApply(LFspSpellCoolDownII, PlayerRef); Cast the cool down spell on the player. PlayerRef.DispelSpell(LFspForesight) PlayerRef.DispelSpell(LFspInCombatStarted) RETURN ELSEIF boHealthWatch && PlayerRef.GetActorValuePercentage("Health") <= 0.5 spToCast.Cast(PlayerRef, PlayerRef) ; If health is less then 50% cast the spell. PlayerRef.DoCombatSpellApply(LFspSpellCoolDownII, PlayerRef); Have to use a Float result for percentages i.e (0.24) = 24% PlayerRef.DispelSpell(LFspForesight) PlayerRef.DispelSpell(LFspInCombatStarted) RETURN ELSEIF boMagickaWatch && PlayerRef.GetActorValuePercentage("Magicka") <= 0.5 spToCast.Cast(PlayerRef, PlayerRef) ; If Magicka is less then 50% cast the spell. PlayerRef.DoCombatSpellApply(LFspSpellCoolDownII, PlayerRef) PlayerRef.DispelSpell(LFspForesight) PlayerRef.DispelSpell(LFspInCombatStarted) RETURN ELSEIF boStaminaWatch && PlayerRef.GetActorValuePercentage("Stamina") <= 0.5 spToCast.Cast(PlayerRef, PlayerRef) ; If Stamina is less then 50% cast the spell. PlayerRef.DoCombatSpellApply(LFspSpellCoolDownII, PlayerRef) PlayerRef.DispelSpell(LFspForesight) PlayerRef.DispelSpell(LFspInCombatStarted) RETURN ENDIF ENDWHILE Utility.Wait(0.5) ; If we leave combat before any conditions are met go back to waiting. GotoState("WaitingOnCombat") ELSE Utility.Wait(0.5) GotoState("WaitingOnCombat") ENDIF ENDEVENTENDSTATE; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; ---------------------------------------- The spell has finished time to clean up -------------------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////EVENT OnEffectFinish(Actor akTarget, Actor akCaster) flGetNewTime = Game.GetRealHoursPassed() * 60 IF flMaxTimeAllowed <= flGetNewTime - flGetCurrentTime ; Oh oh timer has run out but spell still active so dispel. ; If the timer has gone over the limit... LFmsgForesightTO.Show() ; Tell player the spell timed out. PlayerRef.DispelSpell(LFspForesight) ; Dispel the Foresight spell now its served its purpose. PlayerRef.DispelSpell(LFspInCombatStarted) ; Dispel the combat detection spell. ENDIF ENDEVENT; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; ----------------------------------------- Function for getting the activation options --------------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////FUNCTION FunctionGetForesightOption() IF intButton == 1 ; This option is for as soon as combat starts. boCombatStart = TRUE ELSEIF intButton == 2 ; This option is for during combat + "OnHit" boOnHit = TRUE ELSEIF intButton == 3 ; This option is for during combat + Health less then 50%. boHealthWatch = TRUE ELSEIF intButton == 4 ; This option is for during combat + Magicka less then 50%. boMagickaWatch = TRUE ELSEIF intButton == 5 ; This option is for during combat + Stamina less then 50%. boStaminaWatch = TRUE ELSE intButton = 0 ; An escape clause for the player. ENDIFENDFUNCTION ; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; -------------------------------------------------------- BUSY State --------------------------------------------------------------------; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////STATE Busy ; Just a simple state to goto when the script is busy. ENDSTATE Best regards,-gs Link to comment Share on other sites More sharing options...
serio420 Posted July 31, 2017 Share Posted July 31, 2017 Tried to delete all the dispelling were it was appropriate and that stopped the magic effect from dissapearing after the the stored spell was casted, however it never casted the stored spell again even if you entered combat anew. The script looks like this: ELSEIF boHealthWatch && PlayerRef.GetActorValuePercentage("Health") <= 0.5spToCast.Cast(PlayerRef, PlayerRef) ; If health is less then 50% cast the spell.PlayerRef.DoCombatSpellApply(LFspSpellCoolDownII, PlayerRef); Have to use a Float result for percentages i.e (0.24) = 24%PlayerRef.DispelSpell(LFspForesight)PlayerRef.DispelSpell(LFspInCombatStarted)RETURN You would want it to look like this, theoretically, for each of the casting triggers for "WaitingOnHit": ELSEIF boHealthWatch && PlayerRef.GetActorValuePercentage("Health") <= 0.5spToCast.Cast(PlayerRef, PlayerRef) ; If health is less then 50% cast the spell.GotoState("WaitingOnCombat") ; Or "WaitingOnHit" if it set to OnHit() PlayerRef.DoCombatSpellApply(LFspSpellCoolDownII, PlayerRef); Have to use a Float result for percentages i.e (0.24) = 24%PlayerRef.DispelSpell(LFspForesight)PlayerRef.DispelSpell(LFspInCombatStarted)RETURN That would basically ensure that the spell is only cast once during combat. Link to comment Share on other sites More sharing options...
Recommended Posts