Note: LucasForums Archive Project
The content here was reconstructed by scraping the Wayback Machine in an effort to restore some of what was lost when LF went down. The LucasForums Archive Project claims no ownership over the content or assets that were archived on archive.org.

This project is meant for research purposes only.

Spawning a person once.

Page: 1 of 1
 Master Zionosis
01-21-2007, 8:28 PM
#1
hi guys and gals, im having a bit of a problem, i need to spawn a person once after a differant script has been fired using another script and if i attached it to a door transition surely it would keep firing again and again becuase the script is still attached to the door transition, please can someone help me because this is a real pain and i don't know what to do.
 stoffe
01-21-2007, 8:34 PM
#2
hi guys and gals, im having a bit of a problem, i need to spawn a person once after a differant script has been fired using another script and if i attached it to a door transition surely it would keep firing again and again becuase the script is still attached to the door transition, please can someone help me because this is a real pain and i don't know what to do.

You can set a Local boolean on the door when the script has run once, and then check at the start of the script if that variable has been set before proceeding. That way you can block the code from being run more than once. Like:


void main() {
// Abort script if it has already run.
if (GetLocalBoolean(OBJECT_SELF, 40))
return;

// ... do what the script should do here ...

// Set that the script has run
SetLocalBoolean(OBJECT_SELF, 40, TRUE);

}
 Master Zionosis
01-22-2007, 12:49 PM
#3
Exelant thanks stoffe, but how do i make it so that the script connected to the door only runs after another particular script has fired?
 stoffe
01-22-2007, 2:00 PM
#4
Exelant thanks stoffe, but how do i make it so that the script connected to the door only runs after another particular script has fired?

You can set a global variable in the other script, and then check if that global variable is set in the door script. Add a new global boolean variable to globalcat.2da, then use it with the SetGlobalBoolean() and GetGlobalBoolean() functions to set and check for it. The text in the name column in globalcat.2da is what you pass as the first parameter to those two functions.
 Master Zionosis
01-22-2007, 2:36 PM
#5
I sort of know what you mean, i have opened the globalcat.2da file and seen the booloean's but i dont know how the script layout is supposed to look, could you please post what the script is supposed to look like, lets just say the boolean is "DAN_ZAEN_DOOR_SPAWN".
 stoffe
01-22-2007, 3:59 PM
#6
I sort of know what you mean, i have opened the globalcat.2da file and seen the booloean's but i dont know how the script layout is supposed to look, could you please post what the script is supposed to look like, lets just say the boolean is "DAN_ZAEN_DOOR_SPAWN".

Since I don't know what else your scripts are supposed to be doing, insert that code where the yellow lines are in the below examples:


void main() {
// ... do what the script should do here ...

// ST: Set global indicating script has run...
SetGlobalBoolean("DAN_ZAEN_DOOR_SPAWN", TRUE);
}



void main() {
// ST: Abort if the other script has not run yet.
if (!GetGlobalBoolean("DAN_ZAEN_DOOR_SPAWN"))
return;

// ST: Abort this script if it has already run.
if (GetLocalBoolean(OBJECT_SELF, 40))
return;

// ... do what the script should do here ...

// ST: Set that the script has run
SetLocalBoolean(OBJECT_SELF, 40, TRUE);
}


Lines in green are comments describing what the line below does.
 Master Zionosis
01-22-2007, 4:32 PM
#7
Brilliant thanks Stoffe, but i just remembered another key point, i also only want the door script to fire if you havn't allready recruited Zaen.
 stoffe
01-22-2007, 5:05 PM
#8
Brilliant thanks Stoffe, but i just remembered another key point, i also only want the door script to fire if you havn't allready recruited Zaen.

The easiest way of checking that is probably to make another global boolean for it, which you set in the script that recruits your NPC. Then you check for that boolean value in a similar manner as above. (Just remember to add the new global boolean to globalcat.2da as well, or the game won't know about it.)
 Master Zionosis
01-22-2007, 6:45 PM
#9
im sorry stoffe but as im a beginer with scripts could you please demonstrait the scripts that i need to use. i need the scripts that tells to spawn a person but not to fire if they have allready been recruited. Thanks Stoffe, forgive my lack of understanding.
 stoffe
01-22-2007, 7:13 PM
#10
im sorry stoffe but as im a beginer with scripts could you please demonstrait the scripts that i need to use. i need the scripts that tells to spawn a person but not to fire if they have allready been recruited. Thanks Stoffe, forgive my lack of understanding.

Please post the script source code you use for
Recruiting your npc (i.e. adding it to the player's group)
The door script
The script that "must be run before the door script may trigger"


That would make it easier to try to give meaningful examples rather than attempting to guess what it is you are trying to do. :)
 Master Zionosis
01-22-2007, 7:24 PM
#11
Please post the script source code you use for
Recruiting your npc (i.e. adding it to the player's group)
The door script
The script that "must be run before the door script may trigger"


That would make it easier to try to give meaningful examples rather than attempting to guess what it is you are trying to do. :)

Ok, here is the script for recruiting Zaen:

void main()
{
RemoveAvailableNPC(7);
AddAvailableNPCByTemplate(7, "p_zaenbenax");
SetGlobalNumber("RH_RECRUIT", 7);
}


And here is the script for the door:

void main()
{

float x=16.67f;
float y=154.27f;
float z=7.28f;
float r=0.0f;
vector vecNPC=Vector(x,y,z);
location locNPC=Location(vecNPC, r);
object oNPC=GetObjectByTag("g_zaenbenax2");
object oTarget=CreateObjec (OBJECT_TYPE_CREATURE,"g_zaenbenax2",locNPC);
object oPC=GetFirstPC();
AssignCommand(oNPC,ActionMoveToObject(oPC));
AssignCommand(oNPC,ActionStartConversation(oPC,"enclavezb"));
}

And here is the script that has to be run before the door script can trigger:

void main() {
object oNPC=GetObjectByTag("g_zaenbenax");
ChangeToStandardFaction(oNPC, 1);

// and if there are any thugs to fight...
object oThug1 = GetObjectByTag("g_zaenbenax");

ChangeToStandardFaction(oThug1, 1);
}

I hope thats correct.
 stoffe
01-22-2007, 9:03 PM
#12
Ok, here is the script (snip)


The recruit script:

void main() {
RemoveAvailableNPC(7);
AddAvailableNPCByTemplate(7, "p_zaenbenax");
SetGlobalNumber("RH_RECRUIT", 7);
}


You are already setting the global number variable RH_RECRUIT to 7 here, so this may be used to check for if the character has been recruited below, so no further changes to that script should be needed.


The other script:

void main() {
object oNPC = GetObjectByTag("g_zaenbenax");
ChangeToStandardFaction(oNPC, STANDARD_FACTION_HOSTILE_1);

// and if there are any thugs to fight...
object oThug1 = GetObjectByTag("g_zaenbenax", 1);
ChangeToStandardFaction(oThug1, STANDARD_FACTION_HOSTILE_1);

SetGlobalBoolean("DAN_ZAEN_DOOR_SPAWN", TRUE);
}


This script now sets the "DAN_ZAEN_DOOR_SPAWN" global boolean variable when run, which can be checked for in the door script. There is something wrong with this script though, since you essentially do the same thing twice. You change the character with the tag g_zaenbenax to the Hostile faction, but do so twice.

If there is more than one character that should become hostile and they have the same tag you need to increase the second parameter of GetObjectByTag() like I've done above. If the second character has a different tag you'll need to set that instead of the one marked yellow above and remove the ", 1" part marked in red again.


The door script:

void main() {
// ST: Abort if the other script has not run yet, if the script has
// already run or if the character has joined the player.
if ( !GetGlobalBoolean("DAN_ZAEN_DOOR_SPAWN")
|| (GetGlobalNumber("RH_RECRUIT") > 6)
|| GetLocalBoolean(OBJECT_SELF, 40))
{
return;
}

// ST: Spawn character from g_zaenbenax2.utc
location locNPC = Location(Vector(16.67, 154.27, 7.28), 0.0);
object oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_zaenbenax2", locNPC);
object oPC = GetFirstPC();

// ST: move character towards the main character and start conversation
AssignCommand(oNPC, ActionMoveToObject(oPC, FALSE, 2.0));
AssignCommand(oNPC, ActionStartConversation(oPC, "enclavezb"));

// ST: Set that the script has run once.
SetLocalBoolean(OBJECT_SELF, 40, TRUE);
}


This has now been changed to check if the character is recruited, if the script has already run once or if the script turning NPCs hostile above has not run. If either of these is the case the rest of the script will not run.

Aside from that I fixed a mistake where you attempted to get the creature by tag for the oNPC variable before it had been spawned, which shouldn't have worked too well.
 Master Zionosis
01-22-2007, 9:13 PM
#13
Brilliant, thanks stoffe your a star, im just gonna try these out now. Thanks again.

But to the bit about changing his faction to hostile, and that i did it twice, that was just an error on my part, there is only supposed to be him, so does that script change now or can i still use the same one?
 RedHawke
01-23-2007, 2:19 AM
#14
I sure hope you aren't going to use a global number called RH_RECRUIT in your released mod? ;)
 Master Zionosis
01-23-2007, 3:35 AM
#15
No, sorry RedHawke, i should of stated that i was going to change it to ZB_RECRUIT, my bad. :)
Page: 1 of 1