Another Conversation Animation Question (Prevent PC Running To NPC)

Hi All,

@andgalf - I’m not sure if this was covered with one of your own questions, but draw your attention to this question just in case.

Anyway, this is another one of those issues that goes right back to first ever owning NWN2 - Is there a simple means by which (when initiating a normal conversation by simply left clicking on a creature) we can stop the player running up to the NPC and, instead, just have the conversation start at their current location?

I am looking for something similar to the “ignore distance” parameter in the ActionStartConversation function, which can be applied from a simple left-click on an NPC when the talk bubble appears.

I even tried looking through the XML to see if I could work out if I could apply some some sort of intercept code from the contextmenu.xml, but failed to have any gui callback work. Has anybody else perhaps tried this and succeeded? What about any kind of success in getting some gui callback from simply hovering over an NPC that makes the “talk” bubble appear? That may also be a start for me to work with.

I am just looking for a sure fast way to allow a PC to start a conversation with an NPC from the other side of a bar or table. NB: I know initial cutscenes can be easily worked to do this, but outside of a cutscene, I see no easy way to have the PC not run around said desk, table or bar in an effort to talk with the NPC only just across from them.

Maybe I am missing something obvious, such as a “distance” setting or changing something in a 2da, but I am currently at a loss as to how to address this. (Note: My campaign setting is set at 20 already, which only affects the scripted conversations anyway.)

Any help or guidance appreciated.
Thanks, Lance.

I don’t know if this is what you’re after, Lance, but in my inns in ASW3 and ASW4 I use a script by kevL_s that kind of do something like this when talking to the bartender. Not sure if that is what you’re after though. I could post the script here if you want.

By the way, I think you have a typo in one of the lines at the top of your post: “…stop the player running up to the PC and instead…”

1 Like

@andgalf,

(Hopefully that sentence in my post reads better now.)

Anyway, I would certainly welcome taking a look at the script KevL did for you. :slight_smile: It may be just the trick I need. I am hoping to add some kind of functionality that allows better control of when a PC moves or not.

I’ll keep an eye open for your posted script and let you know if it is something I can use/work with in the way I am hoping to.

Thanks, Lance.

Regarding the typo, don’t you mean: “…stop the player running up to the NPC and instead…”

Ok. Here’s the script:

// 'oc_bartender'
/*
    OnConversation script for innkeeper. Script by kevL_s.
*/

const string TAG_WAYPOINT = "e_inkwp";
const float  DEFAULT_DIST_DIALOG = 2.f;

void BeginDialog(object oSpeaker);


// OBJECT_SELF is innkeeper
void main()
{
    object oPc = GetLastSpeaker();

    if (GetDistanceToObject(oPc) > DEFAULT_DIST_DIALOG)
    {
        AssignCommand(oPc, ClearAllActions());

        object oWaypoint = GetNearestObjectByTag(TAG_WAYPOINT);
        AssignCommand(oPc, ActionMoveToObject(oWaypoint, TRUE, 0.f));

        object oSpeaker = OBJECT_SELF; // req'd - do not put OBJECT_SELF directly into the next call
        AssignCommand(oPc, ActionDoCommand(BeginDialog(oSpeaker)));
    }
    else // standard start conversation ->
    {
        ClearAllActions();
        BeginConversation();
    }
}


// OBJECT_SELF is pc here
void BeginDialog(object oSpeaker)
{
    ClearAllActions();
    SetFacingPoint(GetPosition(oSpeaker));

    object oPc = OBJECT_SELF; // req'd - do not put OBJECT_SELF directly into the next calls

    AssignCommand(oSpeaker, ClearAllActions());
    AssignCommand(oSpeaker, SetFacingPoint(GetPosition(oPc)));

    AssignCommand(oSpeaker, ActionStartConversation(oPc));
}

@andgalf,

TYPO: Ah! I see what you mean now … Blind to my own text again.

Thanks for posting the script. I will look over it and come back to you.

EDIT: Interestingly, it looks like a substitution using ActionStartConversation (which I tired already), but I am having one of those days - so maybe it will do exactly what I was after. I am just finishing off an email, then can double check.

Thanks, Lance.

Looking at the script now, I realize that this might not be what you’re after. This script prevents the player from running to the bartender but doesn’t start the dialogue until you’re close enough…I think.
I also know I’ve placed walkmesh cutters so that the PC can’t move around the bar and get to the bartender that way…Anywho…maybe you can still use some of the ideas kevL_s had for this, I don’t know.

