Conversation owner not turning

I’m having a quandary with a script in a conversation:

void main()
{
    object oFake = OBJECT_SELF;
    object oReal = GetNearestObjectByTag("q2d_halas2");
    AssignCommand(oReal, SetFacingPoint(GetPosition(oFake)));
    SetFacingPoint(GetPosition(oReal));
}

The last call to SetFacingPoint is not causing the conversation owner to turn and face oReal. I’m not locking the facing, so it is unclear why this is happening. I also tried ga_face_target, but no luck.

Any suggestions?

hey Rj

when i was playing around with dialog scripts (extensively with andgalf recently) I got the impression that the engine has a hard-coded “dialog manager” of some sort – and that one of its duties is to set Speaker’s facing on each node after action/conditional scripts fire. (also the Listener’s or PCSpeaker’s facing etc). iirc, a script can subsequently force the Speaker’s facing if you wrap SetFacingPoint() in a DelayCommand()

that is, let the engine set the speaker’s default facing, then force the facing to a different point when the delayed command runs a splitsecond later,

at least this worked for generic listeners and speakers, I didn’t try it for the dialog owner itself … /she was incapacitated.

1 Like

Hi,

Basically, just to reiterate what KevL said. Use a slight delay due to system automatically setting direction on node at the same time. You want to make your choice take effect just after the automatic one.

Cheers, Lance

Okay I’ll give that a shot. I actually though there might be an option to set the speakers facing in the options, but I couldn’t find one. Thanks.

Ed.: Nope, that didn’t work.

void main()
{
    object oFake = OBJECT_SELF;
    object oReal = GetNearestObjectByTag("q2d_halas2");
    AssignCommand(oReal, SetFacingPoint(GetPosition(oFake)));
    DelayCommand(0.5f, AssignCommand(oFake, SetFacingPoint(GetPosition(oReal))) );
}

funny, it worked here

void main()
{
//  object oFake = OBJECT_SELF;
//  object oReal = GetNearestObjectByTag("q2d_halas2");
//  AssignCommand(oReal, SetFacingPoint(GetPosition(oFake)));
//  DelayCommand(0.5f, AssignCommand(oFake, SetFacingPoint(GetPosition(oReal))) );


    // Turns first speaker (dialog-owner) to a 3rd party on the pc:"sure ..."
    // dialognode.

    object oMother = GetNearestObjectByTag("d_sicklady");
    if (GetIsObjectValid(oMother))
    {
        object oSelf = OBJECT_SELF; // DialogOwner/1st Speaker tag:d_comwom
        DelayCommand(0.1f, AssignCommand(oSelf, SetFacingPoint(GetPosition(oMother))));
    }
}

I think that “Listener” can be set on each node, for the most part …

Hi,

Strange … Again, as KevL said, it works elswehere … Just a few thoughts …

  1. Did you try the smaller delay of 0.1 instead of 0.5?
  2. Do you have any other animations trying to start on the node you apply the facing?
  3. An obvious, but I’ll ask … The conversation owner is the creature and not an iPoint.
  4. There are no other ClearActions firing on subsequent nodes?
  5. Although you are not locking, apply an unlock function call anyway.

I think the bottom line is that you have to take control of the conversation environment by using more functions than may first be considered due to the game engine “doing stuff” during a conversation. So adding extra functions like orient locks and clearing actions may be required even when we think not.

I’ll keep reading.
Cheers, Lance.

And here is my amended function if you want to try it … Never failed me yet: alb_conv_partytalk

////////////////////////////////////////////////////////////////////////////////////////////////
// FACE SPEAKER CONVERSATION WRAPPER 
// FORCE ALL PARTY MEMBERS TO FACE THE CONVERSATION OWNER (OR sObjTag OBJECT IF SUPPLIED)
// ADDED iNPCFACEPCs PARAMETER TO FORCE NPC TO FACE PARTY (E.g. Sebastion Rewilder in Jail)
// ADDED sObjTagFaces TO FORCE sObjTag TO LOOK AT SOMETHING ELSE (NOW CONV OWNER BY DEFAULT)
////////////////////////////////////////////////////////////////////////////////////////////////

