PDA

View Full Version : NPC action script.


Grindel
05-23-2006, 07:33 PM
I'm working on the first part of the first level of a new game... This should be fun. Anyways to the point. All i want to do for now is to make an npc run down the hall kill two monsters and then defeat a force shield to break the pc out of their cell. This is takeing place on 351NAR (just for referance). The npc will run down the cellblock from it's spawning point near the entrance. It encounters twom monster (not sure wut yet, probably droids of some type). IT then engages the droids in combat, defeats them. Then breaks the force shield on the PC's cell and initiates a dialogue.

I realise all of this is simplistic programming. It's structured even, no need for advanced constructs like objects, and use of polymorphisum or inharetance. However i'm totally lost when it comes to this language implamentation. I have tried writeing custom code from scratch and have always met with utter failure. as a programmer who has little problem wrting compleat java applications or really efficient C++ utilities If find this failure to write a working script infinatly frustrateing.

well advanced thanks for the impending help that i'm sure someone will lend me.
I'll be here bashing my head aginst semi cryptic tutorials and code snippits trieing to formulate a half working script that likely will not compile.

Grindel
05-23-2006, 07:44 PM
Here is one of my first questions about how to do this.

ActionForceMoveToLocation(location locDestination,
int bRun = FALSE,
float fTimeout = 30.0f);

I understand this is the function to be used to script an NPC to move.
here is where i run into my first problem. "location" defined by the NWN lexicon like this

location loc = Location(objArea, vecPosition, fFacing);

so next I look up these data types.

objArea = huh??
vector = (float x, float y, float z)
float = duh

The nwn lexicon expectedly defines an object using fuzzy language.
An integer that represents a particular object in the world
(essentially a pointer to a real object).
I know what an object is. I know it a fuzzy thing it could mean anything at all. However why should I referance an object that dosen't exist just to move and npc from location (err vector xyz) to another location (cough** vector xyz). dose this mean I have to do some type of prestidigitation with invisable objects.

Darth333
05-24-2006, 12:50 AM
I never really used the nwnlexicon. If you look at nwscript.nss (in the bifs) you should see this:

// 382: Force the action subject to move to lDestination.
void ActionForceMoveToLocation(location lDestination, int bRun=FALSE, float fTimeout=30.0f);


// 215: Create a location.
location Location(vector vPosition, float fOrientation);

// 142: Create a vector with the specified values for x, y and z
vector Vector(float x=0.0f, float y=0.0f, float z=0.0f);


This should do the trick :)

void main()
{
object oNPC = GetObjectByTag("my_npc_tag");
AssignCommand(oNPC, ActionForceMoveToLocation (Location(Vector(0.00,0.00,0.00), 0.0)));
}

stoffe
05-24-2006, 07:41 AM
All i want to do for now is to make an npc run down the hall kill two monsters and then defeat a force shield to break the pc out of their cell. This is takeing place on 351NAR (just for referance). The npc will run down the cellblock from it's spawning point near the entrance. It encounters twom monster (not sure wut yet, probably droids of some type). IT then engages the droids in combat, defeats them. Then breaks the force shield on the PC's cell and initiates a dialogue.


Is this supposed to be a cutscene or an in-game action sequence that the player watches happen from their cell? If it's an in-game sequence something like this might work if you put it as the Heartbeat script of an Invisible Placeable that's used as scene controller:


void main() {
int iStage = GetLocalNumber(OBJECT_SELF, 30);
object oNPC = GetObjectByTag("TagOfTheNPC"); // Set the Tag of the NPC here.
object oEnemy1 = GetObjectByTag("TagOfEnemy1"); // Set the Tag of one of the droids here.
object oEnemy2 = GetObjectByTag("TagOfEnemy2"); // Set the Tag of the other droid here.
object oDoor;
location lLoc;

switch (iStage) {
case 0:
lLoc = Location(Vector(1.0, 2.0, 3.0), 0.0); // Set X/Y coordinates NPC should appear here.
oNPC = CreateObject(OBJECT_TYPE_CREATURE, "ResrefOfTheNPC", lLoc); // Set ResRef of NPC template here.
SetLocalBoolean(oNPC, 87, TRUE); // Disable Generic AI
AssignCommand(oNPC, ActionAttack(oEnemy1));
SetLocalNumber(OBJECT_SELF, 30, 1);
break;

case 1:
if (GetIsObjectValid(oEnemy1) && !GetIsDead(oEnemy1)) {
AssignCommand(oNPC, ActionAttack(oEnemy1));
}
else if (GetIsObjectValid(oEnemy2) && !GetIsDead(oEnemy2)) {
AssignCommand(oNPC, ActionAttack(oEnemy2));
}
else {
SetLocalNumber(OBJECT_SELF, 30, 2);
}
break;

case 2:
oDoor = GetObjectByTag("TagOfForceField"); // Set tag of Force field here.
AssignCommand(oNPC, ActionMoveToObject(oDoor, TRUE));
AssignCommand(oNPC, ActionDoCommand(DoDoorAction(oDoor, DOOR_ACTION_BASH)));

SetLocalNumber(OBJECT_SELF, 30, 3);
break;

case 3:
oDoor = GetObjectByTag("TagOfForceField"); // Set tag of Force field here.

if (!GetIsObjectValid(oDoor) || GetIsOpen(oDoor))
SetLocalNumber(OBJECT_SELF, 30, 4);
break;

case 4:
AssignCommand(oNPC, ActionMoveToObject(GetFirstPC(), FALSE));
AssignCommand(oNPC, ActionStartConversation(GetFirstPC()));
SetLocalBoolean(oNPC, 87, FALSE); // Re-enable Generic AI
SetLocalNumber(OBJECT_SELF, 30, 4);
RemoveHeartbeat(OBJECT_SELF); // Stop script from running on scene controller.
break;
}
}


Now, this is untested since I don't have the game where I am right now, so it's possible that I've forgotten about something, but maybe it can be of some help at least.

As for your troubles with the Move functions, only parts of NWNLexicon are applicable to scripting in the KotOR games. The version of NWScript used in KotOR branched off from the NWN variant fairly early, and there are a few fundamental differences beyond that due to differences in the game engines.

In this particular case the Area object reference has been removed from the function parameters, as Darth333 said. This is because in KotOR you can only have one Area per module (eliminating the need to specify which Area to move to), while in NWN you can potentially have hundreds of Areas in the same module.

(Another major difference to keep in mind if you use NWNLexicon as reference is that KotOR is much more restrictive in how it allows variables to be set on objects. In KotOR you can only set LocalNumbers (0-255 range) between index 0 - 31 and LocalBooleans (FALSE/!FALSE) between index 0 - 159. NWN on the other hand don't use a fixed number of index slots, but allows you to use a Tag as variable identifier instead, allowing as many Locals as you wish. NWN also allows you to set Int values (32 bit signed integer), Floats, booleans, strings, locations and Object references as Locals. This restricts what you can do with KotOR scripting quite a bit.)