I’m currently betatesting my module and this script I’ve used in two areas. In one area it works like a charm, and in another area it’s been a bit buggy and I don’t know why. Maybe there is some way to write the code to get less bugs? This script fires in a conversation when the PC has left the companions and is about to rejoin them. There are 11 possible companions, so I made a script to check for each and every one of them in the area. The bug that appears is that on a few occasions only 2 of 3 companions that are actually in the area rejoins the companion instead of all 3. I don’t know why that is. Here is the code:
Try this (it’s untested, but should compile). GetNearestObjectByTag should only get objects in the same area, so no need to cycle through every object in the area, which is probably why your script fails at times.
Thanks @cuiilv ! That actually sounds like a good idea to try your take on it. Will try it out.
@Aqvilinus
Here is the function that is part of the include script:
void AddCompanionToParty(string sCompanionTag)
{
/////////////////////////////////////////////////////
// Make the companion visible on the Roster GUI
/////////////////////////////////////////////////////
SetIsRosterMemberCampaignNPC(sCompanionTag, 0);
/////////////////////////////////////////////////////
// Make the companion selectable on the Roster GUI
// FROM: ga_roster_selectable
/////////////////////////////////////////////////////
SetIsRosterMemberSelectable(sCompanionTag, 1);
/////////////////////////////////////////////////////
// Add the companion to the party
//FROM: ga_roster_party_add
/////////////////////////////////////////////////////
object oPC = GetFirstPC();
AddRosterMemberToParty(sCompanionTag, oPC);
/////////////////////////////////////////////////////
// Just in case we forgot to set this, when we add a
// companion to our party, we've met them.
/////////////////////////////////////////////////////
SetLocalInt(oPC, "met_" + sCompanionTag, TRUE);
/////////////////////////////////////////////////////
// Set the companion's XP equal to that of the PC
/////////////////////////////////////////////////////
object oCompanion = GetObjectByTag(sCompanionTag);
int nXP = GetPCAverageXP();
SetXP(oCompanion, nXP);
ForceRest(oCompanion);
}
GetNearestObjectByTag vs GetObjectByTag should definitely help. Even though only those companions in the actual area return valid in this script … I believe GetObjectByTag is still searching the entire module for them and just flagging those in the same area as the PC. So GetNearestObjectByTag should make the whole process a lot less laggy. If your using NWNX4 maybe you can raise the TMI level as a test first (You can with NWNX2 in NWN, not sure about NWN2 though).
@travus GetNearestObject can only return objects in oTarget’s area (in your example oTarget is OBJECT_SELF). Only for these objects the concept of proximity is defined. The check GetArea(OBJECT_SELF) == GetArea(oCompanion) is redundant.
@travus That was indeed a neat script. Yes, the companions are initialized with the Companion System, but I’ve experienced some few weird bugs with this (even if all the code looks rock solid) so…
I think I’ll go with the slightly more convoluted script from cuiilv just to be on the safe side.
Another question that is somewhat related to this: I’ve often used GetObjectByTag but now I see that GetNearestObjectByTag is much better to use in some instances when you don’t want to check the whole module and just the area. In many of the stock scripts they use GetTarget instead. Maybe one should use that one? Looking at the code in ginc_param_const it seems that it is a bit safer to use than maybe the other two (or I could be wrong here)? It seems that that function covers more and even has GetNearestObjectByTag in its code…Any thoughts on this from you script wizards out there?