I have a tavern where the innkeeper is standing behind the bar counter. It is totally possible to talk to him by standing on the other side, but more often than not, if you click on him, the PC always seem to prefer going around the bar counter to talk to him. Would it be possible, through scripting perhaps, to force the PC to go in front of the counter when initializing a dialog? Maybe put something in OnConversationScript of the character? Or maybe this is hardcoded and impossible?
well,
try an invisible* blocking object behind the counter, where the PC usually ends up at ā¦ this might be enough to force pathfinding to use the spot in front of the counter.
or ā¦
EDIT: dang this next isnāt as straightforward as I thought itād be ā the PC runs up to the NPC before the OnConversation event fires.
dialog with an NPC can (indeed) be āinitializedā in the NPCās OnConversation event script (default: ānw_c2_default4ā). I suppose a custom handler could be written that checks if the PCSpeaker is close enough. Put a waypoint in front of the counter. If the PC isnāt close enough, script the PC to move to the waypoint and start the dialog:
AssignCommand(oPC, ActionMoveToObject())
AssignCommand(oPC, ActionStartConversation())
I think you can get the PC w/ GetLastSpeaker() ā¦ no doubt thereād be frustrations to work through but i believe itās possible.
Ā
* it doesnāt have to be invisible ā¦ a chest or whatever that has collision
after mucking around with this for a while
i get the impression that NPCs really donāt like to have dialog over a table ā¦ (unless the PC is already standing right there)
I did, however, wire up a trigger that stops the PC and makes the NPC bark āhey, stay out from behind the bar.ā And then, although I see this as optional, forces the PC to walk out in front of the bar and restarts the dialog.
i tend to think itās enough to just stop the PC with an NPC bark ā it gets the point across, and player can either then choose to continue behind the bar or walk out in front of the bar and try again ā¦
So you donāt think this would work then? You tried it?
I put a couple barrels down y. When i clicked on the NPC, my PC just stood there ~20m away and the dialog started.
this is my test setup
the barrels were placed diagonally out from the corner of the table, so PC couldnāt enter the trigger
and hereās a vid of the trigger in action ā¦
https://drive.google.com/file/d/1JT9O3NpOuXz_wffRBx4AMboq2hdullH7/view?usp=sharing
why not use the conversation distance setting in the campaign editor? drawback is, you have to convert your module into a campaign to use it and it works on every dialogue. soz uses a value of 20.
Well, I think Iāll skip that then, since I donāt want to convert to campaign.
Ok, Iāll test a bit myself then, kevL_s.
I tried with just doing walkmesh cutter behind the counter and that worked pretty well. However, now the conversation begins, or may begin, when the PC and the innkeeper are pretty far from each other, and that looks kind of odd, like theyāre standing shouting to each other for no apparent reason.
I got an idea think Iāll try: Maybe one can write a conditional at the top node of the dialog, and if the PC isnāt close enough, to move the PC in place to start the conversation?
Hmm. I tried this but my PC wonāt move. I placed the first script below on the first node on conditions, and the second script on the second node on actions - of the conversation of the innkeeperās conversation, so that the last node has the move-script.
Then below that I put the ārealā conversation so to speak.
int StartingConditional()
{
object oPC = GetPCSpeaker();
object oInnkeeper = GetNearestObjectByTag("taw_innk",oPC);
if(GetDistanceToObject(oPC) >4.0f)
{
return TRUE;
}
else
{
return FALSE;
}
}
void main()
{
object oPC = GetPCSpeaker();
object oWP = GetNearestObjectByTag("d_inkwp",oPC);
object oInnkeeper = GetNearestObjectByTag("taw_innk",oPC);
AssignCommand(oPC, ActionMoveToObject(oWP));
AssignCommand(oPC, ActionStartConversation(oInnkeeper));
}
I tried changing oPC to GetFirstPC also but with the same result. The dialog just goes through a neverending loop since the PC wonāt move.
your reply gave me the notion to go back to the OnConversation handler.
// 'oc_bartender'
/*
OnConversation script for innkeeper.
*/
const string TAG_WAYPOINT = "d_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));
}
The dialog has nothing special in its events. The innkeeper doesnāt say hello (unless PC is already close enough). If the PC is farther than ~15 meters away, player gets an āobject is too far away to talk toā message.
it looks/plays really quite good here ā¦
Ā
edit: make sure that the distance between the innkeeper and the waypoint is kept less than DEFAULT_DIST_DIALOG
edit2: all this relies on the innkeeper being ātrappedā behind the walkmesh-cutter
Just tried out your script ingame. It worked flawlessly! Thank you so much!
I still donāt understand why my second script didnāt work though. Maybe it has something to do with float range in ActionMoveToObject?
By the way, I do not fully understand what you mean by ādo not put OBJECT_SELF directly into the next call/callsā
Edit: I tried it in my other inn as well (Iāve got two in this module) and it worked splendidly there as well. Iām suprised how pleased I am to see the PC speaking to the bartender/innkeeper without running around the counter. I donāt think I realized how much this has annoyed me before. So again, kevL_s, thank you for all your help!
i donāt know either. The only thing that stands out is that this
AssignCommand(oPC, ActionStartConversation(oInnkeeper));
is usually
AssignCommand(oInnkeeper, ActionStartConversation(oPC));
but it could be, you know, just dialog intricacies
Because those next calls are being Assigned to a different actor ā¦
eg. This would pass āoPcā (the assignee) into the BeginDialog() funct. (instead of āoSpeakerā)
AssignCommand(oPc, ActionDoCommand(BeginDialog(OBJECT_SELF)));
i did ā¦ Pc always runs behind the counter and i think āyou j*rkā ā¦ so yeh, itās a neat little fix/workaround i guess :)
+1