Script question - weird triggering behaviour

I have a script attached to a door on OnClickScript. Everything works but the door behaviour is a bit odd.
As you can see in the script if there is a certain journal entry, stuff will happen, and then the characters will be teleported to a waypoint. The thing is, ingame when you first open the door, and then click on the door to be transported, nothing happens. If you click on the door a second time everything works. Why is that? I can’t understand why it doesn’t work at first, and then it does.

Since this script is a copy and paste script (I’ve used functions by others that have helped me) maybe I’m doing something weird here.

const string sTAG_DEST = "sickw_wp";

#include "ginc_object"


 void PrepForDestruction(object oTarget)
 {
    	SetPlotFlag(oTarget,FALSE);
        SetImmortal(oTarget,FALSE);
        AssignCommand(oTarget,SetIsDestroyable(TRUE,FALSE,FALSE));
 }

 void jump(object oPlayerPc)
 {
        object oWp = GetObjectByTag(sTAG_DEST);
       if (GetIsObjectValid(oWp))
        {
            object oParty = GetFirstFactionMember(oPlayerPc, FALSE);
            while (GetIsObjectValid(oParty))
            {
                AssignCommand(oParty, ClearAllActions(TRUE));
                AssignCommand(oParty, JumpToObject(oWp));

                oParty = GetNextFactionMember(oPlayerPc, FALSE);
            }
        }
        
}

void Death(string sTagString, int iInstance = 0)
{
    	PrettyDebug("Applying Death Effect To: " + sTagString + " Instance = " + IntToString(iInstance));		
        
            object oObject = GetObjectByTag(sTagString, iInstance);

            AssignCommand(oObject, SetIsDestroyable( FALSE,FALSE,TRUE ));
    	    SetImmortal( oObject, FALSE );
    	    SetPlotFlag( oObject, FALSE );
            effect eFX = EffectDeath();
    		PrettyDebug("Name of oObject = " + GetName(oObject));		
            ApplyEffectToObject( DURATION_TYPE_INSTANT,eFX,oObject );
        
 }



void main()
{

    object oPlayerPc = GetClickingObject();
    object oOldwoman = GetObjectByTag("oldwoman");
    object oSonya = GetObjectByTag("d_sonya");

    int nInt = GetLocalInt(oPlayerPc,"NW_JOURNAL_ENTRYq_margret");
    if (nInt <1)
    {

    FloatingTextStringOnCreature("You have no reason to enter this home.",oPlayerPc);	
    return;
    }

    if (nInt == 21)
    {
    while (GetIsObjectValid(oOldwoman))
        {
    	PrepForDestruction(oOldwoman);
        	DestroyObject(oOldwoman);
    	}
    	
    	Death("d_sonya");
    	
    	object oHerbert = SpawnCreatureAtWP("herbert", "herb_wp");
    	
    }
    		
    AssignCommand(GetModule(), DelayCommand(0.f, jump(oPlayerPc)));

}

Hi andgalf,

I have not looked too closely, but try just putting a slight delay in the last line.

So, use 0.1f instead of 0.0f And have oPC jump themselves and not the module do it.

And use the JumpPartyToArea function rather than loop through party members.

BTW, If you are supplying the destination tag, I don’t see the point of a valid check. :slight_smile: But, I wanted to keep your script to as close to your original for you.

Cheers, Lance.

NOT TESTED …

const string sTAG_DEST = "sickw_wp";

#include "ginc_object"


 void PrepForDestruction(object oTarget)
 {
    	SetPlotFlag(oTarget,FALSE);
        SetImmortal(oTarget,FALSE);
        AssignCommand(oTarget,SetIsDestroyable(TRUE,FALSE,FALSE));
 }

 void jump(object oPlayerPc)
 {
        object oWp = GetObjectByTag(sTAG_DEST);
		
       if (GetIsObjectValid(oWp))
        {
            JumpPartyToArea(oPlayerPc, oWp); 
        }
        
}

void Death(string sTagString, int iInstance = 0)
{
    	PrettyDebug("Applying Death Effect To: " + sTagString + " Instance = " + IntToString(iInstance));		
        
            object oObject = GetObjectByTag(sTagString, iInstance);

            AssignCommand(oObject, SetIsDestroyable( FALSE,FALSE,TRUE ));
    	    SetImmortal( oObject, FALSE );
    	    SetPlotFlag( oObject, FALSE );
            effect eFX = EffectDeath();
    		PrettyDebug("Name of oObject = " + GetName(oObject));		
            ApplyEffectToObject( DURATION_TYPE_INSTANT,eFX,oObject );
        
 }



