You are here

teleport pc to one place, companions another

12 posts / 0 new
Last post
andgalf
teleport pc to one place, companions another

Hi! I'm struggling with finding out if there is a way to teleport the PC to a waypoint and at the same time the companion to another. I feel like I've seen this years ago when playing modules but I can't recall which one (in that case I could check in the toolset and maybe get some ideas about how to do this).

I tried with doing this in a conversation by using the ga_roster_party_remove script and after that on the same node in the conversation ga_roster_respawn and these two worked brilliantly. After that on the same node I used a script, let's call it "Jump the PC", I created using Lilac Soul's script generator, it looks like this:

 

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625    */

//Put this on action taken in the conversation editor
void main()
{

object oPC = GetPCSpeaker();

object oTarget;
location lTarget;
oTarget = GetWaypointByTag("pocket_area2");

lTarget = GetLocation(oTarget);

//only do the jump if the location is valid.
//though not flawless, we just check if it is in a valid area.
//the script will stop if the location isn't valid - meaning that
//nothing put after the teleport will fire either.
//the current location won't be stored, either

if (GetAreaFromLocation(lTarget)==OBJECT_INVALID) return;

AssignCommand(oPC, ClearAllActions());

AssignCommand(oPC, ActionJumpToLocation(lTarget));

}

 

The thing is, if I place this last script first in the node it works with teleporting the PC but when coming back to the area where the companion should have been respawned the companion wasn't there. If I place this script last in the node the companion teleports but the PC wont teleport. Is there a thing that those 3 scripts can't happen at the same time, just the ga_roster_party_remove and ga_roster_respawn that are somehow connected? If I move the "Jump the PC" script to the next conversation node it doesn't work since when removing the companion the conversation ends, which is quite logical. Any ideas how to get around this?

Thank you all for your time!

  • up
    50%
  • down
    50%
andysks

Hi there. Some questions.

1: I cannot find a script ga_roster_respawn. Are you sure this is how it's called?

2: Is the jump area a totally different area or is it the same area but different room?

If during the time this jump happens all you want to achieve is controlling only the PC, then perhaps hidding the companions is the easiest way to go.

  • up
    50%
  • down
    50%
andgalf

Thanks for your answer!

1. Yes, sorry you're right. The script is called ga_roster_spawn and not ga_roster_respawn.

2. Well, in the story I was thinking about a scenario like this: One of the companions are about to teleport all the companions and the PC to a specific place, but something goes wrong and the PC gets transported to another place than the others. Then sometime later the PC manages to get back and meet the companions again. Something along that line. What script do you use to hide the companions?

  • up
    50%
  • down
    50%
andysks

I wanted something similar in my campaign. The PC has dreams but the companions are not in them. I tried jumping and stuff but nothing satisfied me. So what I do, is jump the whole party and then call ga_scripthidden. What this will do, is hide the NPC with the tag passed on the parameter. When hidden, the NPC is not visible/clickable... nothing. In the case of companions too. You know they are there as a builder but the player doesn't. When you go back, call the script again but set the second parameter to FALSE so that they appear again.

 

Perhaps a fade to/from plack could be used too in order to hide the hiding. Play a bit with it and you'll see. It's a nice tool the ga_scripthidden.

One thing that perhaps someone else can tell us because I never tried it myself is... if hidden NPCs can be manipulated in some way. I don't think so but I wouldn't be surprised if they could. In your case, I know that if you call ga_jump_party_to_location (or any jumping script) on the PC, then the companions will jump too even if hidden. I just don't know if you can directly manipulate them. Like giving them items or applying effects etc.

  • up
    50%
  • down
    50%
kevL's

edit: oh, i guess you want the PC all by itself, while the rest of the party stays grouped ... what i did here is rather different,

 

if nobody needs to disappear ...

i wrote & tested the following script in a single module with three areas (an area where the dialog happened, another where the Companion ended up, and a third where the party ends up)

it'd be nice to have delays and fades, but this at least got the job done fer me:

// 'ga_teleport_glitch'
//
// dialog script. Assumes conversation between the PC and a Companion whose
// attempt to teleport will glitch. Also assumes that both the PC and the
// Companion will end up in the same module that the teleport starts in.
//
// NOTE: no checks are done for the validity of waypoints, etc.


const string sDEST_TELEPORTER = ""; // waypoint tag of the teleporter's destination
const string sDEST_PARTY      = ""; // waypoint tag of the party's destination


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

    // first remove the companion (conversation owner) who's doing the teleport
    // from the party
    ClearAllActions();

    string sTeleporter = GetRosterNameFromObject(OBJECT_SELF);
    RemoveRosterMemberFromParty(sTeleporter, oPC, FALSE);

    // second jump the companion to his/her destination waypoint
    object oDestTeleporter = GetWaypointByTag(sDEST_TELEPORTER);
    JumpToObject(oDestTeleporter);


    // third jump the remaining party to their destination waypoint
    object oDestParty = GetWaypointByTag(sDEST_PARTY);

    object oFaction = GetFirstFactionMember(oPC, FALSE);
    while (GetIsObjectValid(oFaction))
    {
        AssignCommand(oFaction, ClearAllActions());
        AssignCommand(oFaction, JumpToObject(oDestParty));

        oFaction = GetNextFactionMember(oPC, FALSE);
    }
}



when my party got to the missing companion, we talked and she rejoined my party normally.

I noticed that the teleporter's Animal Companion was automatically dismissed (not sure what to do about that atm, if anything). My wizard's Familiar, however, did the jump with me and another companion okay.


@andy, you should be able to do most anything to a scripthidden creature. Afaiaa, script hiding only bypasses collision detection and perceptions (and usually turns the creature's AI off).


In my version of events above, nobody gets hidden. It assumes that the teleported companion (the one doing the teleport) can stand happily at his/her destination spot until the party arrives. I suppose it's possible to simply hide the companion and keep him/her in the party, then unhide him/her at a suitable future, but i sense the scripting for that would be a bit more intricate .... Like, what, cross a trigger and ~poof~ the companion reappears? lul, sure :p

But if the companion can stand at its destination okay, then a dialog-node could be added to his/her conversation, like

"Took ya long enough."
- "Quit complaining. Want to rejoin the party?"
-- "okay."

  • up
    50%
  • down
    50%
andgalf

@kevL's -  Your script worked wonders!! Thank you so much! This was exactly what I needed.smiley

@andy - I tried your solution too, but even though my companion dissapeared at first and my PC was transported to the new area, the companion was visible again in the new area. I don't know why that is.

 

Thank you both for your help!

 

  • up
    50%
  • down
    50%
kevL's

glad t' help ... I also like to script a bit, so here's a 2nd version that jumps only the PC to one location and the rest of the party to another (you can rename it or whatever so it doesn't get confused with the 1st):

// 'ga_teleport_glitch'
//
// dialog script. Assumes conversation between the PC and a Companion whose
// attempt to teleport will glitch. Also assumes that both the PC and the
// Companions will end up in the same module that the teleport starts in.
//
// NOTE: no checks are done for the validity of waypoints, etc.


const string sDEST_PC         = ""; // waypoint tag of the PC's destination
const string sDEST_COMPANIONS = ""; // waypoint tag of the Companions' destination


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

    object oDestCompanions = GetWaypointByTag(sDEST_COMPANIONS);

    string sRoster;
    string sRosterListCurrent = "";

    object oFaction = GetFirstFactionMember(oPC, FALSE);
    while (GetIsObjectValid(oFaction))
    {
        sRoster = GetRosterNameFromObject(oFaction);
        if (sRoster != "")
        {
            sRosterListCurrent += sRoster + ";";

            if (GetIsPC(oFaction))
                SetOwnersControlledCompanion(oFaction);

            RemoveRosterMemberFromParty(sRoster, oPC, FALSE);

            AssignCommand(oFaction, ClearAllActions());
            AssignCommand(oFaction, JumpToObject(oDestCompanions));


            oFaction = GetFirstFactionMember(oPC, FALSE);
        }
        else
            oFaction = GetNextFactionMember(oPC, FALSE);
    }

    if (sRosterListCurrent != "")
        SetLocalString(oPC, "CurrentRosterList", sRosterListCurrent);

    AssignCommand(oPC, ClearAllActions());
    AssignCommand(oPC, JumpToObject(GetWaypointByTag(sDEST_PC)));
}



and to get those same party-members to rejoin, set up a trigger near them with this script in the OnEnter event:

// 'regroup'
//
// fired by a trigger.
// Adds a roster-list stored on the PC to the party.

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

    string sRoster;
    int iPos;

    string sRosterListCurrent = GetLocalString(oPC, "CurrentRosterList");
    if (sRosterListCurrent != "")
    {
        iPos = FindSubString(sRosterListCurrent, ";");
        while (iPos != -1)
        {
            sRoster = GetStringLeft(sRosterListCurrent, iPos);
            AddRosterMemberToParty(sRoster, oPC);

            sRosterListCurrent = GetStringRight(sRosterListCurrent, GetStringLength(sRosterListCurrent) - iPos - 1);
            iPos = FindSubString(sRosterListCurrent, ";");
        }

        DeleteLocalString(oPC, "CurrentRosterList");
    }
}



but which version is your preference (the second would be a bit harder to debug..).

  • up
    50%
  • down
    50%
Shallina

The 2 lines which make the jumlps are :

 

AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, JumpToObject(GetWaypointByTag(sDEST_PC)));

 

If you use ClearAllActions() which is in reality ClearAllActions(FALSE), the character won t jump if you are in combat.

Use ClearAllActions(TRUE) to cut a combat action.

 

Now you need to assign to oPC the object you want to jump. and to sDest_PC the tag of the waypoint you want to jump

string sDest_PC= "WP_01";

object oPC = GetObjectByTag("NotMainPC");

object oPC = GetFirstPC(TRUE); //False return the controled caracter.

AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, JumpToObject(GetWaypointByTag(sDEST_PC)));

 

This make your Main character jump to an object with a WP_01 value as TAG.

 

now :

string sDest_PC= "WP_02";

object oPC = GetObjectByTag("NotMainPC");

AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, JumpToObject(GetWaypointByTag(sDEST_PC)));

 

This make a creature which tag is NotMainPC jump to an object which tag is WP_02

 

Now you can build around this something more complex like kevL's did to catch your PC or object in a dynamic manner.

 

you can also wrap the

AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, JumpToObject(GetWaypointByTag(sDEST_PC)));

with VFX and animations to show a teleport effect , for this see Mephasm in the NWN2 original campaign.

 

Sorry for the text format I don t wish to spend 2 hours formating the message.

  • up
    50%
  • down
    50%
andgalf

Again, thanks for all the replys!

I am using kevL's first script that he posted here since it gave me exactly what I needed.

  • up
    50%
  • down
    50%
andgalf

Hello again, everyone!

It turned out I needed kevL's second script after all. I wasn't thinking clearly the first time around. Will test it tomorrow night.

  • up
    50%
  • down
    50%
andgalf

The second script also worked great! Thanks again kevL!

  • up
    50%
  • down
    50%
kevL's

np :)

  • up
    50%
  • down
    50%