Function to GetSpellEffect on any npc from a single script.

Post » Sat May 28, 2011 3:09 pm

I'm pretty new at scripting and I want to have a script that can watch for a spell effect on any npc, and creature if it is possible, that is in combat with the player and than be able to grab the ID of that target and be able to do things with it. Do I need MWSE for this and if so can someone tell me which functions I need and short example of how to use them? So in other words I want to be able to manipulate objects that are hit by a spell and I don't see any way of getting the ID of a target of a spell without seriously weird work arounds with the standard scripting.

After skimming the mwse documentation, I came up with this and it doesn't seem the best way to do it at all. I wanted to use xGetCombat or something but I don't know... what can I do?

Here it is:


float starthealthfloat endhealthfloat beinghitlong spelltargetsetx spelltarget to xGetPCTarget;There has to be a better way, but I think searching the cell for npcs is probably the answer and that looks hard. I == nub if ( beinghit == 0 )   ifx ( spelltarget )	   if ( GetSpellEffects, "vn_pv_vampbite" == 1 )		;I want this to be seeing spelltarget		  set starthealth to GetHealth;The health of the target of my spell. 		  set beinghit to 1	   endif   endifendifif (beinghit == 1 )   ifx ( spelltarget )	   if ( GetSpellEffects, "vn_pv_vampbite" == 0 );I want this to be seeing spelltarget		  set beinghit to 0																													   		  set endhealth to GetHealth;spelltarget health again															  set VH_Bloodlevel to ( VH_Bloodlevel + ( starthealth - endhealth ) );other stuff I need done, does nesting parenthesis like this work?   		  Messagebox, "Blood stage 2";test messagebox	   endif	endifendif



Also, is it pretty safe to open my mod up in MWEdit, compile a script and then save my mod? Edit: Nevermind, that broke the mod. Made a patch esp, how can I merge?

Thanks guys.


Edit: With my script I get spammed with the test Messagebox when looking at any object. How is it making it through my GetSpellEffects If statements when I haven't even cast a spell?
User avatar
Unstoppable Judge
 
Posts: 3337
Joined: Sat Jul 29, 2006 11:22 pm

Post » Sat May 28, 2011 3:14 pm

You might be able to merge your patch in TESCS. Possibly even EE. MWEdit is very bugged in some areas, it can really screw things up if you save a mod from there, so it might be best to leave it as a patch until you're sure it's not going to be changed again.

For the script, a question for you: what kind of spell is this? Because xGetPCTarget only gets things that are in the crosshairs ready to be activated (with name-box up on screen, ie close). So if it's a targeted spell you'll miss it using xGetPCTarget. Not sure if it would be reliable for a touch spell either though, I've never really tested it.

--

Edit: just realised, I'm not sure if xGetPCTarget will work for something in combat either. Never tried...
User avatar
Kahli St Dennis
 
Posts: 3517
Joined: Tue Jun 13, 2006 1:57 am

Post » Sat May 28, 2011 12:56 pm

Do I need MWSE for this
Probably. You may be able to do it with dialogue (See Blood and Gore), but it is a pain.


if so can someone tell me which functions I need and short example of how to use them? So in other words I want to be able to manipulate objects that are hit by a spell and I don't see any way of getting the ID of a target of a spell without seriously weird work arounds with the standard scripting.

You are best looping over every NPC in the cell and checking if they are hit with the spell.

short delaylong npcRefif ( delay > 0 )	set delay to delay - 1	returnendififx ( npcRef )	setx npcRef to xNextRefelse	setx npcRef to xFirstNpcendifif ( npcRef )	set delay to 3elseset delay to 30	returnendifxSetRef npcRefif (getSpellEffects "myspell" == 0 )   returnendif;npc has spell



Also, is it pretty safe to open my mod up in MWEdit, compile a script and then save my mod?
Yup
Nevermind, that broke the mod. Made a patch esp, how can I merge?
That shouldn't be happening. The one issue that you may have is that after editing in MWEdit, when you open in the TESCS you must ensure the main 3 esms are checked.

