Why wont this work when I want it to?

I’ve got a script set on an on enter bit for an area that works when I update my journal with the console from outside the area and enter. When I get the companion to join me before I leave ( she’s in the area with the script on it ), then update the journal and re enter it doesn’t work.

But when I update outside the area and enter without the companion joining up it works ! It seems to only work once ever when you enter. I wiped out the do once part completely and compiled it but it still did the same thing.

This is it…

void main()
{
object oPC=GetEnteringObject();
if(!GetIsPC(oPC))return;
int nInt;
nInt=GetLocalInt(oPC,"NW_JOURNAL_ENTRYgo_home");
if(nInt<2)return;
{
int DoOnce = GetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF));
if (DoOnce==TRUE) return;
SetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF), TRUE);
object oTarget;
oTarget=GetObjectByTag("marissa");
AssignCommand(oTarget,ActionStartConversation(oPC,"path_return",TRUE));
}
}

And it’s in a box ! First time ever ! Thanks andgalf. I had to go and read an old post to see how to do it, failed with the’’’ bit but used the button up above.

The companion’s tag is marissa but she’ll only talk when she’s not in the party and you’ve never entered that area before. I put in the include ginc companions thing at the beginning even though I didn’t know what it was or did ( I’d seen it in a script ) but it made no difference at all.

Any ideas ?

Question - In the code (indented and consistent spaced) -

void main()
{
    object oPC = GetEnteringObject();

    if(!GetIsPC(oPC))
        return;

    int nInt;

    nInt = GetLocalInt(oPC, "NW_JOURNAL_ENTRYgo_home");

    if(nInt < 2)
        return;

    {
        int DoOnce = GetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF));

        if(DoOnce == TRUE)
            return;

        SetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF), TRUE);

        object oTarget;

        oTarget = GetObjectByTag("marissa");
        AssignCommand(oTarget, ActionStartConversation(oPC, "path_return", TRUE));
    }
}

Is there any reason you have a block of code enclosed in {} ?

TR

I might not be too clear on what you want, but this script will fire only once and only if the quest “go_home” is at index 2:

void main()
{
	object oPC = GetEnteringObject();

	if (!GetIsPC(oPC) || GetLocalInt(OBJECT_SELF, "DoOnce")) return;

	if (GetJournalEntry("go_home", GetFirstPC()) == 2)
	{
		SetLocalInt(OBJECT_SELF, "DoOnce", TRUE);
		AssignCommand(GetObjectByTag("marissa"), ActionStartConversation(oPC, "path_return"));
	}
}

Tarot_Redhand… I don’t know why I had it enclosed in brackets, I thought it works by reading the first bit and returning if the condition isn’t met, then if it is it runs the script in the brackets but I don’t really understand scripting. I took it from one of my mods where it worked just fine, but maybe I wasn’t jumping in and out of the area that time. I’d imagine I made it by swapping bits of other scripts into it, I don’t know, it’s pretty ancient.

travus… Short but sweet, I’ll give it a go. So what’s wrong with my one, it’s got the same sort of thing in it and any idea why it’s misbehaving in case I have others like this ?

travus… Bad news I’m afraid it’s exactly the same problem and wont work the second time you enter the area.

What I’m trying to do is this…

1 You join up with marissa and go to another area.
2 You do some heroic deeds and your journal updates.
3 You go back to the area where you first met marissa and a conversation starts from the on enter properties bit of the area as soon as you enter it.
4 If you run in and out of the area after this the conversation shouldn’t work ( I kind of wish it did as I can easily block the conversation from the editor ).

If I update the journal from another area via the console then enter it marissa comes running down the hill and the conversation starts no problem. So the conversation isn’t an issue.

It becomes an issue when you enter the area, join up with her, leave the area, update the journal and return to the first area, nothing happens. I stuck the conversation on a kobold in the woods and spoke to him and it works then with her in the party so she’s not a problem.

Now I’m more clear. This script will fire on the same OnEnter event only once for each of two journal updates:

