PDA

View Full Version : [TSL]Unique placeables rules for inserting items w/o scripting


oldflash
10-10-2005, 06:21 PM
I know it is a thread started for this but I haven't get the anser which I looking for.
I already say in that thread that I found 2 unique pleacebles where I can put my items without repreating in game and without using a script.

And here come the question.

Is there any rules who decided if is unique place or not because "tag" and "Template ResRef" things seems to be ignored (http://q-net.netfirms.com/programing/06.html and http://q-net.netfirms.com/programing/07.html). I think that "plot item" check could be the anser but it will take me a lot of time to test and maybe someone have already test this and give me an anser. Until now seems to be the key in all this. But searching after places all marked on "plot item" and after that testing everyone it will take me too much time.

I will apreciate any anser.
Thanks

stoffe
10-10-2005, 06:34 PM
The Resref, i.e. the name of the placeable template file without the .utp suffix, is what must be unique across all modules.

If several files with the same filename exist in different modules, the placeable templates in all those modules will be overridden by the one you place in the Override folder, since override has higher priority than the module resources and works on a game-wide scope.

And since the placeable templates with the same name likely aren't identical in all modules, this can cause trouble whenever the placeable appears in the modules you didn't extract and modify the template from.

Files with the same resref but very different actual data appears to be quite common in TSL. The developers likely have done a lot of copy&pasting of resources between modules and then modified the data of the local copy to suit the occasion, but haven't bothered to change the Resref.

* * *

As an aside since you mentioned them:
Tag is mostly used to reference an existing placeable from scripts.
Template Resref is mostly used by the toolset to determine which palette base template a placed template was made from. This was/is used for Toolset utility functions like updating all placed instances of a placeable to match the data of its base template. I don't think it's used for anything in-game.
The Plot flag makes a placeable indestructable and undamagable. This isn't used much in KotOR since you can't attack placeables directly anyway in the game. A script can make a creature attack a placeable though, or apply damage to it.

oldflash
10-10-2005, 06:49 PM
...
I'm realy confused right now. If you have 10 min (no need for more) I will like to test gencrps004 which I have modifyed. I have upoaded in my site but you have to copy that q-net.netfirms.com/programing/gencrps004.zip and paste in browser's address bar
(site rules - no download with direct link). All test is to start a new game, check kreia's copse on EH antd skip the rest of tutorial and on peragus check kreia's corpse on morgue.
Thanks

stoffe
10-10-2005, 07:44 PM
...
I'm realy confused right now. If you have 10 min (no need for more) I will like to test gencrps004 which I have modifyed. I have upoaded in my site but you have to copy that q-net.netfirms.com/programing/gencrps004.zip and paste in browser's address bar
Thanks

Tested. gencrps004.utp is indeed the placeable for Kreia's corpse, which is used in both the Prologue on the Ebon Hawk and in the Peragus Morgue.

The difference, however, is that the placeable with that name in the prologue is set as Static, which makes it into basic scenery that cannot be interacted with, and which cannot run any script. You aren't actually interacting with the corpse there when you (seemingly) click on it, but with an invisible placeable (body_invis.utp) which has been placed on top of the static corpse.

This invisible placeable is interactable and has an inventory which contains the locker keycard you need for the cargo hold locker.

The template named gencrps004.utp in the Peragus Morgue, on the other hand, is interactable and will fire the one-liner dialog that tells the player that the old woman looks dead when you click on it.

Your modified gencrps004.utp, when placed in Override, replaced both those placeables with your own copy which is party interactable and has an inventory containing items, and fires a dialog when clicked on.

This means that the items you placed on the kreia-corpse are available at both the Prologue and in the Morgue. You'll have to use the keyboard keys to cycle through selectable objects in the Prologue to easily find it though, since the Invisible "Body" placeable highlights first since it's closer to the player. But the "Corpse" beneath it has become selectable and lootable as well with your modified file in Override.

The script on your placeable that fires the dialog will also start a dialog about the Exile lying in the medical room in critical condition whenever you click on Kreia's corpse in the Prologue, due to the script set in your placeable, a_dlg.ncs being present in both areas but doing different things (another example of naming conflicts). :)

oldflash
10-11-2005, 03:16 AM
I understand. Seems to be no easy way for this. For short time I was hopping to be some matrix thing "some rules can be broken others can be ignored".
Frome here I take a lot of useable info which in other condition I could miss.
Many thanks for give-me ansers which I was looking for.

Darth333
10-11-2005, 10:52 AM
If you want to quickly and easily search if a placeable is unique, you can use tk102's findrefs (http://www.lucasforums.com/showthread.php?s=&threadid=137588) but now it looks like it's time to get into scripting :devsmoke: Seriously, it's not difficult ;)

If you want to place items on Kreia's corpse, try:


void main() {
object oDoor = GetObjectByTag("MorgueDoor");
SetLocked(oDoor, FALSE);
DelayCommand(1.0, AssignCommand(oDoor, ActionOpenDoor(oDoor)));
//this is the new part we add:
//we identify the object on which we want to place the item by the tag:
object oKreia = GetObjectByTag("kreia_corpse");
if (GetIsObjectValid(oKreia)) {
//place the item on the object:
CreateItemOnObject("my_item template", oKreia);
CreateItemOnObject("my_item template2", oKreia);
}
}

Simply insert the template of your item where it says my_item_template, save as a_doormor.nss and compile :)

Add as much lines "CreateItemOnObject("my_item templatex", oKreia);" as you need to place your different items.

a_doormor.ncs is the script that fires when you unlock the door of the morgue from the console.

ChAiNz.2da
10-11-2005, 11:26 AM
The Plot flag makes a placeable indestructable and undamagable. This isn't used much in KotOR since you can't attack placeables directly anyway in the game. A script can make a creature attack a placeable though, or apply damage to it.
On a similar note.. if you click "Plot Item" for a .uti file... you can't take it out of your inventory either. Or break it down for parts, etc.

Getting it out of your inventory is only achievable by scripting methods. Can come in handy if you want to make sure a PC doesn't accidentally get rid of something in their inventory if you want to try a "does a pc have this, then show this dialogue node" type script ;)

That's what I did for the 'token' in Mono's DL-44 Blaster (http://www.pcgamemods.com/mod/14090.html) mod (The gun shop portion). That way the script just checks to see if the token is in the inventory before his shop dialogue will show. Handy trick if you're uncomfortable messing with globals :)

I was going to do this with my Hak Pad at first... though now I'm wondering why I didn't... hmmm :fist:

oldflash
10-11-2005, 11:37 AM
Many thanks.
In 2h I'll test this and if this thread will not be close I will come with other questions.
I don't know why but my head keep spawning questions.
Until now I've got one bad news and a lot of valuable informations.
I can't belive how lucky I am.
Thanks again.

oldflash
10-11-2005, 07:14 PM
Script works. With one condition. To edit "gencrps004.utp" check box "Has inventory" on "advanced" tab. After all, this script create items but kreia's corpse have no inventory. It's ok for that time when I use mouse to interract with objects. But stoffe -mkb- remind-me in (reply#4) there is a way to play this game with keyboard and in training part (module 101ebo) I have 1 invisible placeable called "body" and behind this one 1 placeable called corpse. Should not be a problem. The corpse is empty anyway.
So far so good. All I need now is to find out how to get .nss from .ncs
One more questions. What .git files are good for and most important can I use this type of files to replace one placeables object with another (unique) one?

Thanke you for support.

stoffe
10-12-2005, 06:58 AM
One more questions. What .git files are good for and most important can I use this type of files to replace one placeables object with another (unique) one?


GIT files contain dynamic information about an area, i.e. it holds information about an area that can change during the course of the game.

Unless you are making a new custom area, or are making major modifications to an area, I would not suggest using the GIT file to add new placeables. You can't place GIT files in the override folder without causing trouble for most areas, so you'd need to pack your modified GIT file into the module itself, which is overkill if you only are going to add a placeable.

Putting GIT files in override will cause trouble when several areas are using the same name of the GIT file (there are som examples of this in the standard game, and it's common in custom modder-made areas based on existing areas as well), and there's a fair chance it may override the GIT in the savegames as well, preventing the game from accessing any stored data and rolling back the area to the default state whenever the player re-enters or reloads a savegame.

I'd suggest using a script to spawn your custom placeable instead. If you make a new container placeable called mybox.utp, then you could spawn it in an area with a script like:

void main() {
CreateObject(OBJECT_TYPE_PLACEABLE, "mybox", Location(Vector(1.0, 2.0, 3.0), 90.0));
}


In the simple example above, mybox is the resref of your new placeable template, 1.0 is the X-coordinate on the map where it should appear, 2.0 is the Y-coordinate and 3.0 is the Z-coordinate (elevation, unlike creatures placeables are not snapped to the walkmesh). 90.0 is the angle the placeable should be facing, in degrees (0 - 360).

oldflash
10-12-2005, 07:30 AM
Always looking for easy way. Thanks for info and for code.
I will use .git files only to get coordonates of existing items and place my objects close to those.
If I combine Darth333's script with yours will work?


void main() {
object oDoor = GetObjectByTag("MorgueDoor");
SetLocked(oDoor, FALSE);
DelayCommand(1.0, AssignCommand(oDoor, ActionOpenDoor(oDoor)));
//insert custom box
CreateObject(OBJECT_TYPE_PLACEABLE, "mybox", Location(Vector(1.0, 2.0, 3.0);
//we identify the object on which we want to place the item by the tag:
object oCustombox = GetObjectByTag("mybox_01");
//ref name will be diferent than tag (custombox01)
if (GetIsObjectValid(oCustombox)) {
//place the item on the object:
CreateItemOnObject("my_item template", oCustombox);
CreateItemOnObject("my_item template2", oCustombox);
}
}

Do you think should work?
Thanks for great help.

stoffe
10-12-2005, 07:43 AM
Always looking for easy way. Thanks for info and for code.
I will use .git files only to get coordonates of existing items and place my objects close to those.
If I combine Darth333's script with yours will work?
(snip)
Do you think should work?


You don't need to get the container you just spawned from the tag, CreateObject() will return a reference to it. Like this:

void main() {
// Standard script part - open the Morgue Door
object oDoor = GetObjectByTag("MorgueDoor");
SetLocked(oDoor, FALSE);
DelayCommand(1.0, AssignCommand(oDoor, ActionOpenDoor(oDoor)));

// Custom script part- spawn a new container and put items in it.
object oCustombox = CreateObject(OBJECT_TYPE_PLACEABLE, "mybox", Location(Vector(1.0, 2.0, 3.0), 0.0));
if (GetIsObjectValid(oCustombox)) {
CreateItemOnObject("my_item template", oCustombox);
CreateItemOnObject("my_item template2", oCustombox);
}
}


This should work when you've replaced mybox with the name of your UTP file and my_item template with the name of the UTI files of the items you wish to spawn. Don't forget to change the coordinates and facing as well. If a box faces into a wall the player will be unable to open it since you'll need to be in front of a placeable to activate/open it.

That said, unless you intend to re-use this custom container placeable in several different places you could just have placed your custom items inside it directly with KotorTool, and they would be spawned along with the container placeable. If so you'd only need to spawn the container and not its content, like:

void main() {
// Standard script part - open the Morgue Door
object oDoor = GetObjectByTag("MorgueDoor");
SetLocked(oDoor, FALSE);
DelayCommand(1.0, AssignCommand(oDoor, ActionOpenDoor(oDoor)));

// Custom script part- spawn a new container
CreateObject(OBJECT_TYPE_PLACEABLE, "mybox", Location(Vector(1.0, 2.0, 3.0), 0.0));
}

oldflash
10-12-2005, 08:11 AM
That's great. And easy. And really nice. Thanks.
I like how you "touch" that code.
You just give me the idea to put more containers in different places in same area (like Atton's force cage which will spawn "remaining" bag after shield's down).
Thanks again.

Darth333
10-12-2005, 11:33 AM
If you want to spawn containers in different areas of the game, check the 3rd post of this tutorial: http://www.lucasforums.com/showthread.php?t=143536 at the section "How to spawn a container when I enter an area" :)


I will use .git files only to get coordonates of existing items and place my objects close to those.

You'll have a lot of phun if you do this...to get the coordinates of the location where you want to spawn your containers or else, you can use the whereami armband: http://www.lucasforums.com/showthread.php?s=&threadid=144260 ;)

oldflash
10-12-2005, 06:24 PM
Done. :)
I still wasn't use whereami armband and take coord. from .git file. That's was because my freetime was shorten than normal (only 1h :(( ). But the result it was not so bad (http://q-net.netfirms.com/scr/index2.html). First pic was on first test. The rest was from second. Tomorrow I will use the armbad and put the loccker in right position close to all the others. At least remanings bag from Atton's cage was like I need. Looks like it was drop something. PERFECT. :)
I use this code:

void main() {
object oDoor = GetObjectByTag("MorgueDoor");
SetLocked(oDoor, FALSE);
DelayCommand(1.0, AssignCommand(oDoor, ActionOpenDoor(oDoor)));
//this is the new part we add:
//ok with this1
CreateObject(OBJECT_TYPE_PLACEABLE, "lockerlg0", Location(Vector(49.51067352295, -56.07303237915, 9.096794128418), -0.228615615964));
//
//we identify the object on which we want to place the item by the tag:
object oAttoncage = GetObjectByTag("AttonCageBlocker");
if (GetIsObjectValid(oAttoncage)) {
//place the item on the object:
CreateItemOnObject("a_helmet_05", oAttoncage);
CreateItemOnObject("w_melee_06", oAttoncage);
}
}

Beside that I make 1 custom locker (lockerlg0.utp) where I put a lot of items, and for forcecage set on inventory, off useable. I still need to test if will not be problems with next forcecages (on telos-TSF, telos-secret academy, nar-shaddaa - droid cage and telos-exchange facility: Ithoryan cage).
Since I don't know how to decomp. ncs I will use spawning containers when I enter in new area and spawning crystal formations on dantooine cave. :D
Thanks for helping me on this.
(I haven't programing on last 9 years and my mind works on slow motions)
I just find out that the game put some items in MY locker!. Isn't that cool or what.
:)) (http://q-net.netfirms.com/scr/3.html)

General Kenobi
10-13-2005, 10:55 AM
So I didn't see them listed anywhere while reading through this thread so, what are the two containers utp names that are unique in-game? I'm assuming you can specify their inventory with custom stuff so that would be kewl.

Inquiring minds wish to know...lol ;)

:ben:
General Kenobi

Darth333
10-13-2005, 11:06 AM
So I didn't see them listed anywhere while reading through this thread so, what are the two containers utp names that are unique in-game? I'm assuming you can specify their inventory with custom stuff so that would be kewl.

Inquiring minds wish to know...lol ;)

:ben:
General Kenobi
YI didn't verify but you could as well create your own unique container and place it where you want in the game ;)

oldflash
10-13-2005, 11:51 AM
First locker is a copy of lockerlg001.utp:
filename lockerlg0.utp; tag lockerlg0; template resref lockerlg0 and now it's unique. In this I put some items in inventory since I intend to use only once in all game.

Second place where I put items is Atton's force cage.
filename forcecageblk001.utp; tag AttonCageBlocker; template resref forcecageblk001; location (KT) Rims/Modules/101PER/Blueprints,Placeables. This one is extracted from game, saved under same name. I make some modif on this one. After opening (with doubleclick) in "advanced" tab I check "Has Inventory" box and uncheck "Party Interact" and "Useable". That's because it's not enought to spawn items if that target have't inventory slots.
This placeable is part of the game's objects and is not unique. I use-it just to be shure I will have no conflict with other mods and it's just good for what I need.

You still need to adjust orientation for locker if you want to use this.

General Kenobi
10-13-2005, 04:59 PM
Thanks for the heads up D3 & oldflash :thumbsup:

:ben:
General Kenobi

oldflash
10-13-2005, 06:06 PM
I really need to ask orels I will not sleep tonight. Is any method to convert (or revert) .ncs to ,nss?
Except stoffe's method: see the matrix. :) I'm to dumb to do this.
Thanks again for help.

Darth333
10-13-2005, 10:26 PM
There's DeNCS available at starwarsknigths.com but you also have the scripts here: http://pcgamemods.com/mod/14269.html

And finally, you can always do it manually: http://www.torlack.com/index.html?topics=nwndata_ncs (it's pretty useful to verify the scripts decompiled with DeNCS as sometimes there are weirdnesses)

kdsphantom
10-14-2005, 03:37 AM
Hello
I was reading this thread alot trying to recreate the scripts and working with them. Trying to learn and get more familiar writing, editing, and dealing with scripts, before during and after i starting working with my own, even on my own post (that darth333 helped me on) i made.

2 questions, does or can "GetObjectByTag" replace the 3 locations x,y,z markers needed IF the object is a door or like a communication terminal, that is something locked in place by the game, a immoveable object?

and 2nd question heh, how do you paste into here, the scripts with the pretty blue backgrounds and that ? heh i havent figured that part out?

thank you, and thank you oldflash, General, Stoffe and Darth i learned just reading this post.
kdsphantom

RedHawke
10-14-2005, 04:40 AM
and 2nd question heh, how do you paste into here, the scripts with the pretty blue backgrounds and that ? heh i havent figured that part out?
[code] put your script here [/code ] (Don't put a space between the ending "e" of code and the last bracket.)

I hope this helps! :D

kdsphantom
10-14-2005, 05:33 AM
Thank you buddy
:)

stoffe
10-14-2005, 08:39 AM
does or can "GetObjectByTag" replace the 3 locations x,y,z markers needed IF the object is a door or like a communication terminal, that is something locked in place by the game, a immoveable object?


Unless I misunderstand what you are asking:

The GetObjectByTag() function returns a reference to the first object in the module that has a tag matching what is specified in the first function parameter.

This can be any type of dynamic object existing in the game world that has a tag field; creatures, items, placeables, doors, sounds, waypoints, triggers, encounters, stores, the area or the module itself. Regardless of type, the first object with the matching tag will be returned.

The second, optional parameter can be used to iterate through all objects in the module with this tag, if several objects share the same tag.

The function is typically used to retrieve a game object so a script can perform an operation on it... apply effects, run scripts, issue actions, set variables or remove the object, for example.

If you want to get the coordinates of an existing object in the game, you can use the function along with the GetPosition() (only the coordinates) or GetLocation() (coordinates and facing) function. Like:

void main() {
location lLoc = GetLocation(GetObjectByTag("gencorps04"));
}

kdsphantom
10-14-2005, 11:47 AM
Yes your explaination is exactly what i was looking for. Not exactly in this case to use in a GetLocation use, but that was because i didnt know you could :)

I tried to compile my first script yesterday and after some problems darth333 help me solve fix it. But i still had questions about "GetObjectByTag" which you jsut answered so my script can be changed from

CreateObject( OBJECT_TYPE_CREATURE, "n_hk50_01", Location(Vector(37.6546,-39.6384,9.5015), 0.0));


To, and the x,y,z are the same, that is the same location on the map


CreateObject( OBJECT_TYPE_CREATURE, "g_assassindrd02", GetLocation(GetObjectByTag("news_report", 0)), 0);


and to my eternal happiness the script compiled AND fired up in my mod, due to what i learned here
thank you
kdsphantom