This simple script doesn't work as intended

I have a modified version of gc_is_in_combat that looks like this, that I put on the first node of a conversation with the “NOT” marked. The conversation still starts if I click on the NPC even if I’m in the middle of a battle. Is there something about this that I don’t know perhaps?

#include "ginc_misc"
	
int StartingConditional()
{
	return GetIsInCombat(GetFirstPC());
}

I even tried with a more convoluted version just to see if that did something (and without the “NOT” marked on the first node):

#include "ginc_misc"
		
int StartingConditional()
{
	
if(GetIsInCombat(GetFirstPC()))
return FALSE;

else
return TRUE;

}

Still the same result.

You probably launch an other node of the conversation.

You can also work on “on conversation event”.

/*
	Prevents dialog with NPC if in combat.
	Place on the NPC's OnConversation event.
*/

void main()
{
	object oPC = GetFirstPC(FALSE);
		
	if (GetIsInCombat(oPC))
	{
		SpeakString("Quit talking to me, fool! You're in combat!");	
		return;
	}
	
	ExecuteScript("nw_c2_default4", OBJECT_SELF);
}

I think I’d have to go for something a lot less polite !

This is a really annoying problem especially if companions wander off for a fight or a baddie’s perception range picks up on the party and it all kicks off again… But it can also look quite amusing as your party continues talking to each other while battering people as if nothing unusual is going on.

There’s a thing on speak triggers to stop this but it never seemed to work properly for me. I tend to try and isolate places where conversation’s start instead or make baddies go hostile on the last node.

1 Like

Travus is right GetFirstPC() only work for the player character. Other character won’t be impacted.

You need to use GetFirstPC(FALSE) so it will impact the controlled character.

You can also use GetPCSpeaker() to get the player controlled object which is in conversation.

1 Like

Hmm, ok. But I’ve only tested it with the player character and it doesn’t work with that starting conditional which I find extremely odd. Of course, I can use something like travus suggested by putting something in the OnConversation of the character to solve the whole thing, but my point is that I shouldn’t have to. I’ll test what happens if I replace my script with this (but I doubt it will make any difference):

#include "ginc_misc"
	
int StartingConditional()
{
	return GetIsInCombat(GetFirstPC(FALSE));
}

EDIT: Tested it. As I thought. It didn’t work. I’ll try with GetPCSpeaker and see what happens.

Tried with this (the “NOT” isn’t checked):

#include "ginc_misc"
		
int StartingConditional()
{
	
if(GetIsInCombat(GetPCSpeaker()))
return FALSE;

else
return TRUE;

}

Didn’t work either.

EDIT: Alright, NWN2 conversation editor is officially bonkers. I’ll go with travus’ roundabout way of doing it then.

You could go even more of a roundabout way of starting the conversation by putting a count on the baddies and a condition on the first conversation line that they are all dead… They can’t be fighting when that happens.

1 Like

Yep, I’ve done that in other instances in the module, but it’s just so tedious having to go through 10 NPC baddies and put a script on them that counts how many are killed. I thought that this time it was: “Oh! Here’s an easy way of doing it”, but of course in the NWN2 toolset nothing is ever easy.

I did travus’ suggestion and that worked (and I knew it would since I’ve also used similar things before in this module, putting custom scripts on the OnConversation of a character that is).

I still don’t get why all of my different variations of my conditional script don’t work. They should have worked. Other starting conditional scripts work like a charm. It’s just totally illogical. Maybe it’s some hardcoded bizarre thing in NWN2. It wouldn’t be the first time.

There’s something wrong with it and it’s unreliable, that’s all there is too it… I’ve been there too !

Put this on death of each baddie and then a gc global int on first conversation node, it’s very quick.

// Made by Shalina 27/1/12
void main()
{
int nDeadTrolls = GetGlobalInt("whatever tag you want");
nDeadTrolls = nDeadTrolls+1;
SetGlobalInt("whatever tag you want",nDeadTrolls);
}

It’s now gone past it’s ten year anniversary for Shalina and it doesn’t have to be about trolls either !

1 Like

@Tsongo - Thanks for the script. I think I’ll go with travus’ route for now though, as for this particular situation I don’t need to know that all baddies are dead, just that there isn’t a fight, before starting the conversation.

1 Like

You are probably using a charactger that is not in combat.

You need to check if no one in the player faction is in combat



int isInCombat(){

	    object oFM =  GetFirstFactionMember(GetFirstPC(TRUE), FALSE);
		
	    while( GetIsObjectValid(oFM) )
	
        {
			if (GetIsInCombat(oFM)){
				return TRUE;
			
			}
	
            oFM = GetNextFactionMember(GetFirstPC(TRUE), FALSE);
        }

	return FALSE;
	
}

@andgalf