void PartyFaceSpeaker(object oPartyMember, object oSpeaker, string sObjTagFaces);
void PartyFaceSpeaker(object oPartyMember, object oSpeaker, string sObjTagFaces)
{	   	
	vector vTarget = GetPosition(oSpeaker);	
	
	// WHO THE SPEAKER FACES (DEFAULT THE CONVERSATION OWNER)
	object oSpeakerFaces = OBJECT_SELF;
	if(sObjTagFaces != ""){oSpeakerFaces = GetObjectByTag(sObjTagFaces);}
	vector vTargetListener = GetPosition(oSpeakerFaces);
	
	object oFM = GetFirstFactionMember(oPartyMember, FALSE);
	
	while(oFM != OBJECT_INVALID)
	{			
		SetOrientOnDialog(oFM, TRUE);
		
		// ALL PARTY FACE PARTY SPEAKER
		if(oFM != oSpeaker)
		{
			AssignCommand(oFM, SetFacingPoint(vTarget, 1));
		}
		
		else
		{
			AssignCommand(oFM, SetFacingPoint(vTargetListener, 1));
		}
		
		// BUT PARTY SPEAKER STAYS FACING CONV OWNER (AS THEY ADDRESS THEM)
							
		oFM = GetNextFactionMember(oPartyMember, FALSE);
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////
// FACE SPEAKER CONVERSATION WRAPPER 
// FORCE ALL PARTY MEMBERS TO FACE THE CONVERSATION OWNER (OR sObjTag OBJECT IF SUPPLIED)
// ADDED iNPCFACEPCs PARAMETER TO FORCE NPC TO FACE PARTY (E.g. Sebastion Rewilder in Jail)
// ADDED sObjTagFaces TO FORCE sObjTag TO LOOK AT SOMETHING ELSE (NOW CONV OWNER BY DEFAULT)
////////////////////////////////////////////////////////////////////////////////////////////////

void main(string sObjTag = "", int iNPCFACEPCs = 0, string sObjTagFaces = "")
{
	object oPC = GetPCSpeaker();
	object oSpeaker = OBJECT_SELF;	

	// TAG OBJECT OVERRIDE
	if(sObjTag != ""){oSpeaker = GetNearestObjectByTag(sObjTag, oPC, 1);}
	
	// NPC FACE PARTY INTERCEPT
	if(iNPCFACEPCs == 1)
	{
		SetOrientOnDialog(oPC, TRUE);
		vector vTarget = GetPosition(oPC);	
		AssignCommand(oSpeaker, ClearAllActions(TRUE));
		AssignCommand(oSpeaker, SetFacingPoint(vTarget, 1));
	}
	
	// APPROPRIATE DELAY
	DelayCommand(0.1, PartyFaceSpeaker(oPC, oSpeaker, sObjTagFaces));
}
  • Well the delay length doesn’t seem to matter. I started at 0.1f, but that didn’t work.
  • I turned off the conversation’s animation for that step, but it still didn’t work.
  • The conversation is between three characters; no iPoint. One of the characters just arrived via a jump command.
  • The next step in the animation doesn’t run a script.
  • Is there an unlock function? I don’t see any.

I do see a slight twitch as if the character is starting to turn, then it faces back the way it was set as though it was overridden.

Ed.: Okay I found something: when I add a one second delay, the character completes his turn, then turns back after a second.

I got it working using delays and facing locks. Thanks everybody.

1 Like

That’s what I am talking about … :slight_smile:

Also, just out of interest, did you try my script to see if that also worked?

Cheers, Lance.

No I didn’t. Sorry. It seems like it’s for a different purpose than what I needed.

Huh? Now I’m confused … Can you post your script so I can see what it was you actually required then?

As it may be something useful to know.

Cheers, Lance.

It’s posted up above, which is essentially from a NWN script. Basically it’s the facing of two NPCs who are having conversations with each other and with the PC, so they periodically flip their facing between each other to argue and then with player.

But you said …

And your proposed script does not have any locks or delays in it … and the second script with a small delay (as suggested) you said did not work.

void main()
{
    object oFake = OBJECT_SELF;
    object oReal = GetNearestObjectByTag("q2d_halas2");
    AssignCommand(oReal, SetFacingPoint(GetPosition(oFake)));
    SetFacingPoint(GetPosition(oReal));
}

So, what did you do differently?

Cheers, Lance.

Lance: For the specific conversation nodes I turned off the Animations pick, set the Node delay to a non-zero interval, and set the ga_face_target lockOrientation fields to 1.

1 Like

OK, I see you used the OC ga_face_target to lock the conversation outside of your own script. That makes sense now. Thanks for the explanation.

Cheers, Lance.