Hobbes

Module NPC and Object Placement

Recommended Posts

Hello Deadly Stream Community,

 

Does anyone know if there is a step by step tutorial on object and NPC placements, etc.?  Which method is more practical to achieve this: scripting, or a GFF editor? I am trying to learn about module editing and would like to know how to place NPC's, objects, etc. The tutorials I have found don't seem to be at a novice level, although I do have some background in game scripting, and I enjoy learning about this. Hints and tips are greatly appreciated! Thanks!!

 

Share this post


Link to post
Share on other sites

Yeah, we need more tutorials that, to be frank, are written for amateurs; I say this because those tutorials would explain things in detail using basic wording.

 

As for your question, I'll first outline how an NPC (or any object, really) is positioned in-game and then outline the two methods for placing objects in-game and their pros and cons.

 

...

 

An object in-game possesses two things: a vector of three floats containing its XYZ coordinates, and a float containing its directional facing (between 0.0 and 360.0).

 

Scripting:

The first, and most common, way to spawn objects is through scripting, whether the script is launched from a conversation, entering a level, or a reaction to an event. No matter what, it's all the same basic formula:

 

*It should be noted that in all the examples below, the marks are for example only and cannot be there when compiling the scripts*

 

  Reveal hidden contents

 

 

Pros:

  • Highly adaptable
  • Easy to access
  • Can be used at almost any time
  • Perfect for delayed or conditional placement
  • Simple and universal directional facing

Cons:

  • Cannot spawn doors, triggers, sounds

 

Module-editing (GFF Editor):

Placing or moving objects in the module itself requires a GFF Editor (like K-GFF) and editing the .git file for the module. Each object has its own XYZ coordinates that can all be edited easily, but the directional facing is tricky...

 

Cameras:

A camera's facing is determined by its Orientation field, wherein the first of the four numbers (we don't edit the second or third, normally) is equal to

 

cos( ( - 90.0) / 2)

 

and the fourth number is equal to

 

sin( ( - 90.0) / 2).

 

Placeables and Doors:

Placeables and Doors both use a Bearing field, and this is a radian (everything in regards to facing for everything is a radian), so

 

( + 90) * 0.0174532925.

 

If you're resulting number is greater than 4.7207963267949, then you'd subtract 7.857239039871151612 and use the result.

 

Creatures, Waypoints, and Triggers:
These three all have an XOrientation and a YOrientation field, and the results for both, respectively, are:

 

cos()

 

and

 

sin().

 

Sounds, Encounters, and Stores:

These either don't have orientations, or in the Stores' case, the orientation is thought worthless. However, the Encounters can have spawn points, and these have an Orientation field that is a bearing (like the placeables and doors).

 

Pros:

  • Fine control
  • Ability to place encounters, cameras, sounds, and triggers

Cons:

  • Objects listed spawn the first time you enter the level, and so this is a one-time job
  • Complications in directional facing
  • Like 2

Share this post


Link to post
Share on other sites
  On 11/30/2015 at 9:53 PM, djh269 said:

Hello Fairstrides, 

 

Can the tslpatcher place .utc files within a .mod?

 

Cheers

Please... No thread-hijacking here. :)

 

In short, yes. You'd set the Destination to "modules\" and click the "Set!" button to confirm it.

Share this post


Link to post
Share on other sites

Even though I'm not OP, this is really great. Thank you so much Fair Strides!

I also highly agree that more beginner friendly tutorials would be amazing! Even though I'm not actively looking into getting into Kotor Modding atm, I'd definitely be more tempted to do so if I knew that there were a lot of great tutorials.

Share this post


Link to post
Share on other sites
  On 11/30/2015 at 10:24 PM, Fair Strides said:

Please... No thread-hijacking here.  :D

 

In short, yes. You'd set the Destination to "modules\<module name, no extension>" and click the "Set!" button to confirm it.

 

My bad haha

 

Thanks for the advice!

 

  On 11/30/2015 at 10:28 PM, l2daorch said:

Even though I'm not OP, this is really great. Thank you so much Fair Strides!

I also highly agree that more beginner friendly tutorials would be amazing! Even though I'm not actively looking into getting into Kotor Modding atm, I'd definitely be more tempted to do so if I knew that there were a lot of great tutorials.

 

I concur, there should be more beginner friendly tutorials.

Share this post


Link to post
Share on other sites

Thank you all for your replies they were really helpful!

 

I was also wondering if there was any progress made for making new maps for the K-tool module editor? 

if so it would also be a good way to edit modules.

 

I look forward to hearing more about the modding world of Kotor thanks again!

Share this post


Link to post
Share on other sites
  On 11/30/2015 at 5:54 AM, Fair Strides said:

Objects listed spawn the first time you enter the level, and so this is a one-time job

I figured I'd ask in this thread, rather than start another. Does the addition of placeables via a GIT edit only work if you have not previously entered a level? The same as changing an appearance ID value in a UTC for example? I can get a placeable to spawn via a modified on-enter script, but it doesn't show up when added via a GIT edit for a level I have previously visited.

Share this post


Link to post
Share on other sites

Yeah, anything in the GIT file is only spawned the first time you enter the level.

 

This is because the .git file is modified to have all of the file data for every listing (so every field from a .utc, .utd, .utp, .etc) and is then saved in a .sav file. Each level has its own .sav file and they're all added to SAVEGAME.sav (and are then used in place of the .rim/.mod files (except for resources like scripts or dialogs; these are never in the .sav).

Share this post


Link to post
Share on other sites

Ah ok, cheers. If only I'd known that before I spent two hours constantly re-editing the GIT and UTP and recompiling the model trying to figure out what was broken....

 

I guess I'll stick to scripts for testing and leave the GIT edit for the final/release version.

Share this post


Link to post
Share on other sites
  On 4/25/2016 at 8:42 AM, DarthParametric said:

Ah ok, cheers. If only I'd known that before I spent two hours constantly re-editing the GIT and UTP and recompiling the model trying to figure out what was broken....

 

I guess I'll stick to scripts for testing and leave the GIT edit for the final/release version.

You Can put The .git in your Override folder for testing. This Override .git will then overwrite The data from The.sav file and thus reset The mofule rvery time You enter/load, but that's usually find for testing.

 

Just make Sure to properly place The .git in The corresponding .mod for The final mod and delete The override one.

Share this post


Link to post
Share on other sites

Btw, on the subject of scripting to spawn placeables, how do you spawn multiple placeables in a single script? I've tried multiple variants based on old posts over at LF, but I can't get any to compile. For example:

void main()
{
	if ((GetEnteringObject() == GetFirstPC()))
	{
		if( GetObjectByTag( "PLC_abcd1" ) == OBJECT_INVALID )
			{
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd1", Location(Vector(-85.25,19.45,9.66545), 131));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd2", Location(Vector(-55.5,-6.15,9.722), 90));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd3", Location(Vector(5.7,41.65,9.66551), 180));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd4", Location(Vector(38.25,0.00,9.66545), 180));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd5", Location(Vector(0.00,-44.25,10), 90));
			}
		ExecuteScript("on_enter_ORIG", OBJECT_SELF);
    } 	
}

Share this post


Link to post
Share on other sites
  On 4/26/2016 at 8:35 AM, DarthParametric said:

Btw, on the subject of scripting to spawn placeables, how do you spawn multiple placeables in a single script? I've tried multiple variants based on old posts over at LF, but I can't get any to compile. For example:

 

Add ".0" to the end of the number at the end of each of the CreateObject lines. Those numbers are the degree facing and need to be a float, not an int.

Share this post


Link to post
Share on other sites

 

  On 4/26/2016 at 8:35 AM, DarthParametric said:

Btw, on the subject of scripting to spawn placeables, how do you spawn multiple placeables in a single script? I've tried multiple variants based on old posts over at LF, but I can't get any to compile. For example:

void main()
{
	if ((GetEnteringObject() == GetFirstPC()))
	{
		if( GetObjectByTag( "PLC_abcd1" ) == OBJECT_INVALID )
			{
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd1", Location(Vector(-85.25,19.45,9.66545), 131));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd2", Location(Vector(-55.5,-6.15,9.722), 90));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd3", Location(Vector(5.7,41.65,9.66551), 180));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd4", Location(Vector(38.25,0.00,9.66545), 180));
			CreateObject(OBJECT_TYPE_PLACEABLE, "PLC_abcd5", Location(Vector(0.00,-44.25,10), 90));
			}
		ExecuteScript("on_enter_ORIG", OBJECT_SELF);
    } 	
}

 

Here's a script from my Kashyyk module mod I'm making (change the OBJECT_TYPE_CREATURE to: OBJECT_TYPE_PLACEABLE)

 
void main()
{
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath01", Location(Vector(122.55, 95.42, 10.27), 0.0)); 
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath02", Location(Vector(112.68, 96.82, 10.21), 180.0));
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath03", Location(Vector(141.95, 64.33, 8.73), 0.0)); 
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath04", Location(Vector(130.02, 26.52, 8.04), 180.0)); 
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath05", Location(Vector(129.33, 28.95, 8.03), 0.0)); 
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath06", Location(Vector(91.01, 82.79, 10.05), 180.0));
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath07", Location(Vector(95.53, 81.52, 10.05), 0.0));    
    CreateObject(OBJECT_TYPE_CREATURE, "k25ab_kinrath08", Location(Vector(102.66, 86.68, 10.08), 180.0));
 
    DestroyObject(OBJECT_SELF);
 
   ExecuteScript("lightningm25ab", OBJECT_SELF);
   ExecuteScript("peoplespawn25ab", OBJECT_SELF);
   ExecuteScript("thingsspawn25ab", OBJECT_SELF);
 
}

Share this post


Link to post
Share on other sites
  On 4/26/2016 at 8:52 AM, Fair Strides said:

Add ".0" to the end of the number at the end of each of the CreateObject lines. Those numbers are the degree facing and need to be a float, not an int.

Gah, figures it would be something so trivial. I must have tried half a dozen versions and presumably that was the problem every time.... I didn't even notice. Sigh. Thanks for correction.

 

GIT in the Override testing is all well and good for confirming everything works before release, but it's a pain in the ass having it reset the triggers every time. Scripting is far more useful for iterative testing.

Share this post


Link to post
Share on other sites

If you want to spam a lot it's generally better to use a loop rather than definite each one individually.

Of course that's better if the location is defined in the .git.

Share this post


Link to post
Share on other sites
Guest Qui-Gon Glenn

Sorry to resurrect an old thread, but do we have a list anywhere of KotOR Module Names with their corresponding on_enter scripts?

 

Asking for a friend :P

 

If not, perhaps I'll make a sheet.

Share this post


Link to post
Share on other sites

Here's the module list half of it.

 

K1 modules:

 

  Reveal hidden contents

 

 

TSL modules:

 

  Reveal hidden contents

 

Share this post


Link to post
Share on other sites
Guest Qui-Gon Glenn
  On 11/16/2017 at 2:34 AM, DarthParametric said:

Here's the module list half of it.

 

K1 modules:

 

  Reveal hidden contents

 

 

TSL modules:

 

  Reveal hidden contents

 

LOL!

 

I was just building this same list, as a resource for my fam.

 

Of course it exists! Thank you for sharing!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.