Is it possible that the PC has had a ClearAllActions(TRUE), just prior clicking on the NPC perhaps? Or, as others have said, the PC in question was not actually in combat, even though a combat was going on?

That said, I have had issues with the GetIsInCombat function not being 100% reliable.

I just had a reason to do something similar to what you required and I simply added a check to the NPC OnConversation hook.

I did not want the conversation to even start in the first place, let alone have its start and then check any initial node on a conversation, and so using the OnConversation hook to check the combat state seemed like the safest way to go to me.

No, he is in combat. When testing this I only have one character, the player character. No companions or henchmen in the test.

Nope. The way I tested it is that I am banging on a goblin and right after a stab/slash I try to talk to the NPC while the goblin stabs my back, and the conversation still starts.

Yeah, ok, but it’s really annoying that you need to make a custom script just for that, instead of just letting the conversation itself handle it. Like I said earlier, this seems like some weird hard coded bug on NWN2’s part.

@Shallina - Just for the sake of it, I’ll test your version of the script too, but I don’t think it will make any difference. It shouldn’t.

EDIT: Just as I thought. It made no difference. I modified your script somewhat so I didn’t have to use “NOT” in the first conversation node on the Conditions.

#include "ginc_misc"
		
int StartingConditional()
{
	
	    object oFM =  GetFirstFactionMember(GetFirstPC(TRUE), FALSE);
		
	    while( GetIsObjectValid(oFM) )
	
        {
			if (GetIsInCombat(oFM)){
				return FALSE;
			
			}
	
            oFM = GetNextFactionMember(GetFirstPC(TRUE), FALSE);
        }

	return TRUE;
	

}

In some way or form the conversation system is a bit messed up it seems. Some hard coded problem probably.

Yeah, maybe the function itself is actually buggy.

@andgalf

I note the Lexicon says this (emphasis mine):

" Function - GetIsInCombat: Returns TRUE while the creature is in Combat State, that is for a certain amount of time (8 seconds?) after any offensive action by or towards a member of your faction. Combat State also determines combat music, and the ability to rest so you should be able to do your own experiments to determine how long it lasts for, and which actions trigger it."

This would seem to me (like other combat functions) that some hard code is at play that is determining when this function returns TRUE or not. As I say, in my own experiences when trying to use this function, it has not been reliable, and I have my own variable check setup to help determine if a PC is in combat alongside this function, just in case.

The way I do it, is add a variable the moment combat starts, and then only clear it down when a module HB check resets it after checking to make sure no PC remains in combat. So, it assumes in combat from the moment any combat starts, and cannot return FALSE until we have had a clear few seconds (up to around 6 by default, although this can be overridden with a general end of round check too) of PCs no longer in combat.

You can check this Local Module Variable (or Global if setup as such) in the conversation, I guess. Although, I still check this via the OnConversation script, which, admittedly, is not the default OC version.

E.g. Do/try something like the following …When combat starts…

SetLocalInt(GetModule(), “INCOMBAT”, 1);

In your conversation, try checking the module variable to drop the conversation if TRUE.

In your module HB script, have it do a regular check of any combat, and delete that variable (or set FALSE) when there is no more combat, using a loop test like those already mentioned.

i wonder if

GetCurrentAction(oPc) == ACTION_INVALID

is more reliable than GetIsInCombat()

@kevL_s

:thinking: I believe that can also have some funny results, as I have done checks for that in the past and had unexpected results using it. For example, if a PC has been ordered to STAND GROUND (even when other PCs are in combat around them), do they return ACTION_INVALID?

If they did, then the conversation might still start … ? :thinking: May need some testing.

Also, when does ACTION_MOVETOPOINT get tested?

That is, if a PC clicks on an NPC, they move to the NPC to potentially start a conversation. If/when the conversation starts, what is the current action? :thinking:

there’s a list of some 30 ACTION_* constants … a long time ago I was trying to determine if a character was really doing nothing and settled on

if (GetCurrentAction(oPc) == ACTION_INVALID && !IsInConversation(oPc))

I believe there was a third condition also, like !IsInMultiplayerConversation(oPc) but think i dropped it …

when the object is moving/walking (the engine moves the creature to a “point”)

I have never checked if that action is set if an NPC is clicked that makes a PC walk to that NPC.

possibly ACTION_DIALOGOBJECT but not so sure …

in my (ancient) tests i had to use IsInConversation() to check for (not) dialog state

So maybe DIALOGOBJECT action is set as a priority over any MOVETOPOINT if a valid conversation object is clicked?

Yes, that is one I also use reliably in most situations.

I have currently only found setting my own variable to be more reliable than any OC function check. However, I will follow this with interest to see if an OC check works any more so.

Need to go offline for a bit now. Back later. :slight_smile:

1 Like