Script reviewing

Post » Fri Feb 18, 2011 10:38 pm

Okay, I have the start of a script I am writing to check for NPC's and get their distance from the player. Problem is, I can't even begin to test it because it causes a CTD after about 3 seconds from loading the game. Could someone review this and tell me why?

Set rActor to GetFirstRef 69	Label 10	If rActor.GetInSameCell Player == 1		Set fDistanceFrom to rActor.GetDistance Player		PrintC "NPC %n Distance %.2f", rActor, fDistanceFrom		Set rActor to GetNextRef		GoTo 10	EndIf


I'm still very much a noob scripter. I haven't even begun to understand what cuases CTD's and why.

This script definitely causes CTD's though.

Help, please.

Thanks.
User avatar
Isaiah Burdeau
 
Posts: 3431
Joined: Mon Nov 26, 2007 9:58 am

Post » Sat Feb 19, 2011 7:15 am

Alright. Through trial and error, I found out that using the GetFirstRef and GetNextRef functions themselves are causing the CTD.

I know people have successfully used these functions. So why do they cause a CTD when I use them? I'm also going to post in the OBSE thread.
User avatar
Anna Beattie
 
Posts: 3512
Joined: Sat Nov 11, 2006 4:59 am

Post » Fri Feb 18, 2011 11:56 pm

I would use while loops rather than goto, which would also check if the actor exists (the reason why it crashes for you).

set me to GetFirstRef 69 0while me	; whatever you do	set me to GetNextRefloop

User avatar
Naomi Lastname
 
Posts: 3390
Joined: Mon Sep 25, 2006 9:21 am

Post » Fri Feb 18, 2011 9:01 pm

The following works perfectly on my system:

ScriptName TestScriptRef rActorFloat fQuestDelayTime Float fDistanceFromBegin GameMode	Set fQuestDelayTime to 1	Set rActor to GetFirstRef 69 	Label 10 	If ( rActor )		Set fDistanceFrom to rActor.GetDistance Player 		PrintC "NPC %n Distance %.2f", rActor, fDistanceFrom 		Set rActor to GetNextRef 		GoTo 10 	EndIfEnd


Also, if I'm remembering correctly, you want to stagger NPCs, yes? Why not just use a ScriptEffectSpell cast on the player?:

Ref Target1Ref Target2Begin ScriptEffectStart   Set Target1 to GetSelf   Set Target2 to Player   If ( Target1 != Target2 )     If ( Target2 != Target1 )        ;Stagger Target1    EndIf  EndIfEnd


And use a quest to cast it:

Begin GameMode[XmarkerID].MoveTo Player[XMarkerID].Cast [SpellID] Player

User avatar
Josh Trembly
 
Posts: 3381
Joined: Fri Nov 02, 2007 9:25 am

Post » Sat Feb 19, 2011 10:29 am

I would use while loops rather than goto, which would also check if the actor exists (the reason why it crashes for you).

set me to GetFirstRef 69 0while me	; whatever you do	set me to GetNextRefloop



Using a While Loop corrected the CTD and produced the results I'm looking for. Up to this point, that is. I still have to figure out how to make NPC's stagger, but this is a start.

The following works perfectly on my system:

ScriptName TestScriptRef rActorFloat fQuestDelayTime Float fDistanceFromBegin GameMode	Set fQuestDelayTime to 1	Set rActor to GetFirstRef 69 	Label 10 	If ( rActor )		Set fDistanceFrom to rActor.GetDistance Player 		PrintC "NPC %n Distance %.2f", rActor, fDistanceFrom 		Set rActor to GetNextRef 		GoTo 10 	EndIfEnd


Also, if I'm remembering correctly, you want to stagger NPCs, yes? Why not just use a ScriptEffectSpell cast on the player?:

Ref Target1Ref Target2Begin ScriptEffectStart   Set Target1 to GetSelf   Set Target2 to Player   If ( Target1 != Target2 )     If ( Target2 != Target1 )        ;Stagger Target1    EndIf  EndIfEnd


And use a quest to cast it:

Begin GameMode[XmarkerID].MoveTo Player[XMarkerID].Cast [SpellID] Player



That spell doesn't work. Thanks for the tip though. But I tired it, verbatim, and not one single NPC staggered.

I've looked at Deadly Reflex 6. Skycaptains shield bash staggers NPC's very accurately. It is very rare that an NPC doesn't stagger when using the shield bash. However, skycaptain is a much much better scripter than I am, and I can't quite figure out how he does it. He uses something like 3 or 4 scripts to get the stagger effect.

Both of you are better scripters than I. Is there any way you could break down the DR scripts for me, make them more understandable. I don't mean posting the entire script, broken down. Just maybe take a look at them and tell me what is going on in the script?

I hope that favor isn't asking too much. No big deal though. I still have to complete my idea for staggering, but I suspect it's not going to work.
User avatar
Lyd
 
Posts: 3335
Joined: Sat Aug 26, 2006 2:56 pm

