Jump to content

Home

Problem Setting Custom NPC as Player Character


Malxados

Recommended Posts

So, I'm trying to make a script that removes all party members (both from the current party and from being select-able in the party selection screen), adds a custom version of Darth Nihilus to the party, and makes him the PC (rather than the exile); it's this last bit that's been giving me trouble now. Here's the script (minus some commented-out sections):

 

//nihilus_switch

#include "k_inc_debug"


void main(){

 int i;
 object oPC = GetFirstPC();

 for (i = 0; i < 12; i++){
     RemoveNPCFromPartyToBase(i);
     RemoveAvailableNPC(i);    
 }


 AddAvailableNPCByTemplate(5, "p_darthnihilus");
 object oNih = SpawnAvailableNPC(5, GetLocation(GetFirstPC()));
 AddPartyMember(5, oNih);
 SwitchPlayerCharacter(5);

}

 

If I take out the "SwitchPlayerCharacter(5);" line, the rest seems to work fine- I get the custom Nihilus in my party, and everyone else is gone (and I sometimes get random items or credits, not sure why that is). However, the game freezes when I try to make him the PC; is there a reason scripting-wise why this isn't working?

 

Thanks

Link to comment
Share on other sites

No, it's just a problem with the SwitchPlayerCharacter function. I believe I solved it by adding NoClicksFor(1.5) immediately preceding SwitchPlayerCharacter.

 

That didn't seem to help at all =( And this is for TSL, although you probably assumed that

Link to comment
Share on other sites

Hmm... you should probably also put some time in between Nihilus being spawned and the switch. Also I don't think the NPC should be in the active party... in looks like my script explicitly removes them if so.

 

Here's the whole source code for my script, which does work and doesn't crash the game, as far as I can tell:

Show spoiler
(hidden content - requires Javascript to show)
//Generic dialogue starter
void dlg(string sDLG) {

AssignCommand(OBJECT_SELF, ActionStartConversation(OBJECT_SELF, sDLG, 0, 0, 1, "", "", "", "", "", "", 0, -1, -1, 1));

}



//Gets the NPC integer of an object
int ObjectToNPC(object oObject) {

string sTag = GetTag(oObject);
if( sTag == "atton" ) return 0;
else if( sTag == "baodur" ) return 1;
else if( sTag == "mand" ) return 2;
else if( sTag == "G0T0" ) return 3;
else if( sTag == "handmaiden" ) return 4;
else if( sTag == "HK47" ) return 5;
else if( sTag == "kreia" ) return 6;
else if( sTag == "mira" ) return 7;
else if( sTag == "T3M4" ) return 8;
else if( sTag == "visasmarr" ) return 9;
else if( sTag == "hanharr" ) return 10;
else if( sTag == "disciple" ) return 11;
else return -1;

}



//Gets the NPC integer of the active PC using the previous function
int iNPC0() {

return ObjectToNPC(GetFirstPC());

}



//Gets Script Parameter 2
int iP2() {

return GetScriptParameter(2);

}



//Gets the expected tag of an object using its NPC integer
string NPCToTag(int iNPC) {

string sTag;
if( iNPC == 0 ) return "atton";
else if( iNPC == 1 ) return "baodur";
else if( iNPC == 2 ) return "mand";
else if( iNPC == 3 ) return "G0T0";
else if( iNPC == 4 ) return "handmaiden";
else if( iNPC == 5 ) return "HK47";
else if( iNPC == 6 ) return "kreia";
else if( iNPC == 7 ) return "mira";
else if( iNPC == 8 ) return "T3M4";
else if( iNPC == 9 ) return "visasmarr";
else if( iNPC == 10 ) return "hanharr";
else if( iNPC == 11 ) return "disciple";
else return "";

}



//Gets an object from an NPC integer
object NPCToObject(int iNPC){

return GetObjectByTag(NPCToTag(iNPC), 0);

}



//Returns whether an Object is valid
int validO(object oObject) {

return GetIsObjectValid(oObject);

}



//Gets the expected template (UTC file) of an object using its NPC integer
string NPCToTemplate(int iNPC) {

if( iNPC == 0 ) return "p_atton";
else if( iNPC == 1 ) return "p_baodur";
else if( iNPC == 2 ) return "p_mand";
else if( iNPC == 3 ) return "p_G0T0";
else if( iNPC == 4 ) return "p_handmaiden";
else if( iNPC == 5 ) return "p_HK47";
else if( iNPC == 6 ) return "p_kreia";
else if( iNPC == 7 ) return "p_mira";
else if( iNPC == 8 ) return "p_T3M4";
else if( iNPC == 9 ) return "p_visas";
else if( iNPC == 10 ) return "p_hanharr";
else if( iNPC == 11 ) return "p_disciple";
else return "";

}



//Checks whether Handmaiden and Disciple are present
int HandDisc() {

object oHand = GetObjectByTag(NPCToTag(4));
object oDisc = GetObjectByTag(NPCToTag(11));

if( GetIsObjectValid(oHand) && GetIsObjectValid(oDisc) ) return 0;
if( GetIsObjectValid(oHand) ) return 4;
if( GetIsObjectValid(oDisc) ) return 11;
else return -1;

}



//Checks whether Mira and Hanharr are present
int MiraHanh() {

object oMira = GetObjectByTag(NPCToTag(7));
object oHanh = GetObjectByTag(NPCToTag(10));

if( GetIsObjectValid(oMira) && GetIsObjectValid(oHanh) ) return 0;
if( GetIsObjectValid(oMira) ) return 7;
if( GetIsObjectValid(oHanh) ) return 10;
else return -1;

}