Edit: just realised, I'm not sure if xGetPCTarget will work for something in combat either. Never tried...
It can't be used to detect the combat target
User avatar
!beef
 
Posts: 3497
Joined: Wed Aug 16, 2006 4:41 pm

Post » Sat May 28, 2011 11:54 am

That shouldn't be happening. The one issue that you may have is that after editing in MWEdit, when you open in the TESCS you must ensure the main 3 esms are checked.


I don't know it was a complex mod, I got a missing dialog error when trying to load it after. I will experiment with it more because that would be easier. I am scared it might break something without me knowing though.


Thanks Yacoby for the sample script.


Does anyone know why my loop ( I guess its a loop it looped in my game) script made it through my If ( GetSpellEffect ) statements to the messagebox even though I hadn't cast a spell? I'm really curious about that.

Thanks everyone.
User avatar
Jessica Nash
 
Posts: 3424
Joined: Tue Dec 19, 2006 10:18 pm

Post » Sun May 29, 2011 12:08 am

There's a number of things wrong with your original script, but as far as the spell effects test goes, what exactly are you testing here? What started the script? If it's started from dialogue you're testing the NPC the player was talking to. If it's started from a local script you're testing whatever the script was attached to. And if it's a true global (not targeted) you're testing nothing. You need to test for the effects *on* something - that's why Yacoby's script uses xSetRef before the GetSpellEffects (the xSetRef gives the GetSpellEffects function a target reference to operate on).

And the whole thing "loops" because scripts are run at least once per frame, every frame.

Also, it looks like probably once you've found your NPC/creature being affected by the spell, you'll need to start another script on it to check the starting and end health etc, since it can't all be done in one frame. To do that you can use xSetRef again, like this:
xSetRef npcRefStartScript otherScript

The "otherScript" should have some kind of fix if the game is reloaded too IIRC. Can't remember how that's done atm.

