Jump to content

Home

Swapping characters


Dan Warial

Recommended Posts

Hi, first I want to say that I've always wanted to mod KotOR since I found out about this forum several years ago. Though back then because of my young age and inadequate English, I didn't even manage to create a custom item :D . But today I want to try again. I've managed to create custom module, character and working dialogue. The only eluding part are scripts.... but I'll manage somehow.

 

As for my question, I want to ask if it's possible to swap characters? By that I mean if you can create a double of your character and place him on Ebon Hawk for instance, and yourself play as a Bastila for example. Is writing a script like that possible? Actually it should be since on Leviathan you can play as a party member and in TSL you fight yourself....

 

So maybe better question would be, where can I find those scripts? :p My search ended fruitlessly, but maybe someone had already experimented with something like this and has ready solution stashed somewhere... :p I would be very grateful for some guidance here :p

 

Also the second question... I know how to place character in the custom module, but how do you inject him into an existing one? I couldn't find a tutorial for this, so I would love some help here.

Link to comment
Share on other sites

That's exactly what I was looking for! Thank you very much!

 

Oh also another question, which program you should use to decompress voice over files? I wanted to edit some of vanilla lines for new dialogue, but I can't even install Miles on Windows 8 :(

Link to comment
Share on other sites

Hmm, does someone have a reference how to change your main character? The same way it is done when you are taken aboard Leviathan. Unfortunately this script is only present in compiled form. Maybe someone could point me to a mod which uses similar script? I would be grateful for any help.

Link to comment
Share on other sites

The function is:

SwitchPlayerCharacter(int iNPC)

...with int iNPC being the NPC integer of the character you want to switch to.

 

This function is available in my toolbox for K2 if you want to look at the source scripts. It would be a little different for K1, though. I haven't done it yet for that reason... bit more work (and I primarily made it so I could switch back to my player while testing things; K2 has several of those, but K1 only has the one Leviathan sequence, so it isn't as much an issue).

 

Incidentally, I was unsuccessful in my attempts to clone a character like that. For some reason I could never get them to put on the equipment through the script. That works fine in K2, but I never got it to work in K1.

Link to comment
Share on other sites

Got it work, thank you very much!

 

Another question then :p . I've used a scrip and I'm playing as Carth now and I want to write some character specific dialogue, which will appear only when I'm playing as Carth. What function should I use?

 

Sorry for my newbish questions, but whenever I'm writing a script using data from nwscript.nss and lexycon, I always get either syntax errors, or nothing happens at all.

Link to comment
Share on other sites

Got it work, thank you very much!

 

Another question then :p . I've used a scrip and I'm playing as Carth now and I want to write some character specific dialogue, which will appear only when I'm playing as Carth. What function should I use?

 

Sorry for my newbish questions, but whenever I'm writing a script using data from nwscript.nss and lexycon, I always get either syntax errors, or nothing happens at all.

You can check for the player's tag; the player character normally has no tag, but the party members do. Here's a rough example:

int StartingConditional() {

if( GetTag(GetFirstPC()) == "carth" ) return TRUE;
return FALSE;

}

And then you put that as a conditional script in the dialogue file.

Link to comment
Share on other sites

You can check for the player's tag;

 

Thanks! This should work perfectly!

 

For sound files, if you change the file extension to mp3, you can open them with audacity.

 

Unfortunately while they open, there's no sound, pushing play does nothing.

Link to comment
Share on other sites

Sorry for writing a second post, but I was afraid that no one would see my next question.

 

And the question is: How to achieve the effect of lying NPC? In the same way it happens after the party on Taris, where you get Sith armour. The script responsible for it is unfortunately present only in compiled form, and I can't remember another instance where this effect is used.

 

EDIT: Also, how to destroy a trigger so it's no longer spawning a conversation again and again? I've been trying this one but then conversation stops happening.

void main() {
ActionStartConversation(GetFirstPC(),"tar_miss_npad");
DestroyObject(OBJECT_SELF);
}

Link to comment
Share on other sites

A lying animation is achieved by making the NPC appear to be dead, essentially. In order for them to lie down like they do after the party, you'd need to run a script like this:

 

void main()
{

  object oNPC = GetObjectByTag("NPC_1");

     AssignCommand(oNPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD, 1.0, -1.0));

}

 

The -1.0 signifies that the animation will loop until another animation/action is called. Sometimes I find the -1.0 doesn't work - for God only knows what reason - so I just put in a really large number like 99999999999999999999.9 in its place.

 

As for your trigger, one way to prevent the conversation from happening twice, and make sure it actually works to begin with, is to use local booleans. So, for example, you'd do something like this:

 

void main() 
{
  if ( GetEnteringObject() == GetPartyMemberByIndex(0) ) //This checks to make sure the NPC crossing the trigger is the party leader (i.e. the character the player is currently controlling) so no random NPC can trip the trigger.
  {
     if ( !GetLocalBoolean(OBJECT_SELF, 40) ) //This checks an arbitrary local boolean attached to the trigger file - the number itself can range anywhere from 20ish-50ish.
     {
        ActionStartConversation(GetFirstPC(),"tar_miss_npad"); //I would recommend having an independent object/NPC be assigned to start the conversation, but it works this way as well.
        SetLocalBoolean(OBJECT_SELF, 40, TRUE); //This makes it so the local boolean check above will now fail, preventing this conversation from happening again once it's been fired before.
     }
  }
}

 

I find using local booleans is particularly helpful if you want to reuse the same trigger at a later date. However, if you just want to get rid of the trigger you could set it up like this:

 

void main() 
{
  if ( GetEnteringObject() == GetPartyMemberByIndex(0) )
  {
     ActionStartConversation(GetFirstPC(),"tar_miss_npad");
     DelayCommand(0.5, DestroyObject(OBJECT_SELF));
  }
}

 

Sometimes adding a delay is the way to solve problems like the one you were having, as the game might be destroying the trigger before it has a chance to start the conversation (one of the reasons I prefer using objects/NPCs independent of the trigger to start conversations). Hope this helped.

Link to comment
Share on other sites

Oh, great! Thanks! I want to use trigger area instead of item to save some time. I'm replacing vanilla scene and don't want to build a mod for just this.

 

About booleans... do globals function in the same way? I want an on_enter script to be dependent on your quest stage, so I'm guessing that the best course of action will be to setup them by conversations, like you did with local booleans?

 

EDIT: OK, I found info about global booleans in one of the spawning tutorials, so I think I know how these work.

Link to comment
Share on other sites

Oh, great! Thanks! I want to use trigger area instead of item to save some time. I'm replacing vanilla scene and don't want to build a mod for just this.

 

About booleans... do globals function in the same way? I want an on_enter script to be dependent on your quest stage, so I'm guessing that the best course of action will be to setup them by conversations, like you did with local booleans?

 

EDIT: OK, I found info about global booleans in one of the spawning tutorials, so I think I know how these work.

 

Yeah, reading the tutorials on booleans and such should really get you going. For the most part global booleans are set by conversations - and then checked in onenters like I checked the local boolean in my trigger script - however I've had a few instances where I've needed to set a global boolean when the PC acquires an item or opens a door or something.

Link to comment
Share on other sites

I've another problem, I'm trying to spawn a NPC into player's Taris apartment. Here's the script I'm using:

void main()
{
 object oEntering = GetEnteringObject();
 if (GetIsPC(oEntering))
     {
     if  (!GetIsObjectValid(GetItemPossessedBy(GetFirstPC(), "mission_bik")))
           {
         CreateObject(OBJECT_TYPE_CREATURE, "tar02_mission", Location(Vector(89.27,141.29,0.0), 0.0));

           }

    ExecuteScript("old_02af_en", OBJECT_SELF); 	
    }

}

It's called k_ptar_02af_en as it should, and I've mission_bik in the inventory. What could be wrong?

Link to comment
Share on other sites

  • 2 weeks later...
I'm back and I want to ask for some tips! I'm trying to spawn a NPC lying on a bed but it always spawns on the ground next to it. Maybe you guys have any tips on how to position a NPC to spawn on top of a placeable?

 

Yep, you need to spawn the NPC first, and then spawn the bed under them. I found that out when working on K1R.

Link to comment
Share on other sites

Thanks, your tip helped me a bit, bed spawns properly now... though there must be another secret that is still eluding me...

 

Why, no matter what Z value I input, Mission always remains on ground? Are there any additional steps to be done?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...