So I’ve seen transitions in PWs where they’re just little tab-glowy spheres on the ground. When you click them once they move you (usually) within the same area. Like a small path through a line of trees and it pops you out on the other side.
I’ve messed around with things like x0_o2_use_wdoor but the placeable takes two clicks. Even if it isn’t something that’s a container and I don’t have inventory checked. Happens when the script is in OnUse or OnClick. The first click sounds like it’s opening the placeable and then the 2nd click will teleport to the waypoint.
If the target location is in the same area, you also need to jump the player’s associates. Here’s a function that does that:
// Jump associates of oPC to oTarget if it's in the same area.
// Bloodsong swiped this from Amurayi's ultimate teleport script
// Proleric made this recursive because henchman can have horses in 1.69
void bhtJumpAssociates(object oPC, object oTarget, float fDelay = 2.0)
{
if (GetArea(oTarget) == GetArea(oPC))
{
DelayCommand(fDelay, ptJumpAssociate(oPC, ASSOCIATE_TYPE_ANIMALCOMPANION, oTarget));
DelayCommand(fDelay, ptJumpAssociate(oPC, ASSOCIATE_TYPE_DOMINATED, oTarget));
DelayCommand(fDelay, ptJumpAssociate(oPC, ASSOCIATE_TYPE_FAMILIAR, oTarget));
DelayCommand(fDelay, ptJumpAssociate(oPC, ASSOCIATE_TYPE_HENCHMAN, oTarget));
DelayCommand(fDelay, ptJumpAssociate(oPC, ASSOCIATE_TYPE_SUMMONED, oTarget));
}
}
// Jump associates of a given type to a target location
void ptJumpAssociate(object i_oPC, int i_type, object i_oWP)
{
int i = 0;
object oAssociate = GetAssociate(i_type, i_oPC, ++i);
while (GetIsObjectValid(oAssociate))
{
AssignCommand(oAssociate, ClearAllActions(TRUE));
AssignCommand(oAssociate, JumpToObject(i_oWP));
bhtJumpAssociates(oAssociate, i_oWP); // Recursive line added by Proleric
oAssociate = GetAssociate(i_type, i_oPC, ++i);
}
}
Couple of things. First I don’t understand why nobody has suggested using the built-in functions contained in x0_i0_transport.nss which contains -
//:://////////////////////////////////////////////////
//:: X0_I0_TRANSPORT
//:: Copyright (c) 2002 Floodgate Entertainment
//:://////////////////////////////////////////////////
/*
Functions for making creatures travel/transport to new locations.
*/
//:://////////////////////////////////////////////////
//:: Created By: Naomi Novik
//:: Created On: 09/12/2002
//:://////////////////////////////////////////////////
/**********************************************************************
* CONSTANTS
**********************************************************************/
/**********************************************************************
* FUNCTION PROTOTYPES
**********************************************************************/
// Target goes to specified destination object intelligently.
// If location is in same area, walk (or run) there.
// If location is in different area, walk (or run) to
// most appropriate door, area transition, or waypoint,
// then jump.
// If either of these fail, jump after fDelay seconds.
void TravelToObject(object oDest, object oTarget=OBJECT_SELF, int bRun=FALSE, float fDelay=10.0);
// Target goes to specified location intelligently. See
// TravelToObject for description.
void TravelToLocation(location lDest, object oTarget=OBJECT_SELF, int bRun=FALSE, float fDelay=10.0);
// Find nearest exit to target (either door or waypoint).
object GetNearestExit(object oTarget=OBJECT_SELF);
// Find best exit based on desired target area
object GetBestExit(object oTarget=OBJECT_SELF, object oTargetArea=OBJECT_INVALID);
// Transport a player and his/her associates to a waypoint.
// This does NOT transport the rest of the player's party,
// only their henchman, summoned, dominated, etc.
void TransportToWaypoint(object oPC, object oWaypoint);
// Transport a player and his/her associates to a location.
// This does NOT transport the rest of the player's party,
// only their henchman, summoned, dominated, etc.
void TransportToLocation(object oPC, location oLoc);
// Transport an entire party to a waypoint
void TransportAllToWaypoint(object oPC, object oWay);
// Transport an entire party to a location
void TransportAllToLocation(object oPC, location lLoc);
As far as @NWShacker’s last code goes it can be improved. Instead of 1st getting oPC’s area, clearing their actions, jumping to a location and then doing a return if oPC is not a PC is concerned it would be better to test for them being the PC in main() and only executing JumpPartyToLocation() if they are indeed a PC like -
Because anybody who read past the function declarations in that file can see that they only transfer one of each associate type with the PC. This was already discussed on this forum.
They also don’t transfer henchmen of henchmen of henchmen (…), which my code does.
x0_i0_transport only makes sense in SoU itself and should not be used for any module production.
That check allows transfer of party-less NPCs with the same function without a risk of hanging up the game.
// Transport an entire party with all associates to a location.
void TransportAllToLocation(object oPC, location oLoc)
{
object oPartyMem = GetFirstFactionMember(oPC, TRUE);
while (GetIsObjectValid(oPartyMem)) {
TransportToLocation(oPartyMem, oLoc);
oPartyMem = GetNextFactionMember(oPC, TRUE);
}
TransportToLocation(oPC, oLoc);
}
The final function in that library, doesn’t work as advertised then?
It does what it advertises, but only if you look at it with SoU in mind. It is outdated for HoTU+ (i.e. it has no idea of multiple henchmen).
TransportAllToLocation transfers all PCs and their: 1 henchman, 1 summon, etc. It doesn’t go deeper or to the sibling branches of associate tree.
There is also a bug in that functions code: oPC is transported twice if it is a PC.
They don’t, which is exactly what I want. They jump themselves, leaving the rest of the script to PCs (who pull their whole party). And if we make a cross-area jump, then it doesn’t matter.
Thank you for getting me to look through that function in more detail because I have discovered an even bigger bug according to the lexicon.
oPartyMem = GetNextFactionMember(oPC, TRUE);
According to the lexicon that particular line means that only PCs will be transported. To actually work as it is supposed to that line should actually be
oPartyMem = GetNextFactionMember(oPC, FALSE);
to transport non PCs of the PC’s faction. Here is the example code from the lexicon.
//given this function declaration
object GetFirstFactionMember(object oMemberOfFaction, int bPCOnly = TRUE);
this is the actual example code
// This code shows how you can cycle through all the party
// members of the first PC in the module.
// This will ONLY get PC members - any associates (Henchmen,
// familiars, summoned creatures and so on) will not be got by
// this loop. If the bPCOnly was FALSE in this script, it would ONLY
// get henchmen, familiars and so on for the faction.
void main()
{
// We alway use the SAME object for the GetFirst/Next faction
// member calls - always define it first. Here it is the first PC.
object oPC = GetFirstPC();
// Get the first PC party member
object oPartyMember = GetFirstFactionMember(oPC, TRUE);
// We stop when there are no more valid PC's in the party.
while(GetIsObjectValid(oPartyMember) == TRUE)
{
// Do something to party member
// Get the next PC member of oPC's faction.
// If we put anything but oPC into this, it may be a totally
// unreliable loop!
oPartyMember = GetNextFactionMember(oPC, TRUE);
}
}
Use of GetFirstFactionMember(oPC, TRUE) is correct in this context.
TransportAllToLocation scans all PCs in the multi-PC party, then jumps them one by one (and some of their assocs) with TransportToLocation.
So, with a single PC you’d just call TransportToLocation. But then this function is not multi-hench aware. It’s not even aware that NPCs may have associates at all. Maybe they couldn’t have in SoU… But they do now.
It might work for someone, but in the long run I wouldn’t recommend this include file.
@Tarot_Redhand Perhaps it’s a good idea to make a spot on https://nwn.wiki for some useful or frequently-asked-for snippets? They eventually get buried under other threads. Or a stub for updated lexicon pages.
Until you brought it up, I wasn’t even aware of the possibility for henchpersons to have their own henchpersons. This may have something to do with my having nothing to do with mp, and thus having sp blinkers on… On other hand it may not. Cest la vie.
Well I did go through the original nwn.bioware.com forums and create Just The FAQs, ma’am. Basically I took the contents of 2 separate threads and created pdf documents from them -
Neverwinter Nights SCRIPTING FAQ & TUTORIALS.pdf (188 Pages, 36 articles) - Mainly by David Gaider
Actually, it’s an SP issue, too. For example, horses can be henchmen of henchmen. Summoned creatures can be associates of associates, and so on.
@NWShacker interesting that the faction method works. I find factions a bit quirky, using them only as a last resort, but in this case it seems neater.
The delay in my code ensures that the PC arrives first, exactly on target and within any trigger that may be there. Delaying associates of associates is questionable, though it can make better use of space for, say, horses to arrive after the main party.
Horses as henchies. I know they can be quite intelligent but it would not occur to me that they were henchies. There again I have not created a module with horses in them (got an unfinished one with a horse that’s polymorphed into a giant chicken but that’s another story…)
@Proleric yeah, using a delay, it is possible to control which assoc might end up closer to PC when scanning the faction. I.e. henches could have priority over disposables for someone. But then it would require quite a party to make a difference. In my script it seems PC always arrives first.
By the way, the associate system is pretty flexible. For example, summons can have own summons or even true henchmen (they are correctly disbanded on unsummon - sub-summons disappear without VFX).
That’s a nice compilation, but having a wiki with examples from this and users would be useful too. Or do I have a wrong impression and the nwn.wiki is beta / testing-only / off-limits for general user?