1 Like

Here’s a different solution to the bar problem. Make a bar and leave a gap so it doesn’t surround the landlord/ barmaid. Put an invisible collision box in the gap and stretch it so that it fills the gap. This makes the walkmesh all join up and prevents the bar staff from not wanting to be there and freaking out as they try to escape.

Now you can talk to people behind the bar from a distance and not try and join them. If you’re likely to fight with them at some point name the tag of the collision box and destroy it when everything goes wild or in some cases when I didn’t know when it might happen I made a usable/ smashable section of bar with dynamic collisions so you can destroy it and get behind there.

3 Likes

@andgalf
@Tsongo,

Sorry about the delay in responding, I had to attend a meeting.

Sadly, this is the problem I am having … The meeting stopped me from taking a closer look at the script - and so will look again now. You never know, maybe there is something I missed there. I will let you know shortly.

EDIT: Sadly, the script does the same as mine (after editing it slightly for the ignore distance), not overriding the default run to. I will keep searching.

I believe any success would be one of those rather helpful discoveries for builders all round.

Thanks for the suggestion. (I may have to do something like this if all else fails.) However, I was trying to avoid having to implement special formats to make this work, as I do not know when or how the situation will be needed in some situations.

Example: I have a cutscene where a PC speaks to an NPC who is behind a desk, and after the conversation ends, the player can click on the NPC to continue speaking. Unfortunately, said PC then decides to run off around the circle of tables, gets half way, decides they may be going the wrong way, turns back, changes mind on the return and so goes back again - gets half way, rinse and repeat.

I managed to get around the back and forth by changing the walkmesh structure (although it is not obvious how this had any bearing), but the PC still runs around all tables to get to the position of speaking.

And the point I am struggling with, is that the OnConversation hook does not fire (in testing so far) until the PC is within a few feet of the NPC. i.e. I cannot intercept the conversation pending action, even if the GetCurrentAction reports the pending action (7). Currently, I could have a “random” heartbeat detection, but we would be subject to up to six second variation on it eventually firing. :neutral_face: That’s why if I could intercept the XML click, I may be able to do the distance or variable check from the gui callback at that point to determine if the conversation is to fire immediately or not.

Hi All,

OK, I realised/remembered that I do have a access to a more rapid system wide heartbeat that my campaign uses, which I may be able to take advantage of to override the original function call. It reduces the random time to half a second (the rate I have set the function call), but that may be quick enough to accommodate the means of starting the conversation ignoring distance.

I am also considering one other means of checking via another gui script, which I believe may fire even more frequently at 0.2 seconds. I will check if that is available as I thought and see if adding any other checks to it causes any overhead.

I will report back (EDIT) here if it works.

@Lance_Botelle

this modified version of script above worked for me – conversation started from across a room – no movement. The action queue simply blipped and then the dialog started

// 'oc_standstartdialog'
/*
    OnConversation script that starts a dialog from any reasonable distance.
*/

void BeginDialog(object oSpeaker);

// OBJECT_SELF is Speaker
void main()
{
    SendMessageToPC(GetFirstPC(FALSE), "oc_standstartdialog");

    ClearAllActions();

    object oPc = GetLastSpeaker();
    AssignCommand(oPc, ClearAllActions());

    object oSpeaker = OBJECT_SELF; // req'd - do not put OBJECT_SELF directly into the next call
    AssignCommand(oPc, BeginDialog(oSpeaker));
}

// OBJECT_SELF is pc here
void BeginDialog(object oSpeaker)
{
    SetFacingPoint(GetPosition(oSpeaker));

    object oPc = OBJECT_SELF; // req'd - do not put OBJECT_SELF directly into the next calls
    AssignCommand(oSpeaker, SetFacingPoint(GetPosition(oPc)));
    AssignCommand(oSpeaker, ActionStartConversation(oPc, "", FALSE, FALSE, TRUE, FALSE));
}

@kevL_s,

At a quick glance, that looks very much like what I did with the above script of yours, even where I updated the ActionStartConversation parameters to ensure distance ignored. :astonished:

I will test it immediately and report back.

One minute. …

EDIT: OK, I tested that script as it stands and unfortunately it still did not work …

The problem is, (as it appears to me) the OnConversation does not even fire to employ this script update because the PC is still running around the tables to be able to start the conversation.

