Need help with this script

Post » Fri May 27, 2011 6:38 pm

I wrote the simple script below to force an NPC to give a voice greeting, but it's not working. The NPC does say the greeting, but keeps repeating it infinitely (like every frame). What did I do wrong?

begin FW_greeting_N_nice        if  ( GetDistance, Player < 150 )				        say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"    endif    end FW_greeting_N_nice


The extent of my scripting capability is to find a similar existing script and copy-paste-modify it... and hope it works. :blush: Unfortunately, this one does not. It's probably something very simple (or at least I hope it is). So what would I need to do in order to make the greeting execute only once? Any assistance would be greatly appreciated!
User avatar
lucy chadwick
 
Posts: 3412
Joined: Mon Jul 10, 2006 2:43 am

Post » Fri May 27, 2011 8:53 pm

You need to declare a Short. DoOnce is a commonly used name, so it's easy to remember the function.

begin FW_greeting_N_niceshort DoOnce        if  ( GetDistance, Player < 150 )				    if ( DoOnce == 0 )        say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"	set DoOnce to 1    endif    end FW_greeting_N_nice

User avatar
Saul C
 
Posts: 3405
Joined: Wed Oct 17, 2007 12:41 pm

Post » Sat May 28, 2011 6:40 am

You need to declare a Short. DoOnce is a commonly used name, so it's easy to remember the function.

begin FW_greeting_N_niceshort DoOnce        if  ( GetDistance, Player < 150 )				    if ( DoOnce == 0 )        say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"	set DoOnce to 1    endif    end FW_greeting_N_nice



EDIT: actually, you know. Your script should work without a doOnce.
And I think I'm missing an EndIf.

I shouldn't drink and script. Sorry.
User avatar
FABIAN RUIZ
 
Posts: 3495
Joined: Mon Oct 15, 2007 11:13 am

Post » Sat May 28, 2011 2:37 am

EDIT: actually, you know. Your script should work without a doOnce.
And I think I'm missing an EndIf.

I shouldn't drink and script. Sorry.


Thanks Pluto for the quick reply! I will give this a go. (And no worries - I am sure that your scripting abilities far surpasses mine... drinking or not! :D ) Thanks again.
User avatar
Tiff Clark
 
Posts: 3297
Joined: Wed Aug 09, 2006 2:23 am

Post » Sat May 28, 2011 5:02 am

You do need some way to tell the script to only do the greeting once, Pluto, otherwise it'll continue to "greet" every frame because scripts are run every frame. Maneki, do you want the NPC to only say the greeting once or do you want them to say it again? If it's the former, Pluto's would work like this:

begin FW_greeting_N_niceshort DoOnce        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        endif    endif    end


If it's the later, you'll need to reset the DoOnce variable, but how and where you do that will depend on if this script is attached to the NPC or not.
User avatar
Charlotte Buckley
 
Posts: 3532
Joined: Fri Oct 27, 2006 11:29 am

Post » Sat May 28, 2011 9:15 am

You do need some way to tell the script to only do the greeting once, Pluto, otherwise it'll continue to "greet" every frame because scripts are run every frame. Maneki, do you want the NPC to only say the greeting once or do you want them to say it again? If it's the former, Pluto's would work like this:

begin FW_greeting_N_niceshort DoOnce        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        endif    endif    end


If it's the later, you'll need to reset the DoOnce variable, but how and where you do that will depend on if this script is attached to the NPC or not.


Thanks Jac. Actually, I do want the NPC to say this line each time the player approaches. In testing Pluto's version, I found it worked fine, but when I returned to this NPC, he just gave me a generic greeting from that point on. I knew from past (very limited) experience that you can reset things by leaving the cell, so I found an example of that in some other script, and modified mine this way:

begin FW_greeting_N_nice        short DoOnce        if  ( GetDistance, Player < 150 )				        if ( DoOnce == 0 )            say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"            set DoOnce to 1        endif    endif        ;reset dialogue    if ( CellChanged == 1 )        set DoOnce to 0    endif    end FW_greeting_N_nice



This works, but is there a better way to reset the greeting (e.g. without having to leave the cell and re-enter it)? Let me know if there is. Thanks!

Also, I was wondering if it's possible to put TWO lines of voice together? For example, the first voice file might say, "You shouldn't be here," and the second says, "Get out of here!" Those are two separate mp3 files, so is there a way to make the NPC say both of them in sequence? I tried, but he just goes back to repeating only the first greeting infinitely, so obviously I did something wrong. Or maybe it can't be done? I would greatly appreciate any advice you have for this. Thanks again.
User avatar
Madeleine Rose Walsh
 