Post » Sat Feb 19, 2011 10:38 am

All right!!!!! Positive Progress!!!!

I managed to make an NPC stagger via my script. It's real basic. But, it's definitely not perfect. The game froze for 2 seconds when I got near the NPC, unfroze, and the NPC staggered. I'll post my script and maybe someone can determine why it froze. I'm going to keep trying things, but I am kinda shooting blind, because I don't understand why it froze. It's not a limitation of the function "PlayGroup", because other modders have used it without problems. Anywho, here the script (not much to it yet, I just want the desired result, then I'll refine it):

Set rActor to GetFirstRef 69 0		While rActor		Set fDistanceFrom to rActor.GetDistance Player		If fDistanceFrom < 100			Break		EndIf            Set rActor to GetNextRef	Loop		rActor.PlayGroup Stagger 1


It works, but, like I said, the game freezes for a second and then resumes and the closest NPC does stagger.

EDIT:

Can you nest While Loops?
User avatar
Dezzeh
 
Posts: 3414
Joined: Sat Jun 16, 2007 2:49 am

Post » Sat Feb 19, 2011 9:26 am

You can use nestled while loops without problems. I'm guessing the game froze because you're doing the loop many times somehow, rather than once.
User avatar
BethanyRhain
 
Posts: 3434
Joined: Wed Oct 11, 2006 9:50 am

Post » Sat Feb 19, 2011 10:33 am

Yep, I tried nesting a While Loop, and the game froze up. Best not to do that unless your a better scripter than I am. Which is to say most people can nest the loops.

Anywho, I found a different route for staggering NPC's than the GetFirst/NextRef. I'm using GetCrosshairRef. It works, but not flawlessly.

Here's the problem: The NPC freezes for about 1 second before the stagger animation plays. Like I said a couple posts up, it most likely isn't an limitation of PlayGroup Stagger, because skycaptain uses that function for the shieldbash without problems.

Here's the script:

Set rActor to GetCrosshairRef	Set fDistanceFrom to rActor.GetDistance Player	If rActor.IsActor == 1		Set fDistanceFrom to rActor.GetDistance Player		If fDistanceFrom < 100			rActor.PlayGroup Stagger 1		EndIf	EndIf


I'm going to try to refine the script a little. See if I can't eliminate that animation freeze.

EDIT

Oh. I didn't notice I doubled the variable declaration until I posted this. Let me remove that and see if it helps any.
User avatar
Charleigh Anderson
 
Posts: 3398
Joined: Fri Feb 02, 2007 5:17 am

Post » Sat Feb 19, 2011 9:18 am

instead of using playgroup, try using playidle
User avatar
Elisabete Gaspar
 
Posts: 3558
Joined: Thu Aug 31, 2006 1:15 pm

Post » Sat Feb 19, 2011 9:19 am

Okay, I'll try PlayIdle. Thanks again, 'ol reliable.

Here's my refined script. More work needs to be done, because NPC's still freeze for 1 or 2 seconds before staggering (see if PlayIdle corrects that...).

SetNumericGameSetting IActivatePickLength 300	Set rCrosshairRef to GetCrosshairRef	If rCrosshairRef.IsActor == 1		Set rActor to rCrosshairRef		rActor.PlayGroup Stagger 1	EndIf

User avatar
Kelly John
 
Posts: 3413
Joined: Tue Jun 13, 2006 6:40 am

Post » Sat Feb 19, 2011 5:55 am

No, PlayIdle won't work. The stagger animation is not one of the designated idle animations.
User avatar
Nathan Risch
 
Posts: 3313
Joined: Sun Aug 05, 2007 10:15 pm

Post » Sat Feb 19, 2011 2:44 am

Ooops. Minor details.

copy it to the idles folder? wonder if that would even work......
User avatar
Melis Hristina
 
Posts: 3509
Joined: Sat Jun 17, 2006 10:36 pm

Post » Sat Feb 19, 2011 11:46 am

I don't know. Seems it would take more work to add the stagger animation to all creatures than it would to just leave it alone. I think. I'm baseing this off of the quick browse through the idle animations window to check if stagger was present.

I'll double check, but it could be that there a place that applies to all actors in the game.

I'll post back.

P.S.

I'm also considering the option of adding the stagger animation as an AI package, than calling AddScriptPackage on the reference.
User avatar
Cartoon
 
Posts: 3350
Joined: Mon Jun 25, 2007 4:31 pm

Post » Sat Feb 19, 2011 3:19 am

Nope and nope. To make he stagger animation an idle anim would require adding it to all the creatures in the game. Humanoid NPC's would only require one input, but creatures are separated. Plus it wouldn't effect custom creatures from mods like MMM.

And the other nope is there are set AI packages. You can't create your own, that I know of.
User avatar
roxanna matoorah
 
Posts: 3368
Joined: Fri Oct 13, 2006 6:01 am

Post » Sat Feb 19, 2011 6:02 am

What i was thinking was more along the lines of copying the anim. Adding it to the cs as an Idle, not moving it. That would introduce some serious compatibility issues....... Then you should be able to force it with playidle. I think.
User avatar
dean Cutler
 
Posts: 3411
Joined: Wed Jul 18, 2007 7:29 am

Post » Sat Feb 19, 2011 6:54 am

Yes, but it would be more work to do that, because there are separate Idle Animation categories for each creature type. Copying it to NPC's would be easy, but you have to copy to each creature Idle "folder" separately for each creature.

Something I noticed that maybe you can help me with:

My current script works. It interrupts the reference closes to me and plays the stagger animation. But, if I stay close to the actor, he/she/it freezes for 2 seconds or so and then the stagger animation plays. But I noticed just now that if I get close enough to trigger the stagger animation, and then move quickly away from the actor, the animation plays uninterrupted. So, it seems that there is a link to the actor freeze, and how close I am to the actor.

What are your thoughts on how I can circumvent this?
User avatar
Minako
 
Posts: 3379
Joined: Sun Mar 18, 2007 9:50 pm

Post » Sat Feb 19, 2011 1:13 am

I've got another idea I am not sure how to implement:

Could I tie the animation to the actor to trigger when I activate him/her/it? So, I could then automatically activate the actor when I get within a certain distance.
User avatar
Daniel Holgate
 
Posts: 3538
Joined: Tue May 29, 2007 1:02 am

Post » Sat Feb 19, 2011 9:18 am

Well, the situation has downgraded. The actor I trigger to stagger freezes no matter what until I move away from him/her/it. The actor will remain frozen until I get a certain distance away. Not far, but still...

There has to be a way to remove this freezing. GetCrosshairRef is tied to getting the reference when the player is within activating distance of the actor. If I lower the activating distance, I have to less of a distance to move to make the triggered actor unfreeze and play the stagger animation.

Hmm...I'm gonna try activating the actor immediately after triggering the animation.
User avatar
Je suis
 
Posts: 3350
Joined: Sat Mar 17, 2007 7:44 pm

Post » Sat Feb 19, 2011 9:48 am

Put a check in the script, such that the animation is only called once. Maybe in the distance check? If the result comes back true, set a do once variable, that gets reset after a few seconds or so.
User avatar
Ells
 
Posts: 3430
Joined: Thu Aug 10, 2006 9:03 pm

Post » Sat Feb 19, 2011 6:22 am

Will do, will do.

I made some changes and get better results via the use of an Event Handler. But the actors still freeze prior to staggering. But with the Event Handler, they only freeze for one or two steps away from them.

So, better, but not perfect.

I'll add what you suggested and see if it helps.
User avatar
Gemma Woods Illustration
 
Posts: 3356
Joined: Sun Jun 18, 2006 8:48 pm

Post » Sat Feb 19, 2011 10:57 am

Put a check in the script, such that the animation is only called once. Maybe in the distance check? If the result comes back true, set a do once variable, that gets reset after a few seconds or so.


No, that didn't fix it. Actors still freeze until I move 1 or 2 steps away from them. I'm starting to think it's a limitation of PlayGroup. The wiki says it causes weird behavior. It says you can correct it by calling "Idle" after. But when I tried that, the stagger animation didn't play. I probably didn't implement it right, in my noobness. I'll try again.
User avatar
Taylor Tifany
 
Posts: 3555
Joined: Sun Jun 25, 2006 7:22 am

Post » Sat Feb 19, 2011 10:36 am

I don't know. It seems the actor, when in activating distance from the PC gets it's AI disabled until the PC takes a step or two away from the actor. At which point it resumes the AI package, and starts the stagger animation.

I tried reducing the activating distance, but that caused a BSOD.
User avatar
Nick Jase Mason
 
Posts: 3432
Joined: Sun Jul 29, 2007 1:23 am

Post » Sat Feb 19, 2011 12:33 am

I suspect he is torn between beating up on you, and staggering.... Not sure how to fix though.....
User avatar
Ana Torrecilla Cabeza
 
Posts: 3427
Joined: Wed Jun 28, 2006 6:15 pm

Post » Sat Feb 19, 2011 1:09 am

I don't know either...

I posted in the OBSE thread. Maybe tomorrow one of the OBSE scripting gurus will have an idea as to why the actors freeze.
User avatar
Sylvia Luciani
 
Posts: 3380
Joined: Sun Feb 11, 2007 2:31 am

Post » Sat Feb 19, 2011 7:42 am

It seems you were right in a post you made earlier, HeyYou. You told me to check if the animation was called, but I didn't know how to implement that until I typed with Drake the Dragon. He told me about the IsAnimGroupPlaying function, how to implement it, and BAM! no more actor freezing before playing the stagger animation.

So, I want to thank you once again. I would have had this fixed much sooner had I understood your suggestion properly.
User avatar
Darlene DIllow
 
Posts: 3403
Joined: Fri Oct 26, 2007 5:34 am

Next

Return to IV - Oblivion