Author Topic: Making NPC speak while walking between waypoints.  (Read 612 times)

Legacy_Zeke

  • Jr. Member
  • **
  • Posts: 86
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« on: November 14, 2015, 04:54:02 pm »


               

Hi there,


 


I can't seem to figure out how can I make an NPC waypoint walk and say something.


 


I'm trying to use on heartbeat event but it doesn't work flawlessly.


 


I'm attaching the following script onUserDefined:



#include "X0_INC_HENAI"

int nCalledBy = GetUserDefinedEventNumber();
void main()
{
    switch(nCalledBy)
    {
        case 1001: //OnHeartbeat
            ClearAllActions();
            ActionSpeakString("Ah, I'm bored...");
            ClearAllActions();
            DelayCommand(0.5f, WalkWayPoints());
            break;
    }
}

What is the best way that this can be handled?



               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #1 on: November 17, 2015, 09:11:52 am »


               

If you are focusing on a cinematic appearance - then you need to consider using more controllable means of triggering the dialog.


 


Eg:


Simplify your script - and tell the creature to JUST walk between the waypoints.


 


Then, at the positions where you want the creature to speak -  place triggers.


When the creature walks over the trigger : in the onEnter event.


object oCreature = GetEnteringObejct();


 


then tell oCreature to SpeakString - to say the things you want him to say.


 


This way, he will speak exactly at the right position you need.


The trigger script should be configured to fire just for the creature you intend.



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #2 on: November 17, 2015, 12:48:15 pm »


               

Also, the second ClearAllActions is unwanted, because it cancels the ActionSpeakString.


 


A more subtle issue is that the default OnHeartbeat script calls WalkWayPoints, which will move on if it finds the NPC is no longer walking. It's possible that this will interrupt other actions you assign to the NPC OnUserDefined. The only safe way I know to fix that is to modify the OnHeartbeat script itself, 



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #3 on: November 17, 2015, 02:08:25 pm »


               

Baaleos's suggestion can work nicely if you are in a limited area and path.  Proleric is spot on about the ClearAllActions.


 


One thing you could try is to let the heartbeat as is handle the walking part. It already does that, Then in your userdefined you could do something like :



case 1001: //OnHeartbeat
            switch(Random(3)) {
            case 0: DelayCommand(1.5, SpeakString("Ah, I'm bored...")); break;
            case 1: DelayCommand(2.5, SpeakString("La la la...")); break;
            case 2: // left this on blank so it does not speak every time
            }
            break;


               
               

               
            

Legacy_Zeke

  • Jr. Member
  • **
  • Posts: 86
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #4 on: November 17, 2015, 06:34:26 pm »


               

Hmm, why 



ActionSpeakString("Ah, I'm bored...");

and



AssignAction();

is not working, but



DelayCommand(0.0, SpeakString("Ah, I'm bored..."));

as @meaglyn said, is working?



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #5 on: November 17, 2015, 06:43:02 pm »


               

Actions go in the action queue, which can get cleared before they execute. ClearAllActions() for example.


 


SpeakString is not an action. It happens immediately regardless of the state of the action queue.


 


The Delays I put there are just to make it not fire exactly on the HB.  It should work without them as well.


               
               

               
            

Legacy_Zeke

  • Jr. Member
  • **
  • Posts: 86
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #6 on: November 17, 2015, 10:53:12 pm »


               

Thanks! 


 


And how can I target the bored NPC from an outside script, as SpeakString() is getting the owner of the script?


 


I know about AssignCommand() but as was said, it doesn't seem to work when an NPC is following checkpoints.



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #7 on: November 17, 2015, 11:43:20 pm »


               

AssignCommand(oNPC, SpeakString("foobar"));  from other scripts should work as well as long as you can get the reference to the right object.  That should not conflict with walking waypoints either. Just don't use  AssignCommand(oNPC, ActionDoCommand(SpeakString("foobar"))); Because that will put it on the action queue.   If that's not working post the code you have that's not working. 



               
               

               
            

Legacy_LoA_Tristan

  • Jr. Member
  • **
  • Posts: 64
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #8 on: November 17, 2015, 11:49:48 pm »


               

if this just a question of retrieving the object, you could set the bored npc as a local object on the module (so it can be called up from anywhere without a mess of code)


 


the final line in the outside script would be something like


 


AssignCommand(GetLocalObject(GetModule(), "BORED_GUARD"), SpeakString("Ah, I'm bored..."));



               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #9 on: November 20, 2015, 04:24:56 pm »


               

The thing to remember here is that npcs seem to be only able to act on a single action at a time.


(Ala  - the Action Queue)


 


While they are 'walking' this is an action.


When you ask them to speak, that is another action - which goes to the bottom of the queue, or at best, behind the current action.


 


ClearAllActions will allow you to clear out the action queue and put something first in line to be acted upon, but it has the side effect of interrupting the walk action.


Eg: They may stop walking momentarily to deliver their SpeakString.


Im not sure  - but I guess with this logic, even my earlier suggestion of using a trigger, would be at the mercy of the Action Queue.


The trigger would at most be able to add to the end or add a new action behind the current action.


ClearActions would be needed for trigger based scripting too.


 


It might be a little too complex for what is needed, but I am reasonably sure that nwnx would be able to get around this issue. (nwnx_chat ?)


Eg: It could send the chat message - using the NPC as the speaking object.


Because it is bypassing Action Queue - it would not require ClearActions


Since your not relying on the Creature actually speaking, instead its the server speaking, just changing the object ID to the creature.


So the creature would in effect be able to talk and walk at the same time.


 


At least, that is my theory 



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #10 on: November 20, 2015, 04:46:53 pm »


               

SpeakString is not an action. It should not stop them from doing whatever action they are currently working on.  ActionSpeakString is an action and will go in the queue.



               
               

               
            

Legacy_LoA_Tristan

  • Jr. Member
  • **
  • Posts: 64
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #11 on: November 21, 2015, 01:52:08 am »


               

There are some Actions that are masquerading around as instant commands, though.  Like the function PlaySound().  It gets put in the action queue.



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #12 on: November 21, 2015, 04:41:36 pm »


               


There are some Actions that are masquerading around as instant commands, though.  Like the function PlaySound().  It gets put in the action queue.




 


True, but SpeakString is not one such. 



               
               

               
            

Legacy_Zeke

  • Jr. Member
  • **
  • Posts: 86
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #13 on: November 22, 2015, 01:13:39 pm »


               

Thanks for the answers. I'm beginning to understand the Action Queue.


 


Is it global or per character? I mean, if I want to issue a command to an NPC to go and talk to the bored one (Bob) like this



AssignCommand(oJohn, ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL));
AssignCommand(oJohn, ActionSpeakString("Hi there!"));

Bob starts talking the moment that John starts walking towards him.


 


Why ANIMATION_LOOPING_TALK_NORMAL is stopping? Can it continue while the NPCs are interacting?



               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Making NPC speak while walking between waypoints.
« Reply #14 on: November 22, 2015, 05:10:06 pm »


               

The action queue is per object.


Is one of those lines meant to be on Bob? they are both on John.


When John clicks/interacts with Bob, it will interrupt any action he is currently doing - I think.


This will then make the next item in the action queue fire.


 


The more absolute way to manage actions, is with DelayCommand - it means you need to worry about delays, and absolute timings.


Opposed to waiting for one object to finish an action then continuing on with another.