I have my campaign setting at 20, which is (as far as I know) meant to mean metres, but I am trying to start the conversation at 18 feet.

are there Campaign settings that can affect dialog and dialog distance …?

yep: “ConversationDistance”

(i don’t know what it really means tho)

 
[edit]
blargh
‘oc_standstartdialog’ works in Module1 w/out campaign

i thought a Campaign might hinder it, so tried it in Module2 w/ campaign where it didn’t work
then created Module3 w/out campaign where it also didn’t work

went back to try it in Module1 again where it still works (up to ~10 meters beyond which I get the message “Object is too far away to talk to”)

/blargh

1 Like

Oh Wow! :astonished: That is the first real scripting difference I have witnessed between single module and campaign! That is quite something!

So that may mean I am going to have to try to make the detection via a rapid heartbeat ref if possible. The trick will be to try to make it efficient enough not to impact the rest.

Unless you are able to determine any kind of gui feedback from a context menu call, or maybe target ref … I could not get any, but could easily have missed something - it’s been that kind of day.

not so hasty, Lance:

Module3 was also without campaign … it didn’t work there just like it didn’t work in Module2 with campaign. So unless there’s some property i messed up idk

it worked only in Module1 … for whatever reason

 
[edit]
while there might well be something about the game needing to read the .CAM file that changes the behavior of dialogs (especially with that “ConversationDistance” setting there)

my tests weren’t proof of it …

1 Like

And I just thought I had misread you! I mean I read what you wrote about module 3, but could not see how that was even possible - and so my brain fogged it over … Doh! :face_with_raised_eyebrow:

So where does that leave us then?

I mean if you are able to discover it, all the better, as I was not wanting to “rupture” my mapping heartbeat if I could help it. - Currently testing that path now, but would prefer a more distinct route if possible.

EDIT: Messing with the map functions is too messy, so I am going to look at using my updatetargets callback, which I can make use of outside of combat, which has rapid callback. I will try applying the same test/principle through its check.

you could set up a pseudoHB on/for the PC in that area … but what are you thinking of then checking for … to get a positive evaluation that, yes, PC has clicked on NPC and is moving ?

@kevL_s,

In a test using just the normal heartbeat I was able to have GetCurrentAction return 7 (ACTION_DIALOGOBJECT) after clicking on the NPC to talk. The problem was (obviously) any checks I made to check for this via the six second heartbeat were taking far too long to be acted upon.

Thankfully, I remembered I already have some more rapid “global” heartbeats going on for (a) mapping function and (b) turn-based info. The former fired every 0.5 second, but only when certain conditions were met, which became fiddly to accommodate the changes. The latter, however, I may be able to take advantage of, as it still fires out of combat, and does nothing at the moment when out of combat. Therefore, I can make use of its rapid (0.1 second update) to (hopefully) detect the conversation state requirement on any PCs. However, I may add some delays within this to slow it down a bit as I don’t really want to have to cycle all faction members every 0.1 second all the time. I reckon I could also just have it fire when a global var is set and we are out of combat when I use it for other reasons (and no conversation checks required there anyway).

Hopefully, this can resolve the issue once and for all. Single module or campaign combo!

Sadly, I will have to leave testing until tomorrow now though, as it is late and I need sleep. Brain has made some bad judgements today. I don’t want to add that to module. :slight_smile:

PROOF OF CONCEPT:-

1 Like

Can you be certain that ‘dialogobject’ is indeed that NPC? ie, not a companion, nor a different NPC?

1 Like

That’s the bit I need to work on further … I am hoping retrieving the correct NPC will be achievable, but I have to be honest and say that I am not entirely confidant at this stage.

Hopefully, I will have more by tomorrow.

If you have anything between now and then based on the current action concept, then it would certainly save me some time. :+1: :wink:

EDIT: That is why I had hoped it also possible to intercept the gui callback somewhere.

I will check back here tomorrow - Good night for now. :sleeping:

1 Like

tried the pseudoHB, but didn’t find a way to get the NPC-speaker.

( and I’m still puzzled why it SEEMS that under some circumstances the engine fires OnConversation before PC starts moving … it does for my bartender and for @andgalf’s bartender, but not when I plop down an NPC in the middle of a room or something sry am at a loss here )

 
unfortunately i don’t think you can make a callback by clicking on an NPC either :\

idea
- teleport PC out of the area after the 1st dialog ends /heh

1 Like