Re MWEdit: I've had issues with compiling scripts with AI commands, errors and crashes ingame using PositionCell with negative values for coords when it's compiled in MWEdit (and it won't even compile if you use negative literal values with xPositionCell), and in mods with lots of refs it sometimes removes half of them. After all that, I don't use it anymore for anything that doesn't actually require it.
User avatar
Chris Guerin
 
Posts: 3395
Joined: Thu May 10, 2007 2:44 pm

Post » Sat May 28, 2011 7:55 pm

Thanks melian that sorted out a lot of things in my mind, and while I think I now have a steady basis to move forward on my own, but still have some questions. Yea, I knew lots of things were wrong with the script it was a test script used to try and move forward from so that I could get some sense of direction from you guys.

I had heard that 1 frame thing before but I never actually thought about it that way. I've been trying to learn from other peoples scripts and I wondered why they used more than one script to run a spell. I knew that many things, functions I guess?, have to be on something and that it has to do with the source of the script which is why I'm trying to do something on the target of a spell. I was hoping that once I did

Ifx ( long )

that was what I was doing. But, now I don't really even know what I was hoping for I was kind of guessing. I was really tired.



I have three questions.

First, what does

Ifx ( long )

do? What is this testing for exactly and how is it different than

If ( long == 0 )

I've seen the same script use both. I guess worded differently what is Ifx for and why would you use If for a long that is going to be set as a reference? Ug, I don't know what I'm saying heh.

Second, when you use

xsetref long

how long does that last? Does it only work for the line right after it? How come many scripts that I am examining have it spammed so much? Wow, that sounds like a dumb question.

Third, if I set my long to an npc reference and I have determined that the npc reference has my spell effect if I start a new script like this

xsetref npcref
startscript spellscript2

Does everything in my new script affect the npc reference?

What if I just did

startscript spellscript2

without the xetref is that completely different?


Edit: Ok, guys I got a basic spell script working and because of your help I think I understand the basic structure of all of this and finding npcs in a cell. I still could use some clarification of the above concepts so that I can create my own work from scratch but I think I'm getting there. Thanks guys.

Also, is a freeze, not a CTD, a sign that a script is stuck in a loop and can't get out? I've got it to where I can find the npc with the spell effect and start a secondscript but once I stop the second script it freezes. If I let the second script loop forever, so that the first script won't start the second again because of a check I have in the first, it doesn't freeze. What could that mean?



Thanks all.
User avatar
Jessica Colville
 
Posts: 3349
Joined: Wed Oct 18, 2006 6:53 pm

Post » Sat May 28, 2011 11:14 am

First, what does

Ifx ( long )

do? What is this testing for exactly and how is it different than

If ( long == 0 )

I've seen the same script use both. I guess worded differently what is Ifx for and why would you use If for a long that is going to be set as a reference?

MWSE functions won't work in normal ifs or whiles, you have to use ifx or whilex. These are limited in what they can do (e.g. you can't say "ifx ( ref->xGetItemCount var > othervar )" or anything like that, it won't work), and there's no elseif, so you have to do some odd workarounds sometimes.

So ifx ( var ) is for when you want to use MWSE functions if var != 0. Much the same with whilex.

You can use normal if/while and of course normal functions inside an ifx/whilex, but not the other way round.

Hope that makes sense.

Second, when you use

xsetref long

how long does that last? Does it only work for the line right after it? How come many scripts that I am examining have it spammed so much?

Basically yes, it's just the next function that operates on that reference. It's used when there's no extended function that can take a ref var that can do what you want, so e.g. if you want to disable something you'd use xSetRef, disable - but if you want to startcombat you'd use ref->xStartCombat ref instead since that's easier/clearer.

Third, if I set my long to an npc reference and I have determined that the npc reference has my spell effect if I start a new script like this

xsetref npcref
startscript spellscript2

Does everything in my new script affect the npc reference?

Yes, that makes "spellscript2" a targeted script on that reference, so it will default to that reference when it needs something to operate on. If you still need a ref var in the "spellscript2" script, you can either set it from the first script or use xRefID without specifying anything, which will get you the ref id of the script's target, and convert that to a ref using xGetRef.

What if I just did

startscript spellscript2

without the xetref is that completely different?

Yes, that would start another global script (as opposed to a targeted script), which would always need to specify the id/reference it's operating on (a targeted script can just say, e.g. SetPos x 512, and that will affect the script's target by default).

Also, is a freeze, not a CTD, a sign that a script is stuck in a loop and can't get out?

It can be, yes (it can mean any number of things, but an infinite loop is definitely one of them).

I've got it to where I can find the npc with the spell effect and start a secondscript but once I stop the second script it freezes. If I let the second script loop forever, so that the first script won't start the second again because of a check I have in the first, it doesn't freeze. What could that mean?

Sorry, not sure what you mean by that... If a script is already running you shouldn't try to start it again, if that's what you're doing (you can check if ScriptRunning to make sure)... Or if the script was already stopped then did you reset any variables that need resetting?
User avatar
Rachel Briere
 
Posts: 3438
Joined: Thu Dec 28, 2006 9:09 am

Post » Sun May 29, 2011 2:49 am

Great, that answered all of my questions. Thanks again melian. That's sweet that you can run a targeted script for any reference. I love that feature.

I got my freeze sorted out I wasn't waiting for the spelleffect to stop in my second script. I guess that still being there caused a problem when the first script fired again.
User avatar
xxLindsAffec
 
Posts: 3604
Joined: Sun Jan 14, 2007 10:39 pm

Post » Sat May 28, 2011 4:23 pm

temp
User avatar
Anna Beattie
 
Posts: 3512
Joined: Sat Nov 11, 2006 4:59 am


Return to III - Morrowind