Jump to content

Need to make a potion script run more than once


Xander9009

Recommended Posts

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 by Xander9009
Link to comment
Share on other sites

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

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

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 by Xander9009
Link to comment
Share on other sites

  • Recently Browsing   0 members

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