Annoying conversation script problem [RESOLVED]

I have a situation in my module where the PC and the party enters a trigger and a conversation starts. The script is a bit convoluted since there are 8 companions and there could be anyone of them in the party at the time. Now, most of this works fine, however:

  • If you control one of the companions while entering the trigger, the first node (line of dialogue - a red node) fires twice for some odd reason. I have tried everything I can now to make that go away, but for some reason it seems almost impossible to do.
  • If you control the PC when entering the trigger everything works just fine.

This is quite a minor thing, I know, but it really annoys me. Can anyone of you script masters out there like @kevL_s , @travus , @Lance_Botelle , @Akhacha etc. help with this perhaps?

Here’s the script:

void TheRest(object oPC)
{

	object oFM = GetFirstFactionMember(oPC,FALSE);

	while(GetIsObjectValid(oFM))
	{
	
		if(oFM != oPC)
		{
			AssignCommand(oFM, ClearAllActions());
			AssignCommand(oFM, ActionJumpToObject(oPC));
		}
		
		oFM = GetNextFactionMember(oPC,FALSE);
	}

	oPC = SetOwnersControlledCompanion(oPC); 
	
	SetCutsceneMode(oPC);

	object oFM1 = GetFirstFactionMember(oPC,FALSE);

	if(oFM1 == oPC)
	{

		oFM1 = GetNextFactionMember(oPC,FALSE);

	}

	DelayCommand(0.5,AssignCommand(oFM1, ActionStartConversation(oPC, "c_ce_treasure", FALSE, FALSE, TRUE, FALSE)));
	
}

void main()
{

object oEnter = GetEnteringObject();
object oPC = GetFirstPC(FALSE);
object oWP = GetObjectByTag("pccedigwp");

if(GetJournalEntry("q_treasure",oPC) <1) return;
if(GetJournalEntry("q_treasure",oPC) == 11) return;

if(!GetIsPC(oEnter)) return;

AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, ActionJumpToObject(oWP));

DelayCommand(0.5,TheRest(oPC));


}

EDIT: Alright, I might have found a solution for this myself. I saw I had a similar script at another trigger that actually worked perfectly, and I had just added that you could only enter the trigger once. However, this needs to be able to be entered and running the conversation twice. I might be able to solve this…

2 Likes

Troubles is here

if(!GetIsPC(oEnter)) return;

This isn’t bullet proof with NPC party member. if you control a “companion” it can return FALSE when we expect TRUE

There is 2 others way I use for this behavior

	GetIsOwnedByPlayer()

Doesnt do exactly the same thing, and it isn’t what you want here I think.

What you want I think in this case is :

GetFactionEqual(oEnter,GetFirstPC())

so use :
if(!GetFactionEqual(oEnter,GetFirstPC()))) return;

Those 3 ways gives different result for a same problem. (filtering party members) They all have their use depending on the behavior you wish.

2 Likes

Alright, I’ll try with if(!GetFactionEqual(oEnter,GetFirstPC()))) return; though I noticed there was one oneparentheses too many.

EDIT: Ok, tried it. Didn’t work. It still fires the first node two times. I go back to working on it my own way. I had almost solved it, but there is still a weird issue… I think I can handle it from now on, though.

DelayCommand(0.5,TheRest(oPC));

This is called each time a party member enter the trigger, you are in conversation and it’s launched again for a new convo and cut your current convo.

You can make a filter so it launch only for the “main PC”

or make a filter so it launches only once

if(!GetLocalInt(OBJECT_SELF,"DoOnce")) return;

SetLocalInt(OBJECT_SELF,"DoOnce",TRUE);

There is also the

IsInConversation()

function that can help you filter

1 Like

I managed to solve it my own way. Darn, this game is finicky!
So here’s how I did it. The script:

void TheRest(object oPC)
{

	object oFM = GetFirstFactionMember(oPC,FALSE);

	while(GetIsObjectValid(oFM))
	{
	
		if(oFM != oPC)
		{
			AssignCommand(oFM, ClearAllActions());
			AssignCommand(oFM, ActionJumpToObject(oPC));
		}
		
		oFM = GetNextFactionMember(oPC,FALSE);
	}

	oPC = SetOwnersControlledCompanion(oPC); 
	
	SetCutsceneMode(oPC);

	object oFM1 = GetFirstFactionMember(oPC,FALSE);

	if(oFM1 == oPC)
	{

		oFM1 = GetNextFactionMember(oPC,FALSE);

	}
	
	object oPC1 = GetFirstPC();
	
	SetLocalInt(oPC1,"treasuredoneonce",1);

	DelayCommand(0.5,AssignCommand(oFM1, ActionStartConversation(oPC, "c_ce_treasure", FALSE, FALSE, TRUE, FALSE)));
	
}

void main()
{

object oEnter = GetEnteringObject();
object oPC = GetFirstPC(FALSE);
object oPC1 = GetFirstPC();
object oWP = GetObjectByTag("pccedigwp");

if(GetJournalEntry("q_treasure",oPC) <1) return;
if(GetJournalEntry("q_treasure",oPC) == 11) return;

if(!GetIsPC(oEnter)) return;
if(GetLocalInt(oPC1,"treasuredoneonce")) return;


AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, ActionJumpToObject(oWP));

DelayCommand(0.5,TheRest(oPC));


}

This hinders several party members to enter and launch the conversation. This was kind of the way I did it with my other working script. The one talked about here:

The problem is that this conversation needs to be fired several times if need be. Usually on triggers like this I use SetLocalInt(OBJECT_SELF,"done",TRUE); and if(GetLocalInt(OBJECT_SELF,"done"))return; but this wouldn’t quite work in this scenario since in that case the trigger would only fire once. So I set a local int on the PC instead. When I’m in the middle of the conversation and the outcome is that I want to be able to run the trigger again, I set a local int by ga_local_int like this SetLocalInt(oPC1,"treasuredoneonce",FALSE);

I hope managed to explain this well enough. In any case I’ve tested it a many times and now it seems bulletproof.

3 Likes

I see loppholes , but basically what you did is make a filter for it to be launch only once.

But if you want to be able to launch it again at later time, you need to “erase” the marker before the trigger has to be launched again.

here the “maker”

SetLocalInt(oPC1,"treasuredoneonce",1);

You need to set it at 0 somewhere for it to be able to be launched again.

Also the maker is held by the FirstPC, this can cause troubles.

2 Likes

@andgalf

I encountered a similar problem recently and realised it was because I was jumping a PC into the same trigger that starts the conversation as the trigger is entered. Hence, the conversation starts twice.

As @Shallina says, you basically need to stop this happening. The safest way to do it is to mark the trigger itself as done on entry in the above script. Then mark available again in the first node of the conversation if you want it to be available again straight away.

The problem with PC only is that it can vary, whereas the trigger is a one off… Just make sure the trigger tag is unique so that you can refer to it in the conversation correctly when marking as ready again.

The advantage of using the trigger also means you can control it’s activation ready or not variable more easily. It means one less variable to track on the PC s too.

2 Likes

I already said I did that.

No, I already said that I launch it several times. I’ve tested it. Many times. It works. So, no loopholes, I’m afraid.
Remember I only do single player modules. The first pc is always there.
Sometimes it’s like people don’t read what I write… :man_shrugging: Or maybe I’m not terribly good at explaining things when it’s complicated stuff like this.

Not in my case. Single player module. You know I don’t do multiplayer stuff. If it was for multiplayer, I would have agreed, but it’s not.

@andgalf

Agreed… Hence my “like” for your solution. :slightly_smiling_face:

This was more of a recommendation (to any reader) to avoid using variables on the PC if you can do so, just because it’s probably better protocol to do so if possible … Keeps the PC BIC file down (or is it the ROS :thinking:) and less likely a cause for corruption, perhaps?

So, just a recommended protocol and nothing against your solution. :rabbit:

(As you say, more for MP consideration in this case.)

3 Likes