Posts: 3425
Joined: Wed Oct 04, 2006 2:07 am

Post » Sat May 28, 2011 2:14 am

You could have doOnce reset when the player is a certain distance away, for example:

begin FW_greeting_N_niceshort DoOnce        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        endif    endif        if ( GetDistance, Player > 500 )         set doOnce to 0    endifend

User avatar
An Lor
 
Posts: 3439
Joined: Sun Feb 18, 2007 8:46 pm

Post » Fri May 27, 2011 7:58 pm

You could have doOnce reset when the player is a certain distance away, for example:

begin FW_greeting_N_niceshort DoOnce        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        endif    endif        if ( GetDistance, Player > 500 )         set doOnce to 0    endifend




Yes, that would work much better than having to leave the cell. Thanks Epididamus! (Any thoughts on executing two mp3's in sequence?)
User avatar
Sheila Esmailka
 
Posts: 3404
Joined: Wed Aug 22, 2007 2:31 am

Post » Fri May 27, 2011 6:05 pm

That can be done using SayDone. If the NPC isn't saying anything, SayDone returns 1. So your script could look something like this:

begin FW_greeting_N_niceshort DoOncefloat timer        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        elseIf ( DoOnce == 1 )             if ( SayDone == 1 )                  if ( timer < 2 )  ; this if statement causes him to wait a few seconds before saying the second thing.                       set timer to ( timer + GetSecondsPassed )                   else                       set DoOnce to 2                       say, "vo\N\m\Idl_NM001", "What makes this smell?"                  endif        endif    endif        if ( GetDistance, Player > 500 )         set doOnce to 0    endifend

User avatar
Ells
 
Posts: 3430
Joined: Thu Aug 10, 2006 9:03 pm

Post » Sat May 28, 2011 8:35 am

That can be done using SayDone. If the NPC isn't saying anything, SayDone returns 1. So your script could look something like this:

begin FW_greeting_N_niceshort DoOncefloat timer        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        elseIf ( DoOnce == 1 )             if ( SayDone == 1 )                  if ( timer < 2 )  ; this if statement causes him to wait a few seconds before saying the second thing.                       set timer to ( timer + GetSecondsPassed )                   else                       set DoOnce to 2                       say, "vo\N\m\Idl_NM001", "What makes this smell?"                  endif        endif    endif        if ( GetDistance, Player > 500 )         set doOnce to 0    endifend



Thank you very much for your help with this! No way I would have ever figured that one out... :wacko:
User avatar
Monique Cameron
 
Posts: 3430
Joined: Fri Jun 23, 2006 6:30 am

Post » Sat May 28, 2011 9:46 am

That can be done using SayDone. If the NPC isn't saying anything, SayDone returns 1. So your script could look something like this:

begin FW_greeting_N_niceshort DoOncefloat timer        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        elseIf ( DoOnce == 1 )             if ( SayDone == 1 )                  if ( timer < 2 )  ; this if statement causes him to wait a few seconds before saying the second thing.                       set timer to ( timer + GetSecondsPassed )                   else                       set DoOnce to 2                       say, "vo\N\m\Idl_NM001", "What makes this smell?"                  endif        endif    endif        if ( GetDistance, Player > 500 )         set doOnce to 0    endifend




Epididamus: I tried to implement your version of this script, and the editor gave me an error indicating, "Mismatched if/else/endif starting on line 6." I looked but couldn't figure out what the problem is... Do you know what it could be? Thanks!
User avatar
sarah
 
Posts: 3430
Joined: Wed Jul 05, 2006 1:53 pm

Post » Sat May 28, 2011 9:38 am

If I'm reading this right... I believe you're just missing one (it's lined up correctly to see which if has an end, and there isn't one belonging to the "if ( SayDone == 1 )")

I think this should work:

begin FW_greeting_N_niceshort DoOncefloat timer        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        elseIf ( DoOnce == 1 )             if ( SayDone == 1 )                  if ( timer < 2 )  ; this if statement causes him to wait a few seconds before saying the second thing.                       set timer to ( timer + GetSecondsPassed )                   else                       set DoOnce to 2                       say, "vo\N\m\Idl_NM001", "What makes this smell?"                  endif             endif        endif    endif        if ( GetDistance, Player > 500 )         set doOnce to 0    endifend

User avatar
Yvonne
 
Posts: 3577
Joined: Sat Sep 23, 2006 3:05 am

Post » Fri May 27, 2011 7:07 pm

If I'm reading this right... I believe you're just missing one (it's lined up correctly to see which if has an end, and there isn't one belonging to the "if ( SayDone == 1 )")

I think this should work:

begin FW_greeting_N_niceshort DoOncefloat timer        if  ( GetDistance, Player < 150 )				         if ( DoOnce == 0 )             say, "vo\N\m\Hlo_NM135.mp3", "Hail and welcome friend, hail!"             set DoOnce to 1        elseIf ( DoOnce == 1 )             if ( SayDone == 1 )                  if ( timer < 2 )  ; this if statement causes him to wait a few seconds before saying the second thing.                       set timer to ( timer + GetSecondsPassed )                   else                       set DoOnce to 2                       say, "vo\N\m\Idl_NM001", "What makes this smell?"                  endif             endif        endif    endif        if ( GetDistance, Player > 500 )         set doOnce to 0    endifend



Yes, that did the trick! Thanks Caz!
User avatar
rae.x
 
Posts: 3326
Joined: Wed Jun 14, 2006 2:13 pm

Post » Fri May 27, 2011 6:55 pm

First of all, thanks again to all who assisted with writing this script. Couldn't have done it without your input.

Now that I have certain NPC's speaking to me, is there a way to make them pause (if moving) and face me before reciting their line? I notice this is the standard routine when an NPC greets the player (stop any movement, and turn to face the PC), but with my script, they will often say their lines while doing one of the idle movements, or even while walking past me. That's not very realistic. I know that Idle1 of the AiWander package makes the character stand still and do nothing, but how do I implement that via script, as well as making the NPC turn and face the player (if that is possible)?

I would appreciate any assistance. Thanks!
User avatar
StunnaLiike FiiFii
 
Posts: 3373
Joined: Tue Oct 31, 2006 2:30 am

Post » Fri May 27, 2011 7:58 pm

I'm not sure if you can force an Idle animation in a script, but it's worth a try.

If you increase the Hello # in their AI they will turn and face you sooner. (default is usually 30)
User avatar
Felix Walde
 
Posts: 3333
Joined: Sat Jun 02, 2007 4:50 pm

Post » Sat May 28, 2011 10:16 am

http://www.uesp.net/wiki/Tes3Mod:Face makes them turn to face a certain point. Unfortunately, I don't think that it accepts variables for parameters, so no facing PC specifically. You might try to make a script that checks coordinates of both PC and NPC, compares them, and then accordingly turns the NPC towards one of indubitably far points at north, north-west, west, etc. from the current location, producing an *approximate* feeling of facing PC. Of course, it would only work on NPCs of certain known location and not as a generic solution.
User avatar
katsomaya Sanchez
 
Posts: 3368
Joined: Tue Jun 13, 2006 5:03 am

Post » Sat May 28, 2011 8:08 am

I'm not sure how to make the NPC face you, but I do know how to force an idle animation:
Playgroup, Idle, 1

Playgroup is the function, Idle is the animation, and 1 forces the NPC to stop the current animation immediately and start the Idle animation.
User avatar
Carlos Vazquez
 
Posts: 3407
Joined: Sat Aug 25, 2007 10:19 am

Post » Sat May 28, 2011 1:32 am

Thanks all for the replies. That's too bad I can't make them do specifically what I want. Maybe a combination of these suggestions will come close. Thanks again!
User avatar
Rachel Cafferty
 
Posts: 3442
Joined: Thu Jun 22, 2006 1:48 am

Post » Fri May 27, 2011 6:08 pm

Once the distance is met for the forced greeting you could set the NPC's AI to follow the player. The NPC will immediately face the player as a result. After a short delay for this action, set the AI to wander and then force greet the player.
User avatar
Lady Shocka
 
Posts: 3452
Joined: Mon Aug 21, 2006 10:59 pm

Post » Fri May 27, 2011 9:53 pm

Once the distance is met for the forced greeting you could set the NPC's AI to follow the player. The NPC will immediately face the player as a result. After a short delay for this action, set the AI to wander and then force greet the player.


Hmm... never thought of that. I've played with a lot of companion NPC's and have seen this behavior (turning toward the player once 'enlisted'), so I think this could work! But now the challenging part (for me) is to see if I can actually write the script...!

I may be back asking for help with that next. :hehe:

Thanks cyran0!
User avatar
Marta Wolko
 
Posts: 3383
Joined: Mon Aug 28, 2006 6:51 am

Post » Fri May 27, 2011 11:48 pm

OK, I am finally getting around to trying this out. The NPC greeting (and reset) script as chronicled above is working great. Thanks to all who helped with writing it.

Now for this last bit. The script as is works fine for stationary NPC's, but I would also like to add greetings to wandering NPC's, as well. As it is written, my script does not distinguish what the NPC is doing at the time of greeting. So, sometimes they will say their greeting as they're walking past, or while doing one of the idle motions and not even looking at me (which is not realistic). To correct this, I would like to try to implement what cyran0 proposed above, which is to temporarily put the NPC into AiFollow mode in order to make them stop what they're doing, face the player, then recite their greeting, and then go back out of AiFollow and resume their normal wandering. I am not good at scripts, so I try to find something similar in one of the original Morrowind scripts, and copy-paste and modify it. But this method doesn't always work. :( Like in this instance. Below is the original Hlormar script, which I looked at because he is one of the NPC's who follows the player. But I can't figure out how to adapt that to my situation. Can anyone help? It would be very much appreciated! Thanks.
Begin hlormarScriptshort followOnshort greetonceshort noloreif ( GetJournalIndex "MV_AbusedHealer" >= 80 )	returnendifif ( MenuMode == 1 )	return	;don't run time in Menu Mode. Very bad.endifIf ( GetCurrentAIPackage == 3 )	set followOn to 1endifif ( GetCurrentAIPackage != 3 )	set followOn to 0endifif ( greetonce == 0 )	if ( Player->GetItemCount "cloudcleaver_unique" > 0 )		if ( GetDistance Player <= 512 )			ForceGreeting			;set greetonce to -1		endif	endifendif;short Greeted;if ( Greeted == 1 );	return;endif;if ( GetJournalIndex "MV_AbusedHealer" != 50 );	return;endif;if ( Greeted == 0 );	If ( GetJournalIndex "MV_AbusedHealer" == 50 ) ;		ForceGreeting;		Set Greeted to 1;	endif;endifend

User avatar
Chloé
 
Posts: 3351
Joined: Sun Apr 08, 2007 8:15 am

Post » Fri May 27, 2011 7:09 pm

It sounds like you require a script for a different situation than you first explored, but just in case I will offer an update of your original script as well as versions that will allow the NPC to return to a wander package.

Begin FW_greeting_N_niceshort doOncefloat timerif ( doOnce == 0 )    if ( ( GetDistance player ) < 150 ) ; this may be too close        set doOnce to 1        AIFollow player 0 0 0 0    endifelseif ( doOnce == 1 )    set timer to ( timer + GetSecondsPassed )    if ( timer < 1 )        return    else        set timer to 0        set doOnce to 2        say "vo\N\m\Hlo_NM135.mp3" "Hail and welcome friend, hail!"    endifelseIf ( doOnce == 2 )    if ( SayDone == 1 )        set timer to ( timer + GetSecondsPassed )        if ( timer < 2 ) ; delay before second greeting            return        else            set timer to 0            set doOnce to 3            say "vo\N\m\Idl_NM001" "What makes this smell?"        endif    endifelseIf ( doOnce == 3 )    if ( ( GetDistance player ) > 500 )        set doOnce to 0    endifendifEnd FW_greeting_N_nice

Here is a version script for an NPC that has an AIWander package.

Begin FW_greeting_N_nice_Wshort doOncefloat timershort wanderingNPCif ( doOnce == 0 )    if ( ( GetDistance player ) < 150 ) ; this may be too close        if ( GetCurrentAIPackage == 0 ) ; wandering            set wanderingNPC to 1        endif        set doOnce to 1        AIFollow player 0 0 0 0    endifelseif ( doOnce == 1 )    set timer to ( timer + GetSecondsPassed )    if ( timer < 1 )        return    else        set timer to 0        set doOnce to 2        say "vo\N\m\Hlo_NM135.mp3" "Hail and welcome friend, hail!"    endifelseIf ( doOnce == 2 )    if ( SayDone == 1 )        set timer to ( timer + GetSecondsPassed )        if ( timer < 2 ) ; delay before second greeting            return        else            set timer to 0            set doOnce to 3            say "vo\N\m\Idl_NM001" "What makes this smell?"        endif    endifelseIf ( doOnce == 3 )    if ( ( GetDistance player ) > 500 )        if ( wanderingNPC == 1 )            set wanderingNPC to 0            AIWander 2000 5 0 60 20 10 10 0 0 0 0        endif        set doOnce to 0    endifendifEnd FW_greeting_N_nice_W

The problem with this script is not all NPCs have the same wander distance and it is not possible to detect that distance via script. Therefore you may want to have different versions for different wander distances. Add the appropriate version of the script after checking the receiving NPC's AI settings in the construction set. If you take that approach, there is really no need to have the script detect if the NPC is wandering. You would already have firmed that after checking their AI package in the construction set to assign the appropriate script (wander distance).

Begin FW_greeting_N_nice_2000; for NPCs with AIWander 2000 5 0 60 20 10 10 0 0 0 0short doOncefloat timerif ( doOnce == 0 )    if ( ( GetDistance player ) < 150 ) ; this may be too close        set doOnce to 1        AIFollow player 0 0 0 0    endifelseif ( doOnce == 1 )    set timer to ( timer + GetSecondsPassed )    if ( timer < 1 )        return    else        set timer to 0        set doOnce to 2        say "vo\N\m\Hlo_NM135.mp3" "Hail and welcome friend, hail!"    endifelseIf ( doOnce == 2 )    if ( SayDone == 1 )        set timer to ( timer + GetSecondsPassed )        if ( timer < 2 ) ; delay before second greeting            return        else            set timer to 0            set doOnce to 3            say "vo\N\m\Idl_NM001" "What makes this smell?"        endif    endifelseIf ( doOnce == 3 )    if ( ( GetDistance player ) > 500 )        set doOnce to 0    endifendifEnd FW_greeting_N_nice_2000

None of these scripts have been tested.
User avatar
Nina Mccormick
 
Posts: 3507
Joined: Mon Sep 18, 2006 5:38 pm

Post » Sat May 28, 2011 4:17 am

Hey cyran0, thank you so much (again)! I very much appreciate you taking the time to do this. I will test these out and report back. Thanks again!
User avatar
Chris Duncan
 
Posts: 3471
Joined: Sun Jun 24, 2007 2:31 am

Post » Sat May 28, 2011 5:50 am

Hey cyran0,

I finally got around to testing your scripts in-game, and the second one is very close to what I want, with one exception: I only want the NPC to say one line of dialogue. I tried modifying it myself, but I did something wrong and he keeps reciting the line over and over until I walk away. Here is the script:
Begin FW_greeting_N_nice_W1        short doOnce    float timer    short wanderingNPC        if ( doOnce == 0 )        if ( ( GetDistance player ) < 200 ) ; increased from 150 (too close)            if ( GetCurrentAIPackage == 0 ) ; wandering                set wanderingNPC to 1            endif            set doOnce to 1            AIFollow player 0 0 0 0        endif    elseif ( doOnce == 1 )        set timer to ( timer + GetSecondsPassed )        if ( timer < 1 )            return        else            set timer to 0            set doOnce to 3            say "vo\N\m\Hlo_NM135.mp3" "Hail and welcome friend, hail!"        endif    elseIf ( doOnce == 3 )        if ( ( GetDistance player ) > 50 ) ; decreased from 500 to prevent stalking            if ( wanderingNPC == 1 )                set wanderingNPC to 0                AIWander 2000 5 0 60 20 10 10 0 0 0 0            endif            set doOnce to 0        endif    endif    End FW_greeting_N_nice_W1


I also increased the GetDistance at the beginning (as you suggested) to trigger the dialogue from a little further away, and I also decreased the GetDistance near the end of the script, as I think this (or something in there) was turning the NPC into a stalker. Particularly with the 2000 version (your third script), the NPC would recite his lines properly, but then keep following me all over town. Anyway, I don't know if decreasing the GetDistance to 50 is what did the trick, but there is no stalking when using the altered script above. Just the repeating dialogue. Would you mind taking a look and finding what I did wrong? Many thanks!
User avatar
Latino HeaT
 
Posts: 3402
Joined: Thu Nov 08, 2007 6:21 pm

Post » Sat May 28, 2011 3:26 am

and I also decreased the GetDistance near the end of the script, as I think this (or something in there) was turning the NPC into a stalker.
That's the reason you get the line being told over and over. Previously you'd get reset to the starting point only when the NPC gets away far enough, now you get it while conditions are matched to launch the sequence once again immediately. If you want to keep no-stalking function, modify the script like this:
...    elseIf ( doOnce == 3 )        if ( ( GetDistance player ) > 50 ) ; decreased from 500 to prevent stalking            if ( wanderingNPC == 1 )                set wanderingNPC to 0                AIWander 2000 5 0 60 20 10 10 0 0 0 0            endif            set doOnce to 4 ; stop following, but don't check for vicinity yet        endif        elseIf ( doOnce == 4 )        if ( ( GetDistance player ) > 500 ) ; NOW you can reset            set doOnce to 0        endif    endif    End FW_greeting_N_nice_W1

User avatar
stevie critchley
 
Posts: 3404
Joined: Sat Oct 28, 2006 4:36 pm

Next

Return to III - Morrowind