Jump to content

coordinating multiple NPC actions?


davidlallen

Recommended Posts

For the big final scene in my quest mod, I have three NPC's I need to do certain things in a certain order. I have tried a few things related to adding packages and quest variables, but I can't seem to make it work. Perhaps I am using the wrong approach, but I cannot think of one which is easier. Can anybody suggest a better way?

 

Here is my list of stage directions.

1. NPC1 force greets me outside a door, then walks through the door

2. I walk through the door and see all three NPCs standing in a circle

3. NPC2 performs two particular animations

4. NPC1 performs two particular animations

5. All three NPCs now go back to their regular lives

 

Using enough different packages, I can get this to partly work except that most of the NPC's keep sandboxing away when they are supposed to be waiting. The number of packages seems to be getting too large so there must be an easier way, which would work.

 

I have defined a helper quest with stages 1...5 matching the above steps.

 

The force greet is done with a cubic trigger which does:

StartConversation player topic

setstage quest 2

NPC2.moveto

NPC3.moveto

 

NPC1 has the following packages:

1a. Travel. Condition (getstagedone quest 2) && (getstagedone quest 3 == 0). End script "setstage quest 3".

1b. Guard in place. Condition (getstagedone quest 3) && (getstagedone quest 4 == 0).

1c. Travel in place. Condition (getstagedone quest 4) && (getstagedone quest 5 == 0). Idle tab has the two animations with "run once" and "run in order". End script "setstage quest 5"

1d. Sandbox. Condition (getstagedone quest 5) or (getstagedone quest 2 == 0)

 

NPC2 has the following packages:

2a. Guard in place. Condition (getstagedone quest 2) && (getstagedone quest 3 == 0).

2b. Travel in place. Condition (getstagedone quest 3) && (getstagedone quest 4 == 0). Idle tab has the two animations listed with "run once" and "run in order". End script "setstage quest 4".

2c. Guard in place. Condition (getstagedone quest 4) && (getstagedone quest 5 == 0).

2d. Sandbox. Condition (getstagedone quest 5) or (getstagedone quest 2 == 0)

 

NPC3 has the following packages:

3a. Guard in place. Condition (getstagedone quest 2) && (getstagedone quest 5 == 0)

3b. Sandbox. Condition (getstagedone quest 5) or (getstagedone quest 2 == 0)

 

Did I mention this is complicated? Package 1a moves NPC1 into position and advances to step 3. Package 2b plays NPC2's animations and advances to step 4. Package 1c plays NPC1's animations and advances to step 5. When not doing animations, they should have guard animations. Before and after the scene, ONLY, all three should sandbox.

 

I'd like to add dialog, but that would double, or square the complexity. If I can get a system which works without being so complex, I can probably work out how to add the dialog later.

Link to comment
Share on other sites

I think package 1c and 2b are setting stages before the idles are over, because a travel package ends when it reaches the destination.

The way I would approach this, though it's probably not the only way, is add a quest script to monitor certain things - like the idles playing, or even use it to play the idles on the NPCs when the travel package end script flags a quest variable, instead of having the idles in the package. Then set stages as appropriate.

 

Also in the quest script you can put Sayto's for dialog at the appropriate points.

Link to comment
Share on other sites

I'm having some trouble understanding which things should be in packages, which in quest stages, and which in scripts. Since scripts trigger each frame, you can't do much sequencing in a single script; it will be a big switch statement based on some state variable. So using quest stages seems just as good.

 

I will try as a quest script to learn more.

 

How can I tell in a script, whether an idle is done? I can tell whether a topic is done speaking using "begin saytodone topic". I can start an idle using playidle, but assuming I only use non-looping ones, I need to know when it's done. IsIdlePlaying is the opposite function; I don't want to busy wait until the idle is done, but maybe that is the only way.

 

Should I even be using raw idles, or is it typical to bind these into some kind of spell effect or something? I need to use a couple of the workshop animations, and also (I suppose it is a spoiler) a "die" animation.

 

How can I start an NPC moving towards a target using a script? Does this have to be a package? Moveto teleports.

 

How do I prevent an actor from moving? I have tried a "guard" package with the same NPC location and guard location and radius 0. This seems to work, but I need a bunch of different packages for each NPC and each guard point. I have found "setrestrained" as a script command, which I can try out.

 

I'm fairly sure I've gone past the point where existing tutorials help, but if there is any resource I can read to learn more about coordinating multiple NPC's, please let me know.

Link to comment
Share on other sites

I'm having some trouble understanding which things should be in packages, which in quest stages, and which in scripts. Since scripts trigger each frame, you can't do much sequencing in a single script; it will be a big switch statement based on some state variable. So using quest stages seems just as good.

 

I will try as a quest script to learn more.

 

Many times you see a quest script as the over-all controller for setting stages and checking conditions. A quest script by default only runs every 5 seconds so there are many frames in between each iteration. You can adjust this delay depending on what you want to do. Object and Effect scripts run every frame.

 

How can I tell in a script, whether an idle is done? I can tell whether a topic is done speaking using "begin saytodone topic". I can start an idle using playidle, but assuming I only use non-looping ones, I need to know when it's done. IsIdlePlaying is the opposite function; I don't want to busy wait until the idle is done, but maybe that is the only way.

 

Scripts don't make the engine wait, unless you are doing an NVSE loop/goto. So you have to set the structure up in stages to do complicated things with timing involved.

 

 

;Quest delay of .016 sec, or do this on the object script

short iIdleStage
float fTimer


if (fTimer <= 0)
 if (iIdleStage == 1)
  MyNPC.PlayIdle LooseLazySalute
  set iIdleStage to 2
  set fTimer to .25 ;allow time for idle to start
 elseif (iIdleStage == 2)
  if (MyNPC.IsIdlePlaying)
  else
   set iIdleStage to 3
   set fTimer to .5
  endif
 elseif (iIdleStage == 3)
  set variables to make my NPC do something else, or nothing
 endif
else
 set fTimer to fTimer - GetSecondsPassed
endif

 

Should I even be using raw idles, or is it typical to bind these into some kind of spell effect or something? I need to use a couple of the workshop animations, and also (I suppose it is a spoiler) a "die" animation.

 

You can generally use them. Just check to make sure that any conditions on them are going to be met, and that they are a 'special idle'.

 

How can I start an NPC moving towards a target using a script? Does this have to be a package? Moveto teleports.

 

It's a regular AI package. If you don't want to put it in the NPC object, you can use the addscriptpackage function. You shouldn't be too concerned about how many packages you need on an NPC. The NPC in my companion mod has 47 packages on her NPC object. Plus many packages that are only used through scripting.

 

MyNPC.AddScriptPackage TravelToXMarker1

 

How do I prevent an actor from moving? I have tried a "guard" package with the same NPC location and guard location and radius 0. This seems to work, but I need a bunch of different packages for each NPC and each guard point. I have found "setrestrained" as a script command, which I can try out.

 

Usually a guard package. Take a look at one of the follower's wait packages. When you tell them to wait, they don't move. You can have your NPC travel to an XMarker, then wait.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...