void main()
{
	object oPC = GetEnteringObject();
	
	if (!GetIsPC(oPC)) return;	

	object oComp = GetObjectByTag("marissa");
	string sConvo = "path_return"; 
	int nQuest = GetJournalEntry("go_home", GetFirstPC());
	
	if (!GetLocalInt(OBJECT_SELF, "StepOneDone") && nQuest == 2)
	{
		SetLocalInt(OBJECT_SELF, "StepOneDone", TRUE);
		AssignCommand(oComp, ActionStartConversation(oPC, sConvo));
	}
	
	if (!GetLocalInt(OBJECT_SELF, "StepTwoDone") && nQuest == 3) // <-- change to index of the heroic event.
	{
		SetLocalInt(OBJECT_SELF, "StepTwoDone", TRUE);
		AssignCommand(oComp, ActionStartConversation(oPC, sConvo));
	}
}
1 Like

travus… Thanks for that I will test it in a minute and the skeletons will be butchered again by my level 18 testing tank ! So does this mean that the original script only works once even if the conditions aren’t met the first time ? Because if so I’ve got to be very careful with this sort of thing if I want people to back track.

Off to kill skeletons !

The way you have your original script coded means that once the OnEnter event is fired it checks to see if the quest index is above 1. If it is, the convo will fire and the OnEnter event is then set to never fire again. That’s why the event wouldn’t fire the convo again if it was triggered again later.

travus… Sorry about this but it still wont work and the skeletons are suffering badly !

Perhaps this will help you find something wrong. The quest go_home doesn’t exist at all until you do the heroic deeds in the next door area, then when you leave the area and start heading home the conversation fires.

Nothing should happen with the conversation before you enter the area for the second, third, fourth, anytime without your journal having a go_home quest set at 2. All other conversations in the area with the on enter script are separate from path_return, it’s a one shot conversation.

I’m getting to the point where I’ll just duplicate the area and change the transition to be done with it but can’t believe this is so complicated and really don’t understand why it’s like this.

Doesn’t the script always fire when you enter the area, check for the journal entry and if nothing’s going on it waits until later ? I thought the way my original script worked was that it would do nothing until it was 2 or above, I’ve probably got it back to front but it definitely works with an updated journal to 2 on your first visit to the area and doesn’t work with no set journal at 2.

I’m going mad !

It should do that, yes.

I don’t think that should have anything to do with it not working.

I’m not sure I follow here. Do you mean you have more conversations that should fire within the OnEnter script?

Just trying to brainstorm here. Is the tag of marissa correct? Have you double checked that?

Wait a minute. I have an idea. If it’s on OnEnter it could be that problem that Sawdust37 had.

Maybe you could try something like this?

#include "ginc_ipspeaker"

void main()
{

object oPC = GetEnteringObject();

if(!GetIsPC(oPC)) return;

object oComp = GetObjectByTag("marissa");
int nQuest = GetJournalEntry("go_home", GetFirstPC());

if (!GetLocalInt(OBJECT_SELF, "StepOneDone") && nQuest == 2)
	{
		SetLocalInt(OBJECT_SELF, "StepOneDone", TRUE);
		CreateIPSpeaker("marissa", "path_return", GetLocation(GetFirstPC()), 0.5f);
	}


}

Edit: Even though CreateIPSpeaker works really well most of the times, some times it doesn’t fire right away, but will continue to try to fire until it does at least.

Or maybe you could try with this script (same as travus’ but with a delay):

void StartConversation()
{

object oComp = GetObjectByTag("marissa");
object oPC = GetFirstPC();

AssignCommand(oComp, ActionStartConversation(oPC, "path_return", FALSE, FALSE, FALSE, FALSE));

}


void main()
{
	object oPC = GetEnteringObject();
	
	if (!GetIsPC(oPC)) return;	


	string sConvo = "path_return"; 
	int nQuest = GetJournalEntry("go_home", GetFirstPC());
	
	if (!GetLocalInt(OBJECT_SELF, "StepOneDone") && nQuest == 2)
	{
		SetLocalInt(OBJECT_SELF, "StepOneDone", TRUE);
		DelayCommand(0.2, StartConversation());
	}
	

}

To quote @Lance_Botelle in another thread about similar issue:

“My guess would be that the target for the conversation was “lost” during the switch of the PC. I found that a small delay or even separating the call to start the conversation with the newly selected PC was required in some triggers. Also, just double-check the conversation properties.”

1 Like

Checking now… The skeletons are in trouble again !

andgalf… Looks like me and Sawdust37 had the same issue ! It worked just the way I wanted it. I used the first script and have absolutely no idea what an ipspeaker is but I’m very pleased that they exist as it’s saved my area duplication plan from ever happening ! So maybe all the scripts were absolutely fine but the engine couldn’t think quick enough.

Many thanks for rescuing me from the jaws of scripting madness again ! I can finally stop changing my start location, typing debugmode 1 rs ga_journal(etc. etc. ) and killing skeletons. One of them actually did some damage on my testing tank… But didn’t live long after.

travus… I’m sure it’s an engine thing and your scripts were fine they all worked on a first visit when marissa wasn’t a companion. Many thanks to you too for your perseverance.

Glad to hear it. CreateIPSpeaker I’ve found is the safest way to get a conversation to trigger. There are drawbacks though (Lance Botelle can tell you more about that) and even if it worked for you the first time you tried ingame, be aware that sometimes a CreateIPSpeaker can take up to half a minute to trigger if you’re unlucky. So, if I were you I should really check the second script also, as that might actually be more safe to use in your case…
I always use Cutscene mode together with CreateIPSpeaker when I have a conversation I want to really be sure it is run (and a lot of players or modders don’t like that since it prevents the player from doing anything until the conversation fires) and sometimes I have to wait several seconds, even up to 30 seconds for the conversation to run.
So if I can use a ActionStartConversation it is more ideal, I think.

By the way, I hardly know what an IPSpeaker is myself, to be honest. About two years ago andysks told me about this method, I believe.
I think the script creates an invisible placeable that you can call the same name as the companion, or something like that, that runs the conversation…or something.

Actually, looking at the ClientEnter scripts on the module I’m currently working on (chapter 4 that might not ever be released) I don’t use CreateIPSpeaker hardly at all. I use ClearAllActions and ActionStartConversation and SetCutsceneMode instead.

andgalf… If IP Speakers are invisible placeables that means I used to make them myself ! There are many invisible kobolds scaled down to 0.1,0.1,0.1 hidden in my mods in fireplaces or behind plot things that hold conversations on triggers etc. They didn’t have the same tag though and the poor things had no names, descriptions or sound sets either ! Only issue with the tags is you have to make sure you name the speakers in the conversation otherwise the view gets a bit weird !

This conversation shouldn’t be an issue if it takes 30 seconds and is in cutscene mode but I think I’ll test the other one later too if you think it’s safer.

Yes, I suggest you do that. @kevL_s and @Lance_Botelle can tell you a lot more details about these methods and what tends to work, what doesn’t, and why. I don’t know that much myself apart from what they’ve taught me. And @travus ’ scripts in general tend to be very, very reliable, so I think it was a timing issue this time around that caused his to not work.

What I meant by this is, if you don’t use SetCutsceneMode it can be that the player runs around for half a minute and clicks on something and then the conversation runs instead of right away, which can cause odd situations.

It certainly was annoying whatever the issue was ! I don’t know if my module will ever see the light of day either I’m just having a bit of fun making things with the toolset… Or was until this script happened !

As for the odd situation happening when the conversation fires, so long as it does happen I’m happy. But I’ll still try the other one.

CreateIPSpeaker() creates an IPoint placeable that runs  a pseudo-heartbeat script  a recursive function that checks several conditions every second or two and only when all conditions are met the dialog starts.

iirc

IPoints are very handy and for me were a welcome addition to the stock resources of Nwn2. They look a bit like waypoints in the toolset but are invisible ig. But since they’re placeables they can do things like have conversations and cast spells.

the quirk with them is that there’s a borky space at the end of the stock tag …

 
nag

ps. i didn’t see a single SendMessageToPC() in this thread; you guys must really like a challenge/handicap when debugging i spose ;) ( Throw enough scripts at it and its bound to work blecch )

/nag

2 Likes