Salk

[KotOR] Help with an in game cutscene

Recommended Posts

Hello!
 

I am trying to make possible to start and complete the Dantooine quest "Dead Settler" even after finishing the quest "Shen and Rahasia".

 

The solution I thought of is simple: after the cutscene when the two families confront each other, if it does not end in blood, I would unlock the Sandrals main entrance. There the Player can talk to the droid and inform of the death of Casus. There is already unused material in the dan14_sdroid.dlg file which can easily be restored.

 

That same dialogue file uses the script k_pdan_srdr01.ncs to unlock the door when the Player demands to meet Nurik because on a mission from the Council:

void main() {
object oDan14ad_door01 = GetObjectByTag("dan14ad_door01", 0);
SetLocked(oDan14ad_door01, 0);
}

When the cutscene starts, the front door, which was unlocked and open, is closed and locked again (I do not know where this happens). Even if I use the k_pdan_srdr01.ncs in the dan14_cutscene.dlg the door remains locked and I do not understand why.

 

A workaround I found was to add the following to the k_pdan14d_area script:

if ((GetGlobalNumber("DAN_ROMANCE_PLOT") > 2) && (GetGlobalNumber("DAN_ROMANCE_PLOT") <7))  {
object oDan14ad_door01 = GetObjectByTag("dan14ad_door01", 0);
SetLocked(oDan14ad_door01, 0);
}

This does work but it requires that the player leaves the area and enters it again and I would rather go for a simpler method.

 

Can someone help me with this?

 

Thanks!

Share this post


Link to post
Share on other sites

Took me a surprising amount of time to track down, but the script is k_pdan_endcut14 inside the level itself. It's set in the DLG file to fire when the conversation ends (and when it aborts early), and here's the contents:

void main() {
	object object1 = GetItemPossessedBy(GetFirstPC(), "dan16_key");
	int int1 = 1;
	object oNearest = GetNearestObject(8, OBJECT_SELF, int1);
	while (GetIsObjectValid(oNearest)) {
		SetLocked(oNearest, 1);
		AssignCommand(oNearest, ActionCloseDoor(oNearest));
		(int1++);
		oNearest = GetNearestObject(8, OBJECT_SELF, int1);
	}
	DestroyObject(object1, 0.0, 0, 0.0);
}

So it basically locks and closes the doors to the Estate and then takes away your key forever.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks a lot, Fair Strides.

 

I have reworked the two quests (Dead Settler and Sandral/Matale Feud) to my satisfaction, removing two bugs and making the quest possible to finish even if the second one is completed first.

 

I will investigate the k_pdan_endcut14 file!

Share this post


Link to post
Share on other sites

One question, Fair Strades.

 

What file invokes k_pdan_endcut14? I did not find it in the dan14_cutscene.dlg (or am I blind?)

 

I am still trying to figure out the structure.

Share this post


Link to post
Share on other sites

If you open the dan14_cutscene.dlg in DLG Editor (so not KotOR Tool), and click on the top line (the file path/black line), you'll see some DLG-wide properties like skippable, animated camera, and a script to launch when the conversation is over (regardless of what happens in said conversation).

 

The k_pdan_endcut14 is in the "Script that fires when conversation ends" slot, as well as the "Script that fires when conversation aborts" slot.

 

I suppose deleting it from both slots will do the trick, or you can simply make a new blank script, call it k_pdan_endcut14, and compile.

  • Like 1

Share this post


Link to post
Share on other sites

Great!

I didn't think of checking the file path... Anyway I did go for the second solution.

 

If you do not mind helping out with one more thing. Can you tell me when it is appropriate to create a .mod file and when a .rim file? 

 

In my C:\Program Files\LucasArts\Star Wars Knights of the Old Republic\modules folder I have both .mod and .rim files and I was wondering about the difference.

 

I am in the process of moving some files from the Override into modules and I would like to make sure I am not making a mistake.

 

From what I can see, the ERF -> Modules .mod files replace original resources found in the RIM -> Modules .rim files?

 

Thanks again!

Share this post


Link to post
Share on other sites

The .mod and the .rim formats are slightly different, but they accomplish the same purpose in the end.

 

.Rim files are the vanilla resources for levels. The .are, .ifo, and .git make up the normal ".rim" file. Then all of the resources for the level (dialogs, scripts, gff files, .etc) go into a second "_s.rim" file.

 

.Mod files take precedence over .rim files (meaning the game will use .mod before .rim if it finds both) and combine all of the resources into one file only.

 

If you have .mod files, those are from mods or your own creation. Also, to avoid incompatibility issues, when you're making the installer you will want to try inserting the files into the .mod and doing whatever modifications are necessary (given this project, probably nothing that isn't done outside of the files).

 

What I generally do is make .mod files of the original .rim files (so it's a vanilla .mod, basically), and will tell TSL Patcher to install that to the modules folder if the .mod doesn't already exist. Then I can install files to the .mod without fear that the .mod won't be there. The only downside is that people complain about warnings in the installation if they already had the .mod files (since I DO NOT set them to be replaced).

Share this post


Link to post
Share on other sites

I'd also advise to NEVER edit a .rim file, not when modding yourself but certainly not for a mod you release since this can very easily screw up the game by replacing/deleting the original files.

Share this post


Link to post
Share on other sites

A couple of questions more, if you please.

 

1) The .mod file works even if not all the vanilla resources in the <level>.rim and <level>_s.rim file are there? Would the game then use what it finds in the <level>.mod and take the rest from <level>.rim and <level>_s.rim?

 

2) If the resource found in a .mod file is also found in Override, will the latter take precedence?

 

Thanks for your patience.

Share this post


Link to post
Share on other sites

The Override directory takes precedence. You obviously can't use it though for any resources that don't have a unique filename, which is a common problem in TSL especially.

 

I think the MOD is required to have all the RIM's contents. I don't think it can just have selected elements.

Share this post


Link to post
Share on other sites

1. I admit I've never really tried only including part of a level in the .mod. So I have no clue on that one.

 

2. The game would use the Override's copy.

 

Override > .mod > .rim > .BIF archives

Share this post


Link to post
Share on other sites

Thank you, guys.

 

I am taking advantage of your knowledge to ask you for more help... :D

 

In my attempt to make the game more polished, I would like to avoid unnecessary duplication of supposedly unique items. In this present case, I am talking of the Mandalorian Datapads in Kashyyyk as part of the Hidden Hunters quest. The unarmed party is ambushed twice. The first three enemies leave Datapad 1 (kas25_datapad1) and Datapad 2 (kas25_datapad2). In the second ambush, we obtain Datapad 1 and Datapad 2  again, plus a thirdDatapad (kas25_datapad). 

 

Datapad 1 is dropped by kas25_mandalor01 in the first ambush and by kas25_mand_end in the second. Removing the duplicate is a simple matter of removing Datapad from the inventory of the latter.

 

Datapad 2 is dropped by kas25_mandalor02. This enemy appears in both ambushes so my idea was just to swaps him with kas25_mandalor07 (another Mandalorian warrior carrying no special item).

 

The script that deals with the ambushes (both of them) is k_pkas_mandend and the main function is this:

void main() {
object oNearestKas25_mand_end = GetNearestObjectByTag("kas25_mandalor01", OBJECT_SELF, 1);
object oNearestKas25_mandalor02 = GetNearestObjectByTag("kas25_mandalor02", OBJECT_SELF, 1);
object oNearestKas25_mandalor03 = GetNearestObjectByTag("kas25_mandalor03", OBJECT_SELF, 1);
if ((!GetIsObjectValid(GetObjectByTag("kas25_mandtrig2", 0)))) {
oNearestKas25_mand_end = GetNearestObjectByTag("kas25_mand_end", OBJECT_SELF, 1);
}
ChangeToStandardFaction(oNearestKas25_mand_end, 1);
ChangeToStandardFaction(oNearestKas25_mandalor02, 1);
ChangeToStandardFaction(oNearestKas25_mandalor03, 1);
AssignCommand(oNearestKas25_mand_end, sub1(OBJECT_INVALID));
AssignCommand(oNearestKas25_mandalor02, sub1(OBJECT_INVALID));
AssignCommand(oNearestKas25_mandalor03, sub1(OBJECT_INVALID));
}

The IF condition checks whether or not it is the second ambush taking place (from what I understand) and if it is, it simply swap kas25_mandalor01 with kas25_mand_end. I was hoping that I could just add this line:

oNearestKas25_mandalor02 = GetNearestObjectByTag("kas25_mandalore07", OBJECT_SELF, 1);

but there is a problem. The new enemy that replaces kas25_mandalor02 does not become hostile for some reason and I cannot understand why. 

 

Can someone guess what is happening?

 

Thanks!

 

UPDATE: Well, I think I can start to understand something... The line does not work because the object has never been created during the cutscene. I suppose I need to investigate k_pkas_mand3.ncs.

 

SOLVED: Yes, I did need to add the following also to k_pkas_mand3.ncs:

 

if ((!GetIsObjectValid(GetObjectByTag("kas25_mandtrig2", 0)))) {
string1 = "kas25_mandalor07";
}
Edited by Salk

Share this post


Link to post
Share on other sites

About my latest post above, in case anyone might be interested.

 

My solution had a small bug in the cutscene: kas25_mandalor07 would not decloak like the others so I took another path. I left k_pkas_mandend.ncs alone and only changed k_pkas_mand3.ncs adding the lines in bold:

 

void sub2(string stringParam1, location locationParam2) {
object oPC = GetNearestObjectByTag("kas25_mandalor02", OBJECT_SELF, 1);
object oItem = GetFirstItemInInventory(oPC);
CreateObject(1, stringParam1, locationParam2, 0);
if ((!GetIsObjectValid(GetObjectByTag("kas25_mandtrig2", 0)))) {
           while (GetIsObjectValid(oItem)) {
                if (GetTag(oItem) == "kas25_datapad2") {
                  DestroyObject(oItem);
                }
        oItem = GetNextItemInInventory(oPC);
            }
}
}
 
I noticed though how in the vanilla game there is often one unit (mandalor03) in the second ambush that oftens does not charge to attack like the rest but just stays and watches until attacked first. The attack function in k_pkas_mandend.ncs is a bit too complicated for me to understand why it happens.
  • Like 1

Share this post


Link to post
Share on other sites

If you wanted to, you can just add this right at the bottom of the void main():

 

AssignCommand(GetObjectByTag("mandalor03"), ActionAttack(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, GetObjectByTag("mandalor03"))));

 

If that doesn't work, try

 

AssignCommand(GetObjectByTag("mandalor03"), ActionAttack(GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHARACTER_IS_PC, GetObjectByTag("mandalor03"))));

 

And in case the tag is not "mandalor03", then change it and hope it works. You might also need to wrap all of that up in a DelayCommand for 0.1.

Share this post


Link to post
Share on other sites

Okay, the suggestion did work.

I am now facing another problem and I thought it was better asking in this already opened thread rather than starting a new one.

I need to make a few changes to the dialogue with Xor when I meet him the first time on Manaan.

I thought that the .dlg file for the conversation with him was kas_xor_dialog.dlg which I find using KOTOR Tool under the Dialog tree of the manm26ad_s.rim module. But apparently I must be wrong because I changed a few lines, saved the new file and dumped it in the override folder with no result. The dialogue played is still the original one.

Any advice as to what is happening?

Thanks!

Share this post


Link to post
Share on other sites

The only thing I can think of is that you somehow did not save the changes in the file that ended up in your Override, because I did edits to this file and it works fine by just putting it in the Override.

Share this post


Link to post
Share on other sites

The only thing I can think of is that you somehow did not save the changes in the file that ended up in your Override, because I did edits to this file and it works fine by just putting it in the Override.

 

I thought of that too because it seemed to me it was the only possible explanation.

 

But I did load the .dlg file into he editor several times, making sure it was the one in the override folder...

 

Just out of curiosity, what changes did you make? And could I borrow your edited file and see if it does indeed play right in my game?

 

Thanks!

Share this post


Link to post
Share on other sites

Looking at the manaan level, it seems the Messenger trigger uses a .utc from the templates.bif (called "g_xor.utc") and calls that .utc's assigned conversation, which is "k_hxor_dialog". Could perhaps try that one.

Share this post


Link to post
Share on other sites

Looking at the manaan level, it seems the Messenger trigger uses a .utc from the templates.bif (called "g_xor.utc") and calls that .utc's assigned conversation, which is "k_hxor_dialog". Could perhaps try that one.

 

It must be like you say, surely.

 

I will investigate. And thanks again for the help.

Share this post


Link to post
Share on other sites

From what I could understand, the first encounter with Xor uses the k_hxor.dialog.dlg (Fair Stride is correct about this - thanks!) while the next one uses the duplicate .dlg file kas_xor_dialog.dlg. I do not know why they felt the need to make things more messy but now I am done with my changes and am satisfied.

 

The one thing I do not understand though is why the second encounter is triggered in Manaan, Korriban and Kashyyyk but not in Tatooine too, as it should.

 

Tatooine seems to have the trigger (kas_xor_enc.uti) and the script (k_kas_xorattack.nsc)...

 

I suppose something might not work as intended in the relevant part of k_sup_gohawk.ncs:

 

 

    Db_MyPrintString("Go Hawk Start");
    //Do not jump to anywhere if you are on the Ebon Hawk, in the apartment or already in the spaceport/apartment building
    if(!GetIsObjectValid(oEbonHawk) && !GetIsObjectValid(oSpacePort) && !GetIsObjectValid(oTarisApt))
    {
        Db_MyPrintString("Starting Return to Port Section");
        //This allows the players to be ambushed in the starport outside the Ebon Hawk
        if(nXor == 1)
        {
            Db_MyPrintString("Xor 1 == 1");
            if(GetGlobalBoolean("K_XOR_AMBUSH_FIX") == FALSE)
            {
                Db_MyPrintString("Xor 2 Ambush Fix == FALSE");
                if(nPlanet == 20 || nPlanet == 25 || nPlanet == 30 || nPlanet == 35)
                {
                    Db_MyPrintString("Xor 3 Ambush Choosing Planet");
                    SetGlobalNumber("K_XOR_AMBUSH", TRUE);
                    SetGlobalBoolean("K_XOR_AMBUSH_FIX", TRUE);
                    Db_MyPrintString("Xor 4 Hijack");
                    if(nPlanet == 20)
                    {
                        sPlanet = "kas_m22aa";
                    }
                    if(nPlanet == 25)
                    {
                        sPlanet = "manm26ad";
                    }
                    if(nPlanet == 30)
                    {
                        sPlanet = "korr_m33aa";
                    }
                    if(nPlanet == 35)
                    {
                        sPlanet = "tat_m17ab";
                    }
                    StartNewModule(sPlanet, "K_XOR_AMBUSH_SPAWN");
                    return;
                }
            }
        }
 

I am not sure I know how things work but I did notice that there is no entry for Waypoint K_XOR_AMBUSH_SPAWN in the m17ab.git file. Can it be that that's the reason why Xor doesn't spawn the second time on Tatooine?

Share this post


Link to post
Share on other sites

Fair Strides,

unfortunately it seems my attempt is unsuccessful. I will write here what I have done and perhaps you can tell me what mistake(s) I am making.

 

The module of interest is tat_m17ab.

 

Under Blueprint, Triggers we find kas_xor.enc.utt.

 

Every other planet where the ambush triggers correctly contains a Trigger reference to this file in the corresponding .git file. Not Tatooine.

 

I proceeded to add a Trigger entry to the .git file (entry 4) using GFF Editor.

 

post-8946-0-44769500-1464674632_thumb.jpg

 

Under Blueprint, Waypoint we find k_xor_ambush_wp.

 

Every other planet where the ambush triggers correctly contains a Waypoint reference to this file or similar (Kashyyyk has the same, Korriban has k_xor_ambush_spa and Manaan doesn't have any but its .git file uses sw_waypoint001 found under Templates) in the corresponding .git file. Not Tatooine.

 

I proceeded to add an entry to the .git file (entry 25) using GFF Editor. 

 

post-8946-0-57462600-1464671724_thumb.jpg

 

I was not so sure about the coordinates but other than that I was hoping to have things right.

 

I have used EFF editor to open tat_m17ab.rim and replace the original m17ab.git file. All checks out.

 

Still, when I leave the Ebon Hawk in Tatooine, nothing happens.

 

Can you give me some advice as to why?

 

Thanks again.

Edited by Salk

Share this post


Link to post
Share on other sites

In that save, have you ever been in the Tatooine Hangar before?

 

I can look into it more in-depth tomorrow or the next day. Right now trying to save my bacon with the K1R installer.

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.