void main()
{

    object oPlayerPc = GetClickingObject();
    object oOldwoman = GetObjectByTag("oldwoman");
    object oSonya = GetObjectByTag("d_sonya");

    int nInt = GetLocalInt(oPlayerPc,"NW_JOURNAL_ENTRYq_margret");
    if (nInt <1)
    {

    FloatingTextStringOnCreature("You have no reason to enter this home.",oPlayerPc);	
    return;
    }

    if (nInt == 21)
    {
    while (GetIsObjectValid(oOldwoman))
        {
    	PrepForDestruction(oOldwoman);
        	DestroyObject(oOldwoman);
    	}
    	
    	Death("d_sonya");
    	
    	object oHerbert = SpawnCreatureAtWP("herbert", "herb_wp");
    	
    }
    		
    AssignCommand(oPlayerPc, DelayCommand(0.1f, jump(oPlayerPc)));

}

Hi Lance! Thanks for the answer. I’ve actually always wondered about the GetModule thing in that script. But since it has worked before, and I got it from someone here on the vault that knows scripting a lot better than I do, I have not changed it. I’ll try the JumpPartyToArea and the delay and see if it works.

Should I really use JumpPartyToArea? When looking at the description of that function it seems that that is intended for multiplayer, and this is a single player module.

Try this on the door’s OnOpen handler:

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

	if (GetJournalEntry("q_margret", oPC) > 0 && GetJournalEntry("q_margret", oPC) < 21)
    {
		object oSonya = GetObjectByTag("d_sonya");		
		
		SetPlotFlag(oSonya, FALSE);
		SetImmortal(oSonya, FALSE);
		SetLootable(oSonya, TRUE);
		AssignCommand(oSonya, SetIsDestroyable(FALSE, FALSE, TRUE));
		ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oSonya);

       	DestroyObject(GetObjectByTag("oldwoman"));		
		
    	CreateObject(OBJECT_TYPE_CREATURE, "herbert", GetLocation(GetWaypointByTag("herb_wp")));		
		
		DelayCommand(1.0f, JumpPartyToArea(oPC, GetWaypointByTag("sickw_wp")));
	}
	    	
	else
	{
		FloatingTextStringOnCreature("You have no reason to enter this home.", GetFirstPC(FALSE), FALSE);
		ActionCloseDoor(OBJECT_SELF);
	} 
}

Thanks for the reply, travus…but I don’t think that will work the way I want. The PC and the companions should be able to enter the home if nInt is between 1-20.

But maybe I’ll use my own script on OnOpen instead. Maybe that’s the key to getting it to work without having to click two times.

And my question remains: Should I really use JumpPartyToArea? I have not seen that being used in any stock scripts before where I would want the PC and the companions to jump (for example ga_jump_players) or any other jump scripts provided by people here on the vault.

I edited the script above to account for any journal entry from 1-20.

JumpPartyToArea works fine when you need to jump the entire party somewhere, including companions in single player games.

In fact JumpPartyToArea is a lot safer in single player than in multiplayer, since in multiplayer you should (ideally) account for consent of all players involved and not just the one that triggered the event.

1 Like

Ugh, things doesn’t work now. I think you might have misunderstood what I said, travus, because now it doesn’t work…eh…I can’t seem to explain very well…it has to do with the journal entries…

Whatever, I’ll just keep editing my own script instead so that I know what I’m doing. I’ll try and use OnOpen and JumpPartyToArea. Sometimes when you make a script too compact it’s harder to follow.

Hi andgalf,

What happened when you tried my script on your hook?

Any feedback may be useful.

Cheers, Lance.

Yes. :slight_smile:

By the way, after thinking some more, I believe my own scripts open the door prior to doing any jumping. i.e. Require the two-step process.

I believe my single step jumps are done from “on open”, which includes forcing the door to immediately shut and fire said script as required. ie. Add your script to an on open and have a bit of code shut the door just prior to doing the rest.

I never tried your script, actually, since I was unsure of the JumpPartyToArea. Now, all of a sudden nothing, (well that’s not entirely true) seems to work. I get so frustrated when you try to fix things (and in this case a very minor thing) and all of a sudden you break more things than you fix.

I thought that the OnOpen was the key to everything. But it seems that that was the key to everything getting f****d up.

I’ll try your script. Be back when I’ve tried that.

At least before, even if you had to click on the door twice, all the script functions fired as they should. Now one character won’t die and the spawn of the creature never happens.

Ok. I tried with your script and placed it OnClick instead. Now it’s exactly the way it was in the beginning. It works but you have to click two times on the door (or the teleport symbol, or what’s-it-called to be exact).
I’ll see if I can try your shutting the door stuff…but I’ll try edit travus’ script first.

travus’ take on it doesn’t work 'cause since the CreateObject and DestroyObject should ONLY occur if the journal entry is 21. Now it does those things when the value is between 1-20.
I’ll see if I can somehow wrap my head around how to edit his script so that it does what I need, and if that then works or if it’s like when trying different variations, that the CreateObject and oSonya being dead doesn’t happen. What I want with the script is to CreateObject and DestroyObject and oSonya being dead happens when entry is 21, and if entry is 1-20 I want the characters to just enter, and if the value is 0 I want them to get the message that they should not enter the home.

Edited travus’ script to this. I’ll test it now:

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

	if (GetJournalEntry("q_margret", oPC) == 21)
       {
		object oSonya = GetObjectByTag("d_sonya");		
		
		SetPlotFlag(oSonya, FALSE);
		SetImmortal(oSonya, FALSE);
		SetLootable(oSonya, TRUE);
		AssignCommand(oSonya, SetIsDestroyable(FALSE, FALSE, TRUE));
		ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oSonya);

       	DestroyObject(GetObjectByTag("oldwoman"));		
		
    	CreateObject(OBJECT_TYPE_CREATURE, "herbert", GetLocation(GetWaypointByTag("herbert_wp")));		
		
	DelayCommand(1.0f, JumpPartyToArea(oPC, GetWaypointByTag("sickw_wp")));
	}
	
	else if (GetJournalEntry("q_margret", oPC) > 0 && GetJournalEntry("q_margret", oPC) < 21)
	
	{
	
	DelayCommand(1.0f, JumpPartyToArea(oPC, GetWaypointByTag("sickw_wp")));
	
	}
	    	
	else if (GetJournalEntry("q_margret", oPC) <1)
	{
		FloatingTextStringOnCreature("You have no reason to enter this home.", GetFirstPC(FALSE), FALSE);
		ActionCloseDoor(OBJECT_SELF);
	} 
	
	else return;
}

Tested it. Alright. Almost there. The creature spawns now. oSonya dies. But oldwoman isn’t destroyed. (And I’ve had these problems before, that’s why I always use PrepForDestruction). Will add that and see what happens.

Finally it worked. I added the PrepForDestruction and then it worked as it should.

Thank you everyone for trying to help, and sorry I got a little frustrated!

2 Likes

While working on my module today and testing some new things, I went back to my first module and discovered a script I’d been using often (I think that that particular script was made with the Script Generator) for this exact purpose that I’d been discussing in this thread. Funny that I didn’t remember using this. Just out of curiosity I tried that with my original way of doing things and put it on OnClickScript, and interestingly enough it worked like a charm without the need to clicking two times. I wonder why this worked and not the others (until I used travus’ variation and put it on OnOpen). I’ll share it here to see if you all have any thoughts about why this worked and not my original script (where I had to click twice for the PC and the companions to be transported):

#include "ginc_object"

void PrepForDestruction(object oTarget)
{
    SetPlotFlag(oTarget,FALSE);
    SetImmortal(oTarget,FALSE);
    AssignCommand(oTarget,SetIsDestroyable(TRUE,FALSE,FALSE));
}

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

	if (GetJournalEntry("q_margret", oPC) == 21)
        {
		object oSonya = GetObjectByTag("d_sonya");		
		
		SetPlotFlag(oSonya, FALSE);
		SetImmortal(oSonya, FALSE);
		SetLootable(oSonya, TRUE);
		AssignCommand(oSonya, SetIsDestroyable(FALSE, FALSE, TRUE));
		ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oSonya);

       		PrepForDestruction(GetObjectByTag("oldwoman"));
       		DestroyObject(GetObjectByTag("oldwoman"));			
		
    		object oHerbert = SpawnCreatureAtWP("herbert", "herbert_wp");		
		
		object oTarget;
		location ITarget;
		oTarget=GetWaypointByTag("sickw_wp");
		ITarget=GetLocation(oTarget);
		if(GetAreaFromLocation(ITarget)==OBJECT_INVALID)return;
		oTarget=GetFirstFactionMember(oPC,FALSE);
		while(GetIsObjectValid(oTarget))
		{
		AssignCommand(oTarget,ClearAllActions());
		AssignCommand(oTarget,ActionJumpToLocation(ITarget));
		oTarget=GetNextFactionMember(oPC,FALSE);
		}
	 }
	
	 else if (GetJournalEntry("q_margret", oPC) > 0 && GetJournalEntry("q_margret", oPC) < 21)
	
	 {
	
	 	object oTarget;
		location ITarget;
		oTarget=GetWaypointByTag("sickw_wp");
		ITarget=GetLocation(oTarget);
		if(GetAreaFromLocation(ITarget)==OBJECT_INVALID)return;
		oTarget=GetFirstFactionMember(oPC,FALSE);
		while(GetIsObjectValid(oTarget))
		{
		AssignCommand(oTarget,ClearAllActions());
		AssignCommand(oTarget,ActionJumpToLocation(ITarget));
		oTarget=GetNextFactionMember(oPC,FALSE);
		}
	
	 }
	    	
	 else if (GetJournalEntry("q_margret", oPC) <1)
	 {
		FloatingTextStringOnCreature("You have no reason to enter this home.", GetFirstPC(FALSE), FALSE);
		ActionCloseDoor(OBJECT_SELF);
	 } 
	
	else return;
}