crimson's thread of questions

Post » Sat Feb 19, 2011 6:22 am

Hey!

I'm having a bit of a problem. I wrote this script that's supposed to make a custom spell:

{iCode, iArea, iDuration, iMagnitude, iRange, iType}
Spoiler
scriptName ccWMakeEffectItemref poisonref spellDummyint iCodeint iAreaint iDurationint iMagnitudeint iRangeint iTypebegin _function {iCode, iArea, iDuration, iMagnitude, iRange, iType}	let spellDummy := DefaultPlayerSpell	let poison := cloneForm spellDummy		removeNthEffectItem poison 0		setSpellType iType poison	setSpellMagickaCost 0 poison	setSpellImmuneToSilence 1 poison	setSpellDisallowAbsorbReflect 1 poison		addFullEffectItemC iCode iMagnitude iArea iDuration iRange poison		setFunctionValue poisonend


Then I made this, which is supposed to add a 1 Fire Damage ability on the player, after which - I thought - the ability would disappear. Only it doesn't. It kills me.
Spoiler
scn ccFire10int fDmgint iFiDgCref rFiDgref selfbegin _scriptEffectStart	let self := getSelf	let iFiDgC := getMECode "FIDG"	let rFiDg := call ccTestMakeEffectItem iFiDgC 0 10 1 0 0	self.addSpellNS rFiDg	let fDmg := 10	scribe "Damage: %.4f" fDmgend


Any ideas why?

Also, at the moment, the spell appears in the "active effects tab" as "heal minor wounds" - is there a way to change the displayed name?

Thank you!

cc
User avatar
Nick Pryce
 
Posts: 3386
Joined: Sat Jul 14, 2007 8:36 pm

Post » Fri Feb 18, 2011 9:38 pm

Then I made this, which is supposed to add a 1 Fire Damage ability on the player, after which - I thought - the ability would disappear. Only it doesn't. It kills me.
Any ideas why?

Effects from Ability type spells will remain constant until the spell is removed. Your second script doesn't appear to be set up to remove it, so it remains and continues to damage you until dead. Also, Ability spells bypass resistances, so adding 100% resist fire after a moment won't help here. (Just FYI - I found this out the hard way. :P )

Also, at the moment, the spell appears in the "active effects tab" as "heal minor wounds" - is there a way to change the displayed name?

It sounds like you changed the EditorID and effects of the spell without changing the name also. Find your spell in the CS and alter the Name field (Just below the EditorID) to whatever you want the name to appear as is game.
User avatar
Celestine Stardust
 
Posts: 3390
Joined: Fri Dec 01, 2006 11:22 pm

Post » Sat Feb 19, 2011 1:45 am

Effects from Ability type spells will remain constant until the spell is removed. Your second script doesn't appear to be set up to remove it, so it remains and continues to damage you until dead. Also, Ability spells bypass resistances, so adding 100% resist fire after a moment won't help here. (Just FYI - I found this out the hard way. :P )


It sounds like you changed the EditorID and effects of the spell without changing the name also. Find your spell in the CS and alter the Name field (Just below the EditorID) to whatever you want the name to appear as is game.


Thanks for getting back to me!

I wonder if using the "cast" command instead of "add spell" would work. Do you know if that takes into account resistances & weaknesses?

Ah, one thing - abilities bypass resistances always or do they bypass those added on the same frame? Because I know that it's possible that adding a new active effect would not happen until the end of the current frame. If this is the case, waiting for a frame after casting the resistance should take it into account.

As for the name, I didn't make the spell in the CS, it's generated on the fly by the script. There's no command that I know of that can change the name though.

Edit: What's the best way to make a function script wait for a number of seconds? In the case of the above, I would need to wait 10 seconds before removing the ability. But the code is inside a function that only runs once. Therefore, I would have to either delay the "return" of the function by 10 seconds (haven't found a "wait" function), or have a quest script that removes the effect from the actor after 10 seconds. I would prefer the former, if at all possible.

Cheers!

cc
User avatar
bimsy
 
Posts: 3541
Joined: Wed Oct 11, 2006 3:04 pm

Post » Fri Feb 18, 2011 11:28 pm

I wonder if using the "cast" command instead of "add spell" would work. Do you know if that takes into account resistances & weaknesses?

If you go with the "cast" function, it would have to be from an activator, in which case magical resistances would not be bypassed.

Ah, one thing - abilities bypass resistances always or do they bypass those added on the same frame? Because I know that it's possible that adding a new active effect would not happen until the end of the current frame. If this is the case, waiting for a frame after casting the resistance should take it into account.

I'm not sure about that. I only know about the bypass issue because I tried modifying my cousin's Elemental Elves mod a bit. I gave the Fire Elves a 5 point Fire Damage Ability so the fire damage shader would always play but it completely bypassed the 100% fire resistance, so it was a bust.

Edit: What's the best way to make a function script wait for a number of seconds? In the case of the above, I would need to wait 10 seconds before removing the ability. But the code is inside a function that only runs once. Therefore, I would have to either delay the "return" of the function by 10 seconds (haven't found a "wait" function), or have a quest script that removes the effect from the actor after 10 seconds. I would prefer the former, if at all possible.


The best way to have an Ability spell removed after a specific amount of time is to make a script specifically for that and add it to the spell itself. An example script would be:

scn MySpellRemovalScriptfloat timerref mebegin GameModeset me to GetSelfset timer to timer + GetSecondsPassedif timer >= 10	me.removespell MySpellIDendifend


Attach the above script to your spell (after replacing MySpellID with the EditorID of your spell) and it will remove itself after 10 seconds.
User avatar
Sxc-Mary
 
Posts: 3536
Joined: Wed Aug 23, 2006 12:53 pm

Post » Fri Feb 18, 2011 8:30 pm

Hey!

I tried using a GameMode block on a magic effect item but that just crashes the script. So I learned that the best way to get an Ability applied and removed after a certain period is by using tokens. Below is a script attached to such a token. It adds a Fire Damage ability with magnitude 1 and duration 10 to the "target" (in my case I tested on the player character), after which it removes it. "ccTestRemoval" is merely a shortcut function that checks if the target is an actor, if it's alive and if it's enabled.

The problem is that this ability does more than 10 damage. In fact, it does almost 40 (39) i.e 4 per second. There are no weaknesses nor resistances in effect, even if they were to apply to an ability-type effect (which I heard they don't).

Spoiler
scriptName ccTestFireTokenScriptref targetref rFiDgint iFiDgCint initint healthint countfloat timerfloat fQuestDelayTimebegin onAdd	let target := getContainer	if eval (target == 0)		return	elseif eval (call ccTestRemoval target)		return	else		let iFiDgC := getMECode "FIDG"		let rFiDg := call ccTestMakeEffectItem iFiDgC 0 10 1 0 4		let health := target.getAVC 8		scribe "Initial health: %.4f" health		target.addSpellNS rFiDg		let timer := 0		let init := 1	endifendbegin _gameMode	let fQuestDelayTime := 0.01	if eval (init == -1)		target.removeSpellNS rFiDg		removeMe	elseif eval (init == 0)		return	elseif eval (call ccTestRemoval target)		let init := -1		return	else		let timer += getSecondsPassed		if eval (timer - count >= 1)			let health := target.getAVC 8			scribe "health: %.4f" health			let count += 1			scribe "time: %.4f" count		endif				if eval (timer >= 10)			let health := target.getAVC 8			scribe "Final health: %.4f" health			let init := -1			debugBreak			return		endif	endifend


Spoiler
scriptName ccWMakeEffectItemref poisonref spellDummyint iCodeint iAreaint iDurationint iMagnitudeint iRangeint iTypebegin _function {iCode, iArea, iDuration, iMagnitude, iRange, iType}	let spellDummy := DefaultPlayerSpell	let poison := cloneForm spellDummy		removeNthEffectItem poison 0		setSpellType iType poison	setSpellMagickaCost 0 poison	setSpellImmuneToSilence 1 poison	setSpellDisallowAbsorbReflect 1 poison		addFullEffectItemC iCode iMagnitude iArea iDuration iRange poison		setFunctionValue poisonend


Thank you!

cc
User avatar
Strawberry
 
Posts: 3446
Joined: Thu Jul 05, 2007 11:08 am

Post » Sat Feb 19, 2011 6:54 am

Shameless bump :whistling:

I know they're not exactly short, but that's the minimal amount of code that does what I need with a fair degree of safety (as far as I know, anyway).

Thanks in advance!

cc
User avatar
JERMAINE VIDAURRI
 
Posts: 3382
Joined: Tue Dec 04, 2007 9:06 am

Post » Sat Feb 19, 2011 3:05 am

I tried using a GameMode block on a magic effect item but that just crashes the script. So I learned that the best way to get an Ability applied and removed after a certain period is by using tokens. Below is a script attached to such a token. It adds a Fire Damage ability with magnitude 1 and duration 10 to the "target" (in my case I tested on the player character), after which it removes it. "ccTestRemoval" is merely a shortcut function that checks if the target is an actor, if it's alive and if it's enabled.

Just thought I'd throw in my 2c;

It looks like it's getting too complicated for what you want to do... rather than have a token that adds/removes an ability, why not just put it all on the token. Give the token an EffectItem, and have your token script manipulate it into the effect you want then equip itself, then after the required time remove itself.

However, even that is sounding messier than just http://cs.elderscrolls.com/constwiki/index.php/Casting_Spells_From_An_Activator... old school, but still good. In your case you can replace "The Self Spell Script" with a function or something that just moves the activator above the target actor, crafts the spell using OBSE into the spell you want with the required duration and then casts it at the actor. The spell doesn't need to be an area of effect spell.

Also;

fQuestDelayTime doesn't do anything in non-quest scripts.

Sometimes token gamemode blocks run before onadd blocks, so your gamemode blocks need to detect this and return until the onadd block has had a chance to run. Using "IsFormValid target" works, or only use a gamemode block.

Don't use CloneForm like this because you'll bloat the savegame with one-off spells you never use again. Instead add a single spell in the CS that you change every time you want to cast it.

Duration is meaningless for ability spells... ability spells are designed to be constant. They also are added to the base form, so adding an ability to one wolf means that you've just added it to all wolves.

The Vyper: Rather than add a fire-damage ability for the burning elf effect, make a scripted ability with the fire-damage shader and no script. You might also be able to use a fire-damage ability of magnitude 0...
User avatar
Doniesha World
 
Posts: 3437
Joined: Sun Jan 07, 2007 5:12 pm


Return to IV - Oblivion