Script Question - Absorb Frost

Post » Fri Aug 13, 2010 5:03 am

I'm trying to make a scripted robe that, when worn, causes all frost damage felt by the wearer to heal instead of damage. The only way this is possible, from what I've seen, is using OBSE. I would however like some advice on how to do this in the best way. Here's the part of the script that does the absorbing:

	if ( Timer < 1 )		set Timer to ( Timer + GetSecondsPassed )		Return	else		if ( HasMagicEffect FRDG == 1 )			set FrostMag to GetTotalActiveEffectMagnitude FRDG  ;This function uses OBSE			set FrostMag to ( FrostMag * 2 )			ModAV2 Health FrostMag ;ModAV2 is also OBSE		endif		set Timer to 0	endif


What this does is every second it detects the magnitude of any "frost damage" effects on the wearer, then heals the player by double that. Since damage effects apply on a per-second basis, it would be silly to run this every frame. However, this means that instant-duration effects have a very very small chance of being absorbed, or am I mistaken in that? In any case, I want it to absorb any frost damage felt (after weaknesses and resistances are factored in), and I'd like to know the best way to do that.
User avatar
ShOrty
 
Posts: 3392
Joined: Sun Jul 02, 2006 8:15 pm

Post » Thu Aug 12, 2010 7:43 pm

It's not a vanilla mechanic, so yes, you're pretty much forced to use OBSE.

For your method, not sure why you have a timer present. Instead you might want to use a scripted magic ability to handle the scripting, and just have it either check for the player having a magic effect present when taking damage and how much of that damage is from frost. A scripteffectupdate block 'should' still register any short duration effects since they're both being handled by a similar parent process (spell effects).

But really don't know about most of this.
User avatar
Rhysa Hughes
 
Posts: 3438
Joined: Thu Nov 23, 2006 3:00 pm

Post » Thu Aug 12, 2010 4:44 pm

I tried applying this as a "script effect" apparel enchantment, but for some reason it did absolutely nothing. My guess is that "script effect" simply doesn't work on constant effect enchantments.

Even with ScriptEffectUpdate it would run every frame. Since damage is dealt every second, not every frame, the script would end up healing 40 or 50 times too much. the timer is present to make sure that it only heals you every second, the same rate at which you are damaged.
User avatar
Anna Kyselova
 
Posts: 3431
Joined: Sun Apr 01, 2007 9:42 am

Post » Fri Aug 13, 2010 5:59 am

I tried applying this as a "script effect" apparel enchantment, but for some reason it did absolutely nothing. My guess is that "script effect" simply doesn't work on constant effect enchantments.

This is correct, but can be worked around by having the object scripted to add an ability to the player when worn and remove the ability when the object is unequipped.
User avatar
Czar Kahchi
 
Posts: 3306
Joined: Mon Jul 30, 2007 11:56 am

Post » Fri Aug 13, 2010 3:42 am

Honestly, that wouldn't really do anything. ScriptEffectUpdate would do the same thing as GameMode. At least according to the wiki.

I remember reading somewhere about a mod that causes undead to be damaged by the Restore Health effect. If I could just find of that mod....
User avatar
Emma Pennington
 
Posts: 3346
Joined: Tue Oct 17, 2006 8:41 am

Post » Thu Aug 12, 2010 7:47 pm

Honestly, that wouldn't really do anything. ScriptEffectUpdate would do the same thing as GameMode. At least according to the wiki.

Well, the difference being that the script is being processed with other magic effects, and that things would be a bit more reliable than scripting the item with a gamemode block. The block type determines what conditions the script will run in, not necessarily when the script will run. It's one of those minor details which becomes important for stuff like this.

Since damage is dealt every second, not every frame, the script would end up healing 40 or 50 times too much. the timer is present to make sure that it only heals you every second, the same rate at which you are damaged.

Which is why you use a variable to determine the amount to be healed and only apply that healing once, then zeroing it out afterward. All other aspects could probably be worked out simply by means of using a formula.
User avatar
rae.x
 
Posts: 3326
Joined: Wed Jun 14, 2006 2:13 pm

Post » Fri Aug 13, 2010 12:28 am

Which is why you use a variable to determine the amount to be healed and only apply that healing once, then zeroing it out afterward. All other aspects could probably be worked out simply by means of using a formula.


And what about long-duration effects? If I got hit with 10 points of frost damage over 10 seconds, it would heal me once, for the first second, then I would continue taking damage for the next 9 seconds.


Is there an OBSE function that can detect a spell's duration in the "OnMagicEffectHit" block? If so, I could use that along with "GetTotalAEMagnitude" to set the timer and how long it should last....
User avatar
Alexandra walker
 
Posts: 3441
Joined: Wed Sep 13, 2006 2:50 am

Post » Thu Aug 12, 2010 6:21 pm

And what about long-duration effects? If I got hit with 10 points of frost damage over 10 seconds, it would heal me once, for the first second, then I would continue taking damage for the next 9 seconds.

It would do the 10 points of damage as it happened. 10 points over 10 seconds is not 1 point a second for 10 seconds, but 10 points a second for 10 seconds. The magnitude refers to the damage per hit as opposed to the total.

Is there an OBSE function that can detect a spell's duration in the "OnMagicEffectHit" block? If so, I could use that along with "GetTotalAEMagnitude" to set the timer and how long it should last....

http://cs.elderscrolls.com/constwiki/index.php/GetActiveEffectCount
http://cs.elderscrolls.com/constwiki/index.php/GetNthSpell
http://cs.elderscrolls.com/constwiki/index.php/GetNthActiveEffectDuration
http://cs.elderscrolls.com/constwiki/index.php/GetNthActiveEffectMagnitude

Yes, it means more work, but is likely the only way to get it done. Someone who is more familiar with OBSE could probably help you further. But, is another reason why trying to work around a timer might not work so well. Yes, it has to work within 0/1 logic, but you'll need it to respond more frequently in order to detect damage from multiple sources.
User avatar
james reed
 
Posts: 3371
Joined: Tue Sep 18, 2007 12:18 am

Post » Thu Aug 12, 2010 7:36 pm

I've looked into those functions. They look like they'll do the trick, but there's a problem. GetActiveEffectCount includes every spell effect, and as far as I can see, there's no way to make it only return the number of "Frost Damage" effects GetNthSpell might be able to work around this, but it's poorly documented and doesn't say exactly what it returns. So either way, I don't know what to do with them.


EDIT: I've got an idea, and it`s amazingly simple. Instead of playing around with timers and ModAV, I could have the robe add an ability to the wearer. The ability would only, by default, have "Restore Health 0 points", but every frame the script would check for any magnitude of "Frost Damage", and using OBSE, set the magnitude of the "Restore Health" ability to double that of the total Frost Damage. This allows it to run every frame, catching instant effects, and eliminates worries about duration, as Restore Heath and Frost Damage work at the same pace.
User avatar
sally coker
 
Posts: 3349
Joined: Wed Jul 26, 2006 7:51 pm

Post » Thu Aug 12, 2010 9:30 pm

I've looked into those functions. They look like they'll do the trick, but there's a problem. GetActiveEffectCount includes every spell effect, and as far as I can see, there's no way to make it only return the number of "Frost Damage" effects GetNthSpell might be able to work around this, but it's poorly documented and doesn't say exactly what it returns. So either way, I don't know what to do with them.

Well, that function can still be used to keep track of how many effects are present on the player, and can be used for the purposes of tracking and conditions. To which it could be combined with http://cs.elderscrolls.com/constwiki/index.php/GetNthActiveEffectCode or http://cs.elderscrolls.com/constwiki/index.php/IsSpellTarget. But this discussion has already progressed beyond anything I've personally worked with.
User avatar
Kelly John
 
Posts: 3413
Joined: Tue Jun 13, 2006 6:40 am

Post » Fri Aug 13, 2010 1:38 am

Well, if my modded restore health doesn't work, it appears that I can set the magnitude of the frost damage effects to a negative of itself, which should heal the wearer instead of damage. I've no idea how to go about that, though.

Either way, the timer and ModAV are abandoned in favor of a more magic-appropriate appoach.
User avatar
Marquis deVille
 
Posts: 3409
Joined: Thu Jul 26, 2007 8:24 am

Post » Fri Aug 13, 2010 1:07 am

This thread has been the answer to my work! :D I've been toying with easing sundamage with clothing and being underwater and it seems I finally have the functions to achieve that. GetTotalActiveEffectMagnitude FRDG would indeed give you the total magnitude per second and using that to modify a dummy restore health spell magnitude should work, and if it only has a single effect then SetNthEffectitemmagnitude (frostdamagemagnitude*2) YourHealingspell 0 would modify the effect in due course if used in a script effect. I'm using this healing method with sundamage too but I probably could do it even simpler, by just reducing the active sun damage effects with mod/setnthactiveeffectmagnitude but I don't understand how to get the Sun damage effect references. How would you tell which effects the active sun damage effects are among all the other active effects if you use Getnthactiveeffectcode. I thought our issues are quite similar to be discussed, perhaps we can figure something out :)
User avatar
Rhiannon Jones
 
Posts: 3423
Joined: Thu Sep 21, 2006 3:18 pm

Post » Thu Aug 12, 2010 9:37 pm

Well, as far as i can tell, modding the effects directly using GetNthActiveEffect and ModNthActiveEffect would be the most direct and effective method, but as I have no idea how to go about that, it seems my modded restore health is the best way. If there are any OBSE masters out there, I'd love your input.
User avatar
Pete Schmitzer
 
Posts: 3387
Joined: Fri Sep 14, 2007 8:20 am

Post » Fri Aug 13, 2010 1:00 am

scn HVHAbsorbFrostScriptOBSElong FrostMagref UserRefBegin OnAdd	set UserRef to GetContainerEndBegin OnEquip	UserRef.PlayMagicShaderVisuals GhostEffect	UserRef.AddSpellNS HVHAbsorbFrostHealEndBegin OnUnequip	UserRef.StopMagicShaderVisuals GhostEffect	UserRef.RemoveSpellNS HVHAbsorbFrostHealEndBegin GameMode	if ( UserRef.HasMagicEffect FRDG == 1 )		set FrostMag to UserRef.GetTotalActiveEffectMagnitude FRDG		set FrostMag to ( FrostMag * 2 )	else		set FrostMag to 0	endif	SetNthEffectItemMagnitude FrostMag HVHAbsorbFrostHeal 0End


Here's the latest version of the script. Couple problems though. I put it on, and had myself get pelted by frost damage effect - nothing happened. "HVHAbsorbFrostHeal" displayed a magnitude of 0 points, even when I was actively taking damage from Frost Damage.

BTW, the script is meant to add a visual shader to the wearer, but since the shader I wanted to use is less apparent, I used the more-visual GhostEffect. It applies as desired. HVHAbsorbFrostHeal was also added to the player, as desired. However, the magnitude of HVHAbsorbFrostHeal never changed, and having myself pelted with frost damage effects nearly killed me.
User avatar
abi
 
Posts: 3405
Joined: Sat Nov 11, 2006 7:17 am

Post » Thu Aug 12, 2010 8:07 pm

scn HVHAbsorbFrostScriptOBSElong TempMag  ;This variable stores the magnitude of the frost damage, and alterations are made upon it.long EffectCode  ;Stores the effect code of the desired magic effect, since "GetNthActiveEffectCode" returns longs instead of charsref UserRef  ;The user (in most cases, the player - This exists instead of "player" to allow you to give it to npc's or companions)long NumEffectslong CurrentEffectBegin OnAdd	set UserRef to GetContainerEndBegin GameMode	if ( UserRef.GetEquipped HVHIceRobeOBSE == 0 )		return  ;Do nothing if the user doesn't have the item equipped	endif	set NumEffects to UserRef.GetActiveEffectCount	set CurrentEffect to 0	set EffectCode to GetMagicEffectCode FRDG ; Sets "Frost Damage" as the affected magic effect	if ( NumEffects <= 0 )		return  ;stops the loop from running at all if the player doesn't have any active effects	endif	Label  ;The loop begins here	If ( UserRef.GetNthActiveEffectCode CurrentEffect == EffectCode )  ;Only apply the script to the effect you want		set TempMag to UserRef.GetNthActiveEffectMagnitude CurrentEffect		if ( TempMag > 0 )  ;Only apply to magnitudes that we haven't already reversed			set TempMag to ( TempMag * -1 )			UserRef.SetNthActiveEffectMagnitude TempMag CurrentEffect		endif	endif	set CurrentEffect to ( CurrentEffect + 1 )	if ( CurrentEffect < NumEffects )		GoTo ;Returns processing of the script to "Label", allowing the loop	endifEnd


...And here's the newest rendition of the script, using the direct effect modding approach. Problem is, this script doesn't do much more than the last one. I pelted myself with frost damage, and it wouldn't heal me one bit. I looked up "frost damage" under my active effects, and they showed positive. Could I be using GetNthActiveEffectCode wrong?
User avatar
Naomi Ward
 
Posts: 3450
Joined: Fri Jul 14, 2006 8:37 pm

Post » Thu Aug 12, 2010 4:53 pm

That's brilliant, I don't know why it doesn't work. It definitely should :) Ah, I see, It's not that you're using the command wrong, it's just that you don't get healed if you reverse the effects of a damage effect :P It doesn't really work that way. In your case a modified healing spell would be an only option if you want frost to heal you. But you've helped me accomplish the sundamage reduction with this last piece of code and I'm very grateful! :)
User avatar
Nicole M
 
Posts: 3501
Joined: Thu Jun 15, 2006 6:31 am

Post » Thu Aug 12, 2010 4:54 pm

Well that's dissapointing. You used my script with something other than "* -1" and it worked fine, I presume?

So, if neither scripts work for me, how can I get one of them working?


Either way, I seem to have successfully created an artificial "weakness/resistance to" script (which should theoretically work for scripted spells too, just replace GameMode with ScriptEffectUpdate, remove the bit about it being equipped, and eliminate all instances of "UserRef."). That's gotta count for something, right?


Somehow I keep thinking that the problem is somewhere around here:
		set TempMag to UserRef.GetNthActiveEffectMagnitude CurrentEffect		if ( TempMag > 0 )  ;Only apply to magnitudes that we haven't already reversed			set TempMag to ( TempMag * -1 )

Now, if "if ( TempMag > 0 )" isn't working right, that means every frame it would be switching the sign of every active frost effect. (by the way, watch out for that: without "* -1", "if ( TempMag > 0 )" will always return true, meaning any modifier you place on that effect will repeat next frame. So, I guess artificial weakness/resistance wont work quite as nicely as I'd hoped... It's likely possible, but you'd have to flag a certain active effect as modified, and then have a way to find out if that effect's duration has expired so you can delete the flag. Plus you have to worry about other effects expiring and that effect changing position. Maybe if you flag the effect's source....)

Are there any issues with "long"s storing negatives...?
User avatar
Amanda savory
 
Posts: 3332
Joined: Mon Nov 27, 2006 10:37 am

Post » Fri Aug 13, 2010 5:58 am

I haven't actually gotten it to work yet. Namely because of that flag issue you mentioned. I'm having some trouble figuring out how to store the original magnitude, so I can restore it when the scripted spell expires. Sundamage is commonly used as an ability so I don't really have worry about it running out(although the effects get removed or modified from time to time) I think you were on to something with your initial script. But I also stand corrected about reversed damage not giving you health, I didn't know what I was talking about...had to test it :)
User avatar
Kanaoka
 
Posts: 3416
Joined: Fri Jun 16, 2006 2:24 pm

Post » Fri Aug 13, 2010 12:27 am

Well, maybe if we're really really lucky, run in a circle counter-clockwise around a nix-hound 3 times, and pray to Hermaeus Mora for a good harvest, a master of OBSE will come in and shed some light on the situation.


'cause this is pretty much as far as I go without assistance :S
User avatar
Louise
 
Posts: 3407
Joined: Wed Nov 01, 2006 1:06 pm

Post » Fri Aug 13, 2010 2:48 am

I would like to chime in that I have tried using negatives before, and it just didn't work. In my case I tried to use negative values for defensive magic buffs (resist fire, resist magic, spell absorption, spell reflect, etc.).

I can't give you any more insight on your current script, but if you want to try something completely different, try this:
Detect projectiles using getfirstref/getnextref.
Check for distance, frost damage, and magnitude.
Make the projectile disappear (if desired).
Modav the player's health.
User avatar
Jade Barnes-Mackey
 
Posts: 3418
Joined: Thu Jul 13, 2006 7:29 am

Post » Thu Aug 12, 2010 9:59 pm

That would leave out on touch spells though, as well as weapon enchantments.

I thought using a negative magnitude might work, as the wiki said that it did with Damage Health. I guess negative magnitude only works for simple magic effects (possibly fortify/drain, too?).


Hmm, is there a reliable way to detect FPS, in such a way that I could use ModAV to heal at a rate of once per second instead of once per frame, without using a timer (except maybe to get fps, if it's needed)?

..Or better yet, does OBSE have a function that mods health (or other stats) on a per-second basis instead of per-frame?
User avatar
Joe Bonney
 
Posts: 3466
Joined: Tue Jul 17, 2007 12:00 pm

Post » Thu Aug 12, 2010 7:50 pm

As for your FPS question, I can't answer that. I would just use a timer to make sure an appropriate amount of health is added every second.

Since my first idea didn't work, here's another. If your script detects a frost damage effect on the player, how about applying a restore health effect to the player, with twice the magnitude and same duration? Or, make a simple 1hp/sec effect and apply it multiple times to match the magnitude, and reapply these effects again for every second.
User avatar
[ becca ]
 
Posts: 3514
Joined: Wed Jun 21, 2006 12:59 pm

Post » Thu Aug 12, 2010 9:57 pm

That sounds awfully similar to my modded restore health idea. See my first script - uses GetTotalActiveEffectMagnitude FRDG and sets the magnitude of a 0 - point restore health ability to whatever you have for frost damage magnitude.

Can you think of a reason why SetNthEffectItemMagnitude isn't working?
User avatar
Channing
 
Posts: 3393
Joined: Thu Nov 30, 2006 4:05 pm

Post » Thu Aug 12, 2010 9:33 pm

That sounds awfully similar to my modded restore health idea. See my first script - uses GetTotalActiveEffectMagnitude FRDG and sets the magnitude of a 0 - point restore health ability to whatever you have for frost damage magnitude.

Can you think of a reason why SetNthEffectItemMagnitude isn't working?

I don't think 0 is a valid magnitude for spells like that. Instead, you might try just removing the spell from the player if the magnitude is not atleast 1.
User avatar
Ludivine Poussineau
 
Posts: 3353
Joined: Fri Mar 30, 2007 2:49 pm

Post » Thu Aug 12, 2010 8:12 pm

I don't think 0 is a valid magnitude for spells like that. Instead, you might try just removing the spell from the player if the magnitude is not atleast 1.

I'll try that, it can't hurt. It also solves the problem of a useless effect in the player's spell list.
User avatar
Shianne Donato
 
Posts: 3422
Joined: Sat Aug 11, 2007 5:55 am

Next

Return to IV - Oblivion