//Generic release function - all other release functions include this
void ReleaseNPC(int iNPC, int iPM) {

if( iNPC != iNPC0() ){

switch(iPM) {

	case 0:
		RemovePartyMember(iNPC);
		break;

	case 1:
		if( IsNPCPartyMember(iNPC) ){
		RemovePartyMember(iNPC);
		}
		break;

	}

}

else AssignCommand(GetFirstPC(), dlg("jc_pc4"));

}



//Enables or disables a party member, included in add NPC and switch PC functions
void SetPC(int iPC, int iSet) {

if( iPC != -1 ) SetNPCSelectability(iPC, iSet);

}



//Generic add function - all other add functions include this
void AddNPC(int iNPC, int iNear) {

if( iNPC != iNPC0() ){

switch(iNear) {

	case 0:
		AddAvailableNPCByTemplate(iNPC, NPCToTemplate(iNPC));
		SetPC(iNPC, 1);
		break;

	case 1:
		if( validO(NPCToObject(iNPC)) ){
			AddAvailableNPCByTemplate(iNPC, NPCToTemplate(iNPC));
			SetPC(iNPC, 1);
			}
		break;
		}

	}

else AssignCommand(GetFirstPC(), dlg("jc_pc5"));

}



//Generic remove function - all other remove functions include this
void RemoveNPC(int iNPC, int iPM) {

if( iNPC0() != iNPC ){

switch(iPM) {

	case 0:
		RemovePartyMember(iNPC);
		RemoveAvailableNPC(iNPC);
		break;

	case 1:
		if( IsNPCPartyMember(iNPC) ){
			RemovePartyMember(iNPC);
			RemoveAvailableNPC(iNPC);
		}
		break;

	}

}

else AssignCommand(GetFirstPC(), dlg("jc_pc6"));

}



//Generic dismiss function
void DismissNPC(int iNPC){

if( iNPC0() != iNPC ){
RemoveNPCFromPartyToBase(iNPC);
}

}


//Adds Handmaiden or Disciple
void AddHandOrDisc() {

switch(HandDisc()) {

case 0:
	if( GetGender(GetFirstPC()) == 1 )  AddNPC(11, 1);
	else AddNPC(4, 1);
	break;

case 4:
	AddNPC(4, 1);
	break;

case 11:
	AddNPC(11, 1);
	break;

}

}



//Adds Mira or Hanharr
void AddMiraOrHanh() {

switch(MiraHanh()) {

case 0:
	if( GetGoodEvilValue(GetFirstPC()) < 50 )  AddNPC(10, 1);
	else AddNPC(7, 1);
	break;

case 7:
	AddNPC(7, 1);
	break;

case 10:
	AddNPC(10, 1);
	break;

}

}



//Spawns NPC if it is not already present
void SpawnPC(int iNPC) {

if( !IsNPCPartyMember(iNPC) && iNPC != -1 ) SpawnAvailableNPC(iNPC, GetLocation(GetFirstPC()));

}



//Adds NPC directly to the party, if not already present
void AddPM(int iNPC, object oObject) {

if( 	iNPC != -1 &&
iNPC != iNPC0() &&
GetPartyMemberCount() < 3 ){
	object oNPC = SpawnAvailableNPC(iNPC, GetLocation(oObject));
	AddPartyMember(iNPC, oNPC);
	}

}



//Prepares to spawn the remote
void SetRem() {

object oInv = CreateObject(OBJECT_TYPE_PLACEABLE, "jc_inv", GetLocation(GetFirstPC()), FALSE);
AssignCommand(oInv, dlg("jc_rem3"));

}



//Spawns the remote if not already present and assigns it to Bao-Dur
void AddRemote() {

object oBao = GetObjectByTag("baodur");
object oRem = GetObjectByTag("remote");

if( GetIsObjectValid(oRem) ){

if( !GetIsPuppet(oRem) ){
	if( GetIsObjectValid(oBao) && IsNPCPartyMember(1) ){
		ActionWait(0.5);
		AddAvailablePUPByObject(0, oRem);
		AssignPUP(0, 1);
		AddPartyPuppet(0, oRem);
		ChangeToStandardFaction(oRem, 23);
		SetNPCAIStyle(oRem, 14);
		}
	else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_rem2")));
	}	
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_rem1")));
}
else	if( GetIsObjectValid(oBao) && IsNPCPartyMember(1) ){
	vector v1 = GetPosition(oBao);
	float f1 = GetFacing(oBao);
	location l1 = Location(v1 + (AngleToVector(f1) * 1.5), f1);  
	ActionWait(0.5);      
	AddAvailablePUPByTemplate(0, "p_remote");
	AssignPUP(0, 1);
	object oPUP = SpawnAvailablePUP(0, l1);
  		AddPartyPuppet(0, oPUP);
	ChangeToStandardFaction(oPUP, 23);
	SetNPCAIStyle(oPUP, 14);
	}
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_rem2")));

}



//Prepares to switch the active PC
void SetNum(int iNPC) {

vector v1 = GetPosition(GetFirstPC());
float f1 = GetFacing(GetFirstPC());
location l1 = Location(v1 + (AngleToVector(f1) * 1.5), f1);  

object oInv = CreateObject(OBJECT_TYPE_PLACEABLE, "jc_inv", l1, FALSE);
SetLocalNumber(oInv, 28, iNPC);
AssignCommand(oInv, dlg("jc_pcswitch"));

}



//Switches the active PC
void SwitchPC(int iNPC, string sTag) {

int iPM1 = ObjectToNPC(GetFirstPC());
int iPM2 = ObjectToNPC(GetNextPC());
int iPM3 = ObjectToNPC(GetNextPC());

int iCount = GetPartyMemberCount();

if( iNPC == -1 ) {
if( iNPC != iNPC0() ){
	AssignCommand(GetFirstPC(), ClearAllActions());
	SetPC(iNPC0(), 1);
	ActionWait(0.5);
	SwitchPlayerCharacter(-1);
	SetPartyLeader(iNPC);
	object oPC = GetFirstPC();
	if( iCount < 3 ){
		AddPM(iPM1, oPC);
		AddPM(iPM2, oPC);
		AddPM(iPM3, oPC);
		}
	else AddPM(iPM1, oPC);
	}
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc1")));
}

else if( iNPC0() == -1 ){
	if( IsAvailableCreature(iNPC) && GetNPCSelectability(iNPC) == 1 ){
		AssignCommand(GetFirstPC(), ClearAllActions());
		SetPC(iNPC0(), 1);
		ActionWait(0.5);
		SpawnPC(iNPC);
		ReleaseNPC(iNPC, 1);
		SwitchPlayerCharacter(iNPC);
		SetPartyLeader(iNPC);
		SetPC(iNPC, 0);
		object oPC = GetFirstPC();
		AddPM(iPM2, oPC);
		AddPM(iPM3, oPC);
		}
	else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc1")));
	}

else {
if( iNPC != iNPC0() ){
	if( IsAvailableCreature(iNPC) && GetNPCSelectability(iNPC) == 1 ){
		AssignCommand(GetFirstPC(), ClearAllActions());
		SetPC(iNPC0(), 1);
		ActionWait(0.5);
		SpawnPC(iNPC);
		ReleaseNPC(iNPC, 1);
		SwitchPlayerCharacter(iNPC);
		SetPartyLeader(iNPC);
		SetPC(iNPC, 0);
		object oPC = GetFirstPC();
		if( iNPC == iPM2 || iNPC == iPM3 ){
			AddPM(iPM1, oPC);
			AddPM(iPM2, oPC);
			AddPM(iPM3, oPC);
			}
		else if( iCount < 3 ){
			AddPM(iPM1, oPC);
			AddPM(iPM2, oPC);
			AddPM(iPM3, oPC);
			}
		else{
			AddPM(iPM1, oPC);
			}
		}
	else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc2")));
	}
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc1")));
}

}






void main() {

switch(GetScriptParameter(1)) {

//Enable party selection screen, fired whenever the party manager is opened
case 0:
	SetAreaUnescapable(FALSE);
	break;

//Release NPCs
case 1:
	SetPartyLeader(iNPC0());

	if( iP2() >= 0 && iP2() < 12 ){
		ReleaseNPC(iP2(), 0);
		}
	else if( iP2() == 12 ){
		int iNPC;
		for(iNPC = 0; iNPC <= 11; iNPC++ ) ReleaseNPC(iNPC, 1);
		}
	else AssignCommand(GetFirstPC(), dlg("jc_error"));			
	break;

//Add NPCs
case 2:
	SetPartyLeader(iNPC0());

	if( iP2() == 4 ){
		RemoveNPC(11, 0);
		AddNPC(4, 0);
		}
	else if( iP2() == 7 ){
		RemoveNPC(10, 0);
		AddNPC(7, 0);
		}
	else if( iP2() == 10 ){
		RemoveNPC(7, 0);
		AddNPC(10, 0);
		}
	else if( iP2() == 11 ){
		RemoveNPC(4, 0);
		AddNPC(11, 0);
		}
	else if( iP2() >= 0 && iP2() < 12 ){
		AddNPC(iP2(), 0);
		}
	else if( iP2() == 12 ){
		AddNPC(0, 1);
		AddNPC(1, 1);
		AddNPC(2, 1);
		AddNPC(3, 1);
		AddNPC(5, 1);
		AddNPC(6, 1);
		AddNPC(8, 1);
		AddNPC(9, 1);
		AddHandOrDisc();
		AddMiraOrHanh();
		}
	else if( iP2() == 13 ){
		RemoveNPC(10, 0);
		RemoveNPC(11, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(4, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(7, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		}
	else if( iP2() == 14 ){
		RemoveNPC(4, 0);
		RemoveNPC(10, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(7, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		AddNPC(11, 0);
		}
	else if( iP2() == 15 ){
		RemoveNPC(7, 0);
		RemoveNPC(11, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(4, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		AddNPC(10, 0);
		}
	else if( iP2() == 16 ){
		RemoveNPC(4, 0);
		RemoveNPC(7, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		AddNPC(10, 0);
		AddNPC(11, 0);
		}
	else if( iP2() == 17 ){
		NoClicksFor(1.5);
		SetGlobalFadeIn(2.0, 1.0, 0.0, 0.0, 0.0);
		SetRem();
		}
	else if( iP2() == 18 ){
		DelayCommand(0.2, AddRemote());
		DelayCommand(1.3, DestroyObject(GetObjectByTag("jc_inv"), 0.0, 1, 0.0, 1));
		}
	else if( iP2() == 19 ){
		AddNPC(11, 0);
		AddNPC(4, 0);
		}
	else if( iP2() == 20 ){
		AddNPC(10, 0);
		AddNPC(7, 0);
		}
	else AssignCommand(GetFirstPC(), dlg("jc_error"));
	break;

//Remove NPCs
case 3:
	SetPartyLeader(iNPC0());

	if( iP2() >= 0 && iP2() < 12 ){
		RemoveNPC(iP2(), 0);
		}
	else if( iP2() == 12 ){
		int iNPC;
		for(iNPC = 0; iNPC <= 11; iNPC++ ) RemoveNPC(iNPC, 1);
		}
	else if( iP2() == 13 ){
		int iNPC;
		for(iNPC = 0; iNPC <= 11; iNPC++ ) RemoveNPC(iNPC, 0);
		}
	else AssignCommand(GetFirstPC(), dlg("jc_error"));			
	break;

//Set up switch (precedes case 8)
case 4:
	SetPartyLeader(iNPC0());
	NoClicksFor(1.5);
	SetGlobalFadeIn(2.0, 1.0, 0.0, 0.0, 0.0);
	SetNum(iP2());
	break;

//Launch party selection screen
case 5:
	DelayCommand(0.1, ShowPartySelectionGUI("", -1, -1, TRUE));
	break;

//Dismiss NPC
case 6:
	SetPartyLeader(iNPC0());
	DismissNPC(iP2());
	break;

//Add NPC directly to the party
case 7:
	SetPartyLeader(iNPC0());
	AddPM (iP2(), GetFirstPC());
	break;

//Switch active PC
case 8:
	AssignCommand(GetFirstPC(), ClearAllActions());
	int iNum = GetLocalNumber(GetObjectByTag("jc_inv"), 28);
	if( iNum == 12 ){
		DelayCommand(0.2, SwitchPC(-1, ""));
		DelayCommand(1.3, DestroyObject(GetObjectByTag("jc_inv"), 0.0, 1, 0.0, 1));
		}
	else {
		DelayCommand(0.2, SwitchPC(iNum, NPCToTag(iNum)));
		DelayCommand(1.3, DestroyObject(GetObjectByTag("jc_inv"), 0.0, 1, 0.0, 1));
		}
	break;

//Dismiss all
case 9:
	int iNPC;
	for( iNPC = 0; iNPC <= 11; iNPC++ ) DismissNPC(iNPC);
	break;

//Recruit nearest
case 10:
	int iNearest;
	if( GetScriptParameter(3) == 0 ) iNearest = 1;
	else iNearest = GetScriptParameter(3);
	AddAvailableNPCByObject(GetScriptParameter(2), GetNearestObject(OBJECT_TYPE_CREATURE, OBJECT_SELF, iNearest));
	break;

case 11:
	AddAvailableNPCByObject(10, GetFirstPC());
	break;

case 12:
	vector v1 = GetPosition(GetFirstPC());
	float f1 = GetFacing(GetFirstPC());
	location l1 = Location(v1 + (AngleToVector(f1) * 1.5), f1);  
	ActionWait(0.5);      
	AddAvailablePUPByTemplate(0, "p_remote");
	AssignPUP(0, 10);
	object oPUP = SpawnAvailablePUP(0, l1);
  		AddPartyPuppet(0, oPUP);
	ChangeToStandardFaction(oPUP, 23);
	SetNPCAIStyle(oPUP, 14);
	break;



}

}

The relevant parts are cases 4 and 8, as well as the subroutines they include, particularly SwitchPC.

Link to comment
Share on other sites

Hmm... you should probably also put some time in between Nihilus being spawned and the switch. Also I don't think the NPC should be in the active party... in looks like my script explicitly removes them if so.

 

Here's the whole source code for my script, which does work and doesn't crash the game, as far as I can tell:

Show spoiler
(hidden content - requires Javascript to show)
//Generic dialogue starter
void dlg(string sDLG) {

AssignCommand(OBJECT_SELF, ActionStartConversation(OBJECT_SELF, sDLG, 0, 0, 1, "", "", "", "", "", "", 0, -1, -1, 1));

}



//Gets the NPC integer of an object
int ObjectToNPC(object oObject) {

string sTag = GetTag(oObject);
if( sTag == "atton" ) return 0;
else if( sTag == "baodur" ) return 1;
else if( sTag == "mand" ) return 2;
else if( sTag == "G0T0" ) return 3;
else if( sTag == "handmaiden" ) return 4;
else if( sTag == "HK47" ) return 5;
else if( sTag == "kreia" ) return 6;
else if( sTag == "mira" ) return 7;
else if( sTag == "T3M4" ) return 8;
else if( sTag == "visasmarr" ) return 9;
else if( sTag == "hanharr" ) return 10;
else if( sTag == "disciple" ) return 11;
else return -1;

}



//Gets the NPC integer of the active PC using the previous function
int iNPC0() {

return ObjectToNPC(GetFirstPC());

}



//Gets Script Parameter 2
int iP2() {

return GetScriptParameter(2);

}



//Gets the expected tag of an object using its NPC integer
string NPCToTag(int iNPC) {

string sTag;
if( iNPC == 0 ) return "atton";
else if( iNPC == 1 ) return "baodur";
else if( iNPC == 2 ) return "mand";
else if( iNPC == 3 ) return "G0T0";
else if( iNPC == 4 ) return "handmaiden";
else if( iNPC == 5 ) return "HK47";
else if( iNPC == 6 ) return "kreia";
else if( iNPC == 7 ) return "mira";
else if( iNPC == 8 ) return "T3M4";
else if( iNPC == 9 ) return "visasmarr";
else if( iNPC == 10 ) return "hanharr";
else if( iNPC == 11 ) return "disciple";
else return "";

}



//Gets an object from an NPC integer
object NPCToObject(int iNPC){

return GetObjectByTag(NPCToTag(iNPC), 0);

}



//Returns whether an Object is valid
int validO(object oObject) {

return GetIsObjectValid(oObject);

}



//Gets the expected template (UTC file) of an object using its NPC integer
string NPCToTemplate(int iNPC) {

if( iNPC == 0 ) return "p_atton";
else if( iNPC == 1 ) return "p_baodur";
else if( iNPC == 2 ) return "p_mand";
else if( iNPC == 3 ) return "p_G0T0";
else if( iNPC == 4 ) return "p_handmaiden";
else if( iNPC == 5 ) return "p_HK47";
else if( iNPC == 6 ) return "p_kreia";
else if( iNPC == 7 ) return "p_mira";
else if( iNPC == 8 ) return "p_T3M4";
else if( iNPC == 9 ) return "p_visas";
else if( iNPC == 10 ) return "p_hanharr";
else if( iNPC == 11 ) return "p_disciple";
else return "";

}



//Checks whether Handmaiden and Disciple are present
int HandDisc() {

object oHand = GetObjectByTag(NPCToTag(4));
object oDisc = GetObjectByTag(NPCToTag(11));

if( GetIsObjectValid(oHand) && GetIsObjectValid(oDisc) ) return 0;
if( GetIsObjectValid(oHand) ) return 4;
if( GetIsObjectValid(oDisc) ) return 11;
else return -1;

}



//Checks whether Mira and Hanharr are present
int MiraHanh() {

object oMira = GetObjectByTag(NPCToTag(7));
object oHanh = GetObjectByTag(NPCToTag(10));

if( GetIsObjectValid(oMira) && GetIsObjectValid(oHanh) ) return 0;
if( GetIsObjectValid(oMira) ) return 7;
if( GetIsObjectValid(oHanh) ) return 10;
else return -1;

}



//Generic release function - all other release functions include this
void ReleaseNPC(int iNPC, int iPM) {

if( iNPC != iNPC0() ){

switch(iPM) {

	case 0:
		RemovePartyMember(iNPC);
		break;

	case 1:
		if( IsNPCPartyMember(iNPC) ){
		RemovePartyMember(iNPC);
		}
		break;

	}

}

else AssignCommand(GetFirstPC(), dlg("jc_pc4"));

}



//Enables or disables a party member, included in add NPC and switch PC functions
void SetPC(int iPC, int iSet) {

if( iPC != -1 ) SetNPCSelectability(iPC, iSet);

}



//Generic add function - all other add functions include this
void AddNPC(int iNPC, int iNear) {

if( iNPC != iNPC0() ){

switch(iNear) {

	case 0:
		AddAvailableNPCByTemplate(iNPC, NPCToTemplate(iNPC));
		SetPC(iNPC, 1);
		break;

	case 1:
		if( validO(NPCToObject(iNPC)) ){
			AddAvailableNPCByTemplate(iNPC, NPCToTemplate(iNPC));
			SetPC(iNPC, 1);
			}
		break;
		}

	}

else AssignCommand(GetFirstPC(), dlg("jc_pc5"));

}



//Generic remove function - all other remove functions include this
void RemoveNPC(int iNPC, int iPM) {

if( iNPC0() != iNPC ){

switch(iPM) {

	case 0:
		RemovePartyMember(iNPC);
		RemoveAvailableNPC(iNPC);
		break;

	case 1:
		if( IsNPCPartyMember(iNPC) ){
			RemovePartyMember(iNPC);
			RemoveAvailableNPC(iNPC);
		}
		break;

	}

}

else AssignCommand(GetFirstPC(), dlg("jc_pc6"));

}



//Generic dismiss function
void DismissNPC(int iNPC){

if( iNPC0() != iNPC ){
RemoveNPCFromPartyToBase(iNPC);
}

}


//Adds Handmaiden or Disciple
void AddHandOrDisc() {

switch(HandDisc()) {

case 0:
	if( GetGender(GetFirstPC()) == 1 )  AddNPC(11, 1);
	else AddNPC(4, 1);
	break;

case 4:
	AddNPC(4, 1);
	break;

case 11:
	AddNPC(11, 1);
	break;

}

}



//Adds Mira or Hanharr
void AddMiraOrHanh() {

switch(MiraHanh()) {

case 0:
	if( GetGoodEvilValue(GetFirstPC()) < 50 )  AddNPC(10, 1);
	else AddNPC(7, 1);
	break;

case 7:
	AddNPC(7, 1);
	break;

case 10:
	AddNPC(10, 1);
	break;

}

}



//Spawns NPC if it is not already present
void SpawnPC(int iNPC) {

if( !IsNPCPartyMember(iNPC) && iNPC != -1 ) SpawnAvailableNPC(iNPC, GetLocation(GetFirstPC()));

}



//Adds NPC directly to the party, if not already present
void AddPM(int iNPC, object oObject) {

if( 	iNPC != -1 &&
iNPC != iNPC0() &&
GetPartyMemberCount() < 3 ){
	object oNPC = SpawnAvailableNPC(iNPC, GetLocation(oObject));
	AddPartyMember(iNPC, oNPC);
	}

}



//Prepares to spawn the remote
void SetRem() {

object oInv = CreateObject(OBJECT_TYPE_PLACEABLE, "jc_inv", GetLocation(GetFirstPC()), FALSE);
AssignCommand(oInv, dlg("jc_rem3"));

}



//Spawns the remote if not already present and assigns it to Bao-Dur
void AddRemote() {

object oBao = GetObjectByTag("baodur");
object oRem = GetObjectByTag("remote");

if( GetIsObjectValid(oRem) ){

if( !GetIsPuppet(oRem) ){
	if( GetIsObjectValid(oBao) && IsNPCPartyMember(1) ){
		ActionWait(0.5);
		AddAvailablePUPByObject(0, oRem);
		AssignPUP(0, 1);
		AddPartyPuppet(0, oRem);
		ChangeToStandardFaction(oRem, 23);
		SetNPCAIStyle(oRem, 14);
		}
	else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_rem2")));
	}	
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_rem1")));
}
else	if( GetIsObjectValid(oBao) && IsNPCPartyMember(1) ){
	vector v1 = GetPosition(oBao);
	float f1 = GetFacing(oBao);
	location l1 = Location(v1 + (AngleToVector(f1) * 1.5), f1);  
	ActionWait(0.5);      
	AddAvailablePUPByTemplate(0, "p_remote");
	AssignPUP(0, 1);
	object oPUP = SpawnAvailablePUP(0, l1);
  		AddPartyPuppet(0, oPUP);
	ChangeToStandardFaction(oPUP, 23);
	SetNPCAIStyle(oPUP, 14);
	}
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_rem2")));

}



//Prepares to switch the active PC
void SetNum(int iNPC) {

vector v1 = GetPosition(GetFirstPC());
float f1 = GetFacing(GetFirstPC());
location l1 = Location(v1 + (AngleToVector(f1) * 1.5), f1);  

object oInv = CreateObject(OBJECT_TYPE_PLACEABLE, "jc_inv", l1, FALSE);
SetLocalNumber(oInv, 28, iNPC);
AssignCommand(oInv, dlg("jc_pcswitch"));

}



//Switches the active PC
void SwitchPC(int iNPC, string sTag) {

int iPM1 = ObjectToNPC(GetFirstPC());
int iPM2 = ObjectToNPC(GetNextPC());
int iPM3 = ObjectToNPC(GetNextPC());

int iCount = GetPartyMemberCount();

if( iNPC == -1 ) {
if( iNPC != iNPC0() ){
	AssignCommand(GetFirstPC(), ClearAllActions());
	SetPC(iNPC0(), 1);
	ActionWait(0.5);
	SwitchPlayerCharacter(-1);
	SetPartyLeader(iNPC);
	object oPC = GetFirstPC();
	if( iCount < 3 ){
		AddPM(iPM1, oPC);
		AddPM(iPM2, oPC);
		AddPM(iPM3, oPC);
		}
	else AddPM(iPM1, oPC);
	}
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc1")));
}

else if( iNPC0() == -1 ){
	if( IsAvailableCreature(iNPC) && GetNPCSelectability(iNPC) == 1 ){
		AssignCommand(GetFirstPC(), ClearAllActions());
		SetPC(iNPC0(), 1);
		ActionWait(0.5);
		SpawnPC(iNPC);
		ReleaseNPC(iNPC, 1);
		SwitchPlayerCharacter(iNPC);
		SetPartyLeader(iNPC);
		SetPC(iNPC, 0);
		object oPC = GetFirstPC();
		AddPM(iPM2, oPC);
		AddPM(iPM3, oPC);
		}
	else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc1")));
	}

else {
if( iNPC != iNPC0() ){
	if( IsAvailableCreature(iNPC) && GetNPCSelectability(iNPC) == 1 ){
		AssignCommand(GetFirstPC(), ClearAllActions());
		SetPC(iNPC0(), 1);
		ActionWait(0.5);
		SpawnPC(iNPC);
		ReleaseNPC(iNPC, 1);
		SwitchPlayerCharacter(iNPC);
		SetPartyLeader(iNPC);
		SetPC(iNPC, 0);
		object oPC = GetFirstPC();
		if( iNPC == iPM2 || iNPC == iPM3 ){
			AddPM(iPM1, oPC);
			AddPM(iPM2, oPC);
			AddPM(iPM3, oPC);
			}
		else if( iCount < 3 ){
			AddPM(iPM1, oPC);
			AddPM(iPM2, oPC);
			AddPM(iPM3, oPC);
			}
		else{
			AddPM(iPM1, oPC);
			}
		}
	else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc2")));
	}
else DelayCommand(1.0, AssignCommand(GetFirstPC(), dlg("jc_pc1")));
}

}






void main() {

switch(GetScriptParameter(1)) {

//Enable party selection screen, fired whenever the party manager is opened
case 0:
	SetAreaUnescapable(FALSE);
	break;

//Release NPCs
case 1:
	SetPartyLeader(iNPC0());

	if( iP2() >= 0 && iP2() < 12 ){
		ReleaseNPC(iP2(), 0);
		}
	else if( iP2() == 12 ){
		int iNPC;
		for(iNPC = 0; iNPC <= 11; iNPC++ ) ReleaseNPC(iNPC, 1);
		}
	else AssignCommand(GetFirstPC(), dlg("jc_error"));			
	break;

//Add NPCs
case 2:
	SetPartyLeader(iNPC0());

	if( iP2() == 4 ){
		RemoveNPC(11, 0);
		AddNPC(4, 0);
		}
	else if( iP2() == 7 ){
		RemoveNPC(10, 0);
		AddNPC(7, 0);
		}
	else if( iP2() == 10 ){
		RemoveNPC(7, 0);
		AddNPC(10, 0);
		}
	else if( iP2() == 11 ){
		RemoveNPC(4, 0);
		AddNPC(11, 0);
		}
	else if( iP2() >= 0 && iP2() < 12 ){
		AddNPC(iP2(), 0);
		}
	else if( iP2() == 12 ){
		AddNPC(0, 1);
		AddNPC(1, 1);
		AddNPC(2, 1);
		AddNPC(3, 1);
		AddNPC(5, 1);
		AddNPC(6, 1);
		AddNPC(8, 1);
		AddNPC(9, 1);
		AddHandOrDisc();
		AddMiraOrHanh();
		}
	else if( iP2() == 13 ){
		RemoveNPC(10, 0);
		RemoveNPC(11, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(4, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(7, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		}
	else if( iP2() == 14 ){
		RemoveNPC(4, 0);
		RemoveNPC(10, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(7, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		AddNPC(11, 0);
		}
	else if( iP2() == 15 ){
		RemoveNPC(7, 0);
		RemoveNPC(11, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(4, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		AddNPC(10, 0);
		}
	else if( iP2() == 16 ){
		RemoveNPC(4, 0);
		RemoveNPC(7, 0);
		AddNPC(0, 0);
		AddNPC(1, 0);
		AddNPC(2, 0);
		AddNPC(3, 0);
		AddNPC(5, 0);
		AddNPC(6, 0);
		AddNPC(8, 0);
		AddNPC(9, 0);
		AddNPC(10, 0);
		AddNPC(11, 0);
		}
	else if( iP2() == 17 ){
		NoClicksFor(1.5);
		SetGlobalFadeIn(2.0, 1.0, 0.0, 0.0, 0.0);
		SetRem();
		}
	else if( iP2() == 18 ){
		DelayCommand(0.2, AddRemote());
		DelayCommand(1.3, DestroyObject(GetObjectByTag("jc_inv"), 0.0, 1, 0.0, 1));
		}
	else if( iP2() == 19 ){
		AddNPC(11, 0);
		AddNPC(4, 0);
		}
	else if( iP2() == 20 ){
		AddNPC(10, 0);
		AddNPC(7, 0);
		}
	else AssignCommand(GetFirstPC(), dlg("jc_error"));
	break;

//Remove NPCs
case 3:
	SetPartyLeader(iNPC0());

	if( iP2() >= 0 && iP2() < 12 ){
		RemoveNPC(iP2(), 0);
		}
	else if( iP2() == 12 ){
		int iNPC;
		for(iNPC = 0; iNPC <= 11; iNPC++ ) RemoveNPC(iNPC, 1);
		}
	else if( iP2() == 13 ){
		int iNPC;
		for(iNPC = 0; iNPC <= 11; iNPC++ ) RemoveNPC(iNPC, 0);
		}
	else AssignCommand(GetFirstPC(), dlg("jc_error"));			
	break;

//Set up switch (precedes case 8)
case 4:
	SetPartyLeader(iNPC0());
	NoClicksFor(1.5);
	SetGlobalFadeIn(2.0, 1.0, 0.0, 0.0, 0.0);
	SetNum(iP2());
	break;

//Launch party selection screen
case 5:
	DelayCommand(0.1, ShowPartySelectionGUI("", -1, -1, TRUE));
	break;

//Dismiss NPC
case 6:
	SetPartyLeader(iNPC0());
	DismissNPC(iP2());
	break;

//Add NPC directly to the party
case 7:
	SetPartyLeader(iNPC0());
	AddPM (iP2(), GetFirstPC());
	break;

//Switch active PC
case 8:
	AssignCommand(GetFirstPC(), ClearAllActions());
	int iNum = GetLocalNumber(GetObjectByTag("jc_inv"), 28);
	if( iNum == 12 ){
		DelayCommand(0.2, SwitchPC(-1, ""));
		DelayCommand(1.3, DestroyObject(GetObjectByTag("jc_inv"), 0.0, 1, 0.0, 1));
		}
	else {
		DelayCommand(0.2, SwitchPC(iNum, NPCToTag(iNum)));
		DelayCommand(1.3, DestroyObject(GetObjectByTag("jc_inv"), 0.0, 1, 0.0, 1));
		}
	break;

//Dismiss all
case 9:
	int iNPC;
	for( iNPC = 0; iNPC <= 11; iNPC++ ) DismissNPC(iNPC);
	break;

//Recruit nearest
case 10:
	int iNearest;
	if( GetScriptParameter(3) == 0 ) iNearest = 1;
	else iNearest = GetScriptParameter(3);
	AddAvailableNPCByObject(GetScriptParameter(2), GetNearestObject(OBJECT_TYPE_CREATURE, OBJECT_SELF, iNearest));
	break;

case 11:
	AddAvailableNPCByObject(10, GetFirstPC());
	break;

case 12:
	vector v1 = GetPosition(GetFirstPC());
	float f1 = GetFacing(GetFirstPC());
	location l1 = Location(v1 + (AngleToVector(f1) * 1.5), f1);  
	ActionWait(0.5);      
	AddAvailablePUPByTemplate(0, "p_remote");
	AssignPUP(0, 10);
	object oPUP = SpawnAvailablePUP(0, l1);
  		AddPartyPuppet(0, oPUP);
	ChangeToStandardFaction(oPUP, 23);
	SetNPCAIStyle(oPUP, 14);
	break;



}

}

The relevant parts are cases 4 and 8, as well as the subroutines they include, particularly SwitchPC.

 

Good grief, that is quite the script haha; after looking through it (and your post) I changed my script to this, but it still freezes the game up:

 

Show spoiler
(hidden content - requires Javascript to show)
//nihilus_switch

#include "k_inc_debug"


void main(){

 int i;
 object oPC = GetFirstPC();

 for (i = 0; i < 12; i++){

     RemoveNPCFromPartyToBase(i);
     RemoveAvailableNPC(i);    
 }



 AddAvailableNPCByTemplate(5, "p_darthnihilus");

 object oNih = CreateObject(OBJECT_TYPE_CREATURE, "p_darthnihilus", GetLocation(GetFirstPC()));

 ActionWait(0.5);
 AssignCommand(oPC, ClearAllActions());
 ActionWait(0.5);
 NoClicksFor(1.5);
 SwitchPlayerCharacter(5);
 SetPartyLeader(5);
 SetNPCSelectability(5, 0);
}

Link to comment
Share on other sites

Hmm... perhaps you should try SpawnAvailableNPC instead of CreateObject.

 

I may have confused myself into thinking that SpawnAvailableNPC wouldn't work in this situation, but my logic seems to have been faulty hah; so I switched it out, but it still freezes.

 

I tried messing around with the .utc file some more (matching it up more with what the other npc's templates look like), but with no success yet.

Link to comment
Share on other sites

Hmm... let me see if I can nail down the essential parts of my script. I'm actually having trouble reading my own script... oops.

 

But I think this works:

void SwitchPC() {

AssignCommand(GetFirstPC(), ClearAllActions());
SetNPCSelectability(5, 1);
ActionWait(0.5);
SpawnAvailableNPC(5, GetLocation(GetFirstPC()));
RemovePartyMember(5);
SwitchPlayerCharacter(5);
SetPartyLeader(5);

}

void main() {

NoClicksFor(1.5);
SetGlobalFadeIn(2.0, 1.0, 0.0, 0.0, 0.0);
AddAvailableNPCByTemplate(5, "p_darthnihilus");
AssignCommand(GetFirstPC(), ClearAllActions());
DelayCommand(0.2, SwitchPC());

}

I think it's just picky about the timing.

Link to comment
Share on other sites

Hmm... let me see if I can nail down the essential parts of my script. I'm actually having trouble reading my own script... oops.

 

But I think this works:

Show spoiler
(hidden content - requires Javascript to show)
void SwitchPC() {

AssignCommand(GetFirstPC(), ClearAllActions());
SetNPCSelectability(5, 1);
ActionWait(0.5);
SpawnAvailableNPC(5, GetLocation(GetFirstPC()));
RemovePartyMember(5);
SwitchPlayerCharacter(5);
SetPartyLeader(5);

}

void main() {

NoClicksFor(1.5);
SetGlobalFadeIn(2.0, 1.0, 0.0, 0.0, 0.0);
AddAvailableNPCByTemplate(5, "p_darthnihilus");
AssignCommand(GetFirstPC(), ClearAllActions());
DelayCommand(0.2, SwitchPC());

}

I think it's just picky about the timing.

 

Well, here's the OnEnter script for the Freedon Nadd Tomb Outside...

Show spoiler
(hidden content - requires Javascript to show)
/ Prototypes
void sub4();
void sub3();
void sub2();
void sub1();

void sub4() {
object oTo_403 = GetObjectByTag("To_403", 0);
if ((!GetLocalBoolean(oTo_403, 50))) {
	if ((GetIsObjectValid(GetObjectByTag("xarga", 0)) && GetIsObjectValid(GetFirstPC()))) {
		AssignCommand(GetObjectByTag("xarga", 0), ClearAllActions());
		DelayCommand(0.1, AssignCommand(GetObjectByTag("xarga", 0), ActionStartConversation(GetFirstPC(), "xarga", 0, 0, 0, "", "", "", "", "", "", 0, 0xFFFFFFFF, 0xFFFFFFFF, 0)));
		SetLocalBoolean(oTo_403, 50, 1);
	}
}
}

void sub3() {
object object1 = SpawnAvailableNPC(GetGlobalNumber("403DXN_PARTY2_NPC2"), GetLocation(GetObjectByTag("sp_cnpc2", 0)));
object object4 = SpawnAvailableNPC(GetGlobalNumber("403DXN_PARTY2_NPC3"), GetLocation(GetObjectByTag("sp_cnpc3", 0)));
AddPartyMember(GetGlobalNumber("403DXN_PARTY2_NPC2"), object1);
AddPartyMember(GetGlobalNumber("403DXN_PARTY2_NPC3"), object4);
}

void sub2() {
SwitchPlayerCharacter(GetGlobalNumber("403DXN_PARTY2_NPC1"));
SetGlobalFadeIn(0.5, 2.0, 0.0, 0.0, 0.0);
}

void sub1() {
while ((GetPartyMemberCount() > 1)) {
	{
		int int2 = 0;
		while ((int2 <= 12)) {
		if (IsNPCPartyMember(int2)) {
			RemovePartyMember(int2);
		}
			(int2++);
		}
	}
}
}

void main() {
object oTo_403 = GetObjectByTag("To_403", 0);
object oEntering = GetEnteringObject();
if ((GetIsPC(oEntering) && (!GetLocalBoolean(oTo_403, 55)))) {
	SetGlobalNumber("410DXN_Begin", 1);
	SetLocalBoolean(oTo_403, 55, 1);
	sub1();
	DelayCommand(0.1, sub2());
	DelayCommand(0.2, sub3());
	DelayCommand(3.0, sub4());
}
}

 

Hope it helps. I don't see the game spawning the party leader first, so it might be automatic?

 

I forget which armband mod it was(Either the Workbox or Mr Defender's), but it had the option of changing the partly leader/player character and it would always freeze...

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...