Xander9009 Posted May 12, 2013 Share Posted May 12, 2013 (edited) I'm attempting to make a mod which applies spells through potions. The actual goal is to have an active effect which will provide an armor bonus until the player has taken a certain amount of damage (which should be directly proportional to how much damage the spell has prevented), and then dispel itself. It's sort of a way to make it so you can take the potion any time you want and it won't run out until its fulfilled its usefulness. I've gotten everything working so far except one thing. After I drink the potion, it'll run its course. However, if I drink another potion, nothing happens. I've tried a few different methods of making it work, but nothing seems to make it cooperate. Any help would be greatly appreciated. If someone can help with making it more efficient, that would be awesome, too. So you understand how everything is working, here's the setup (it's not the simplest, but it's the only way I could make it work): Two spells: AE_AbsorbDamageSpell and AE_AbsorbDamageSpellDispel. The first is applied when the player drinks the potion. When the script's counter runs out, it dispels itself by casting the second spell which has the same keywords as the first and dispels those keywords. Three effects: AE_AbsorbDamage (this one runs the script but does nothing else), AE_Armor (the actual armor fortification), and AE_Dispel (obviously, this one does nothing except dispels the others it shares a keyword with). The first spell above calls the first effect (tat runs the script); the second spell calls the third effect. One potion: AE_AbsorbDamageShard calls the first two effects. Scriptname AE_AbsorbDamageScript extends activemagiceffect Spell Property AE_AbsorbDamageSpell Auto Float AbsorbDamageCount Float PlayerHealthCurrent Float PlayerHealthDif Float PlayerHealthStart MagicEffect Property AE_AbsorbDamage Auto Spell Property AE_AbsorbDamageDispelSpell Auto Float LastCheck Bool HasADS Function StartChain() If ( Game.GetPlayer().HasSpell(AE_AbsorbDamageSpell) == 0 ) RegisterForSingleUpdate(1.0) ; Give us a single update in one second Game.GetPlayer().AddSpell(AE_AbsorbDamageSpell) PlayerHealthStart = Game.GetPlayer().GetAV("Health") AbsorbDamageCount = 100 LastCheck = AbsorbDamageCount Debug.Notification("Player health is " + PlayerHealthStart) EndIf EndFunction Function RemoveAura() AE_AbsorbDamageDispelSpell.Cast(Game.GetPlayer()) Game.GetPlayer().RemoveSpell(AE_AbsorbDamageSpell) Debug.Notification("Aura removed") EndFunction Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect) StartChain() ;Debug.Notification("Chain started") EndEvent Event OnUpdate() Bool bKeepUpdating = True PlayerHealthCurrent = Game.GetPlayer().GetAV("Health") PlayerHealthDif = PlayerHealthStart - PlayerHealthCurrent If ( PlayerHealthDif > 0 ) AbsorbDamageCount -= PlayerHealthDif If ( LastCheck - AbsorbDamageCount >= 10 ) Check() EndIf EndIf If ( AbsorbDamageCount <= 0 ) RemoveAura() ;Debug.Notification("Triggered aura removal") EndIf PlayerHealthStart = Game.GetPlayer().GetAV("Health") If bKeepUpdating RegisterForSingleUpdate(1.0) If ( Game.GetPlayer().HasSpell(AE_AbsorbDamageSpell) == 1 ) HasADS = 1 Else HasADS = 0 EndIf Debug.Notification("ADC: " + AbsorbDamageCount + ", ADS: " + HasADS) EndIf EndEvent ; This is solely for monitoring the script until it's working properly, at which point it will be erased. Function Check() Debug.Notification("Current " + PlayerHealthCurrent + ", difference " + PlayerHealthDif + ", Count " + AbsorbDamageCount) LastCheck = AbsorbDamageCount EndFunction Like I said, everything seems to working well except that it only works once. When I drink a second potion after the first has expired, I'm given the effects (the fortify armor and the AE_AbsorbDamage script effect), but the script itself doesn't run again. I'm not sure if this should be here or a different forum. If it needs, let me know where to put it and I'll happily switch it over. Edited December 21, 2013 by Xander9009 Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 12, 2013 Share Posted May 12, 2013 Have you confirmed that the spell does indeed get removed from the player after the first use of the potion? Seems to me that that is what the script is depending upon, the status of the player having or not having a specific spell. Link to comment Share on other sites More sharing options...
Xander9009 Posted May 13, 2013 Author Share Posted May 13, 2013 Yes, the spell is removed. In fact, it even works multiple times like it's supposed to. By chance I realized something. It doesn't fire unless a different magic effect is applied to the player while they have the other effects in place and the script is already running. When I was testing it previously, I was being attacked by an animal and was constantly healing myself. So, thanks to the fact that I had a constant stream of new effects hitting me, I never realized it. So, as it stands, the player drinks the potion and the effects are applied immediately. The script is started. Then, when another effect hits the player, StartChain fires and everything starts working. Is there a different way to go about it to ensure it runs immediately? Will OnInit() work here? Hopefully, 'cause that's what I'm gonna try. (I got the original setup from someone else's suggestion to a completely different person. Apparently, it's not 100% applicable to my situation haha.) Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 13, 2013 Share Posted May 13, 2013 No idea if OnInit() will work for you. You can try it. If it doesn't perhaps you can put some of the stuff on a quest script and have the potion effect script start the quest. At least then the OnInit() would work. Link to comment Share on other sites More sharing options...
Xander9009 Posted May 13, 2013 Author Share Posted May 13, 2013 (edited) After writing out about 2.5 paragraphs to explain what's wrong now (global variables weren't being set or retrieved at all), I went to check a VERY minor detail (whether commenting a seemingly unnecessary line would mess anything up. answer: no) and now it's working flawlessly lol. Anyway, the following (which works and doesn't need fixed as far as I can tell.... yet) is the result. This script will run when the player drinks the potion. When they drink the potion, it will add 150 to the count that was stored last (starts at 0 before drinking any). Then, when the player's health isn't full, it will fully heal the player and remove that much from the count. If the player is missing more health than the current count, then it heals the current count instead of healing fully. It then stores the current count to a global variable so multiple potions can be consumed without negating those before. When the count reaches 0, it removes itself. This does require, however, that the player exit the inventory before drinking another potion, I believe. Scriptname AE_AbsorbDamageScript extends activemagiceffect Float Property AbsorbDamageCountStart Auto Float Property AbsorbDamageCount Auto Float PlayerHealthCurrent Float PlayerHealthDif Float PlayerHealthStart MagicEffect Property AE_AbsorbDamage Auto Spell Property AE_AbsorbDamageDispelSpell Auto Float LastCheck GlobalVariable Property AE_AbsorbDamageCount Auto Event OnInit() RegisterForSingleUpdate(0.5) PlayerHealthStart = Game.GetPlayer().GetBaseAV("Health") AbsorbDamageCountStart = 150 AbsorbDamageCount = AbsorbDamageCountStart + AE_AbsorbDamageCount.GetValue() AE_AbsorbDamageCount.SetValue(AbsorbDamageCount) LastCheck = AbsorbDamageCount Debug.Notification("Absorb Health: Count " + AbsorbDamageCount) EndEvent Event OnUpdate() PlayerHealthCurrent = Game.GetPlayer().GetAV("Health") If ( PlayerHealthCurrent < PlayerHealthStart ) PlayerHealthDif = PlayerHealthStart - PlayerHealthCurrent If ( PlayerHealthDif > AbsorbDamageCount ) PlayerHealthDif = AbsorbDamageCount EndIf Game.GetPlayer().RestoreAV("Health", PlayerHealthDif) AbsorbDamageCount -= PlayerHealthDif AE_AbsorbDamageCount.SetValue(AbsorbDamageCount) If ( LastCheck - AbsorbDamageCount >= 10) Check() EndIf EndIf If ( AbsorbDamageCount <= 0 ) RemoveAura() ; Debug.Notification("Triggered aura removal") EndIf RegisterForSingleUpdate(0.5) ; Debug.Notification("ADC: " + AbsorbDamageCount) EndEvent Function RemoveAura() AE_AbsorbDamageDispelSpell.Cast(Game.GetPlayer()) Debug.Notification("Absorb Damage Aura removed") EndFunction Function Check() Debug.Notification("Absorb Damage: Count " + AbsorbDamageCount + " of " + AbsorbDamageCountStart) LastCheck = AbsorbDamageCount EndFunction Now to go replicate it for the other attributes :smile: Edited December 21, 2013 by Xander9009 Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 13, 2013 Share Posted May 13, 2013 You got it working. That's cool! Link to comment Share on other sites More sharing options...
Recommended Posts