PDA

View Full Version : Adding New Planets to the Galaxy Map in KOTOR 2


Jyuanii
08-21-2005, 02:11 PM
I read the tutorial for adding new planets to the Galaxy Map in KOTOR 1 here in Holowan Labs, but I'm intending to do this in KOTOR 2, which has different scripts. Can anyone tell me how and which scripts to edit in KOTOR 2?

Darkkender
08-21-2005, 02:34 PM
For the most part you rely upon the same scripts for K2. What K2 really did for us is add some new functions to play with. But most of the core scripting that is refered to in the Tut is still used.

Jyuanii
08-21-2005, 02:44 PM
I looked into the scripts for KOTOR 2 but the scripts mentioned in the tutorial don't exist. I found a few equivalents but they work differently.

stoffe
08-21-2005, 04:55 PM
To add a planet to the galaxy map, you'll need to edit the planetary.2da file to add your planet. Take note of the line number you use, this is what you will call in the scripts. The PLANET_ constants used by the scripts to refer to the standard planets correspond to the line number in planetary.2da for that planet.

There are two scripts attached to the standard Ebon Hawk galaxy map. The script a_galaxymap sets what planets are available on the map, and then opens the map screen. This is the script that is run when the player clicks on the galaxy map placeable. This script exists in the 003EBO_s.rim file in compiled form only. This re-created version compiles to an exact match of that file:


// ST: a_galaxymap.nss (003EBO_s.rim)

#include "k_inc_hawk"

void main() {
if (GetGlobalNumber("003EBO_Atton_Talk") <= 4) {
object oPC = GetFirstPC();
AssignCommand(oPC, ClearAllActions());
AssignCommand(OBJECT_SELF, ActionStartConversation(oPC, "galaxy", FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
return;
}
else if (GetGlobalNumber("003EBO_RETURN_DEST") == 4) {
if (GetGlobalNumber("502OND_End_First") == 0) {
object oPC = GetFirstPC();
AssignCommand(oPC, ClearAllActions());
AssignCommand(OBJECT_SELF, ActionStartConversation(oPC, "galaxy2", FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
return;
}
}
else if (GetGlobalNumber("003_IN_COMBAT") == 1) {
object oPC = GetFirstPC();
AssignCommand(oPC, ClearAllActions());
AssignCommand(OBJECT_SELF, ActionStartConversation(oPC, "galaxy", FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
return;
}

int nWorld = 0;
for (nWorld = PLANET_DANTOOINE; nWorld < PLANET_LIVE_01; ++nWorld) {
SetPlanetAvailable(nWorld, FALSE);
SetPlanetSelectable(nWorld, FALSE);
}

if (GetGlobalNumber("900MAL_Open") == 1) {
for (nWorld = PLANET_DANTOOINE; nWorld < PLANET_LIVE_01; nWorld++) {
int nPlanet = nWorld;
SetPlanetAvailable(nPlanet, TRUE);

if (nWorld == PLANET_MALACHOR_V)
SetPlanetSelectable(nPlanet, TRUE);
}
}
else if (GetGlobalNumber("262TEL_Escape_Telos") == 1) {
for (nWorld = PLANET_DANTOOINE; nWorld < PLANET_LIVE_01; nWorld++) {
int nPlanet = nWorld;

if (nWorld != PLANET_MALACHOR_V) {
SetPlanetAvailable(nPlanet, TRUE);

if (nWorld != PLANET_PERAGUS)
SetPlanetSelectable(nPlanet, TRUE);
}
}

if (GetGlobalNumber("401DXN_Visited") == 0) {
SetPlanetAvailable(PLANET_DXUN, FALSE);
SetPlanetSelectable(PLANET_DXUN, FALSE);
}
else {
SetPlanetSelectable(PLANET_ONDERON, FALSE);
}
}
else {
SetPlanetAvailable(PLANET_HARBINGER, TRUE);
SetPlanetSelectable(PLANET_HARBINGER, TRUE);
SetPlanetAvailable(PLANET_PERAGUS, TRUE);
SetPlanetSelectable(PLANET_PERAGUS, FALSE);
}

SetPlanetAvailable(PLANET_TELOS, FALSE);
SetPlanetSelectable(PLANET_TELOS, FALSE);
SetPlanetAvailable(PLANET_M4_78, FALSE);
SetPlanetSelectable(PLANET_M4_78, FALSE);
SetPlanetAvailable(PLANET_EBON_HAWK, FALSE);
SetPlanetSelectable(PLANET_EBON_HAWK, FALSE);

int nPlanet = GetCurrentPlanet();

// ST: In Space or Hyperspace
if ((GetGlobalNumber("003EBO_BACKGROUND") == 8) || (GetGlobalNumber("003EBO_BACKGROUND") == 10)) {
nPlanet = PLANET_EBON_HAWK;
SetPlanetAvailable(PLANET_EBON_HAWK, TRUE);
}

SetPlanetSelectable(nPlanet, FALSE);
ShowGalaxyMap(nPlanet);
}


The other script is k_sup_galaxymap, for which source code can be found in the Scripts.bif file with KotorTool. This is the script that is run when the player selects a planet to travel to on the galaxy map screen, and does the actual "travel" so to speak.

It plays the travel movie, changes the room animation for the cockpit windows and replaces the holographic world placeable in the main hold, and sets the Global 003EBO_RETURN_DEST which the Ebon Hawk Exit Trigger uses to transition you to the correct area when you leave the ship.

The SetPlanetAvailable() function toggles if the planet appears at all on the map screen, while SetPlanetSelectable() determines if the map allows you to select that planet for travel. Set the first parameter when you call those functions to the line number of your planet in planetary.2da.

If Available is TRUE but Selectable is set to FALSE, the text set in the lockedoutreason column in planetary.2da will be displayed if the player tries to go to that planet on the map screen.

* * *

Then you need to modify the Ebon Hawk exit script to allow the player to actually leave the ship onto your new planet. There are two scripts used for this.

The first is tr_leave_ehawk, found in 003EBO_s.rim in compiled form. This is the OnEnter script for the trigger covering the exit-ramp of the Ebon Hawk. When recreated it looks something like:


// ST: tr_leave_ehawk.nss (003EBO_s.rim)

#include "k_inc_hawk"

void ExitToDxunOnderon();
void ExitToKorriban();
void DoEbo004ExitHawk();

void main() {
object oEnter = GetEnteringObject();

// ST: Merged tr_leave_ehawk from 003EBO and 004EBO so they both
// work if put in Override.
if (GetTag(GetArea(oEnter)) == "004EBO") {
DoEbo004ExitHawk();
return;
}

SetNPCSelectability(NPC_KREIA, TRUE);
SetNPCSelectability(NPC_ATTON, TRUE);

if (oEnter == GetFirstPC()) {
// ST: In combat
if (GetGlobalNumber("003_IN_COMBAT") == 1) {
BarkString(OBJECT_INVALID, 135165);
return;
}
// ST: In space
else if (GetGlobalNumber("003EBO_RETURN_DEST") == 8) {
BarkString(OBJECT_INVALID, 129942);
return;
}
// ST: Landed on Dxun
else if (GetGlobalNumber("003EBO_RETURN_DEST") == 4) {
SetGlobalFadeOut();
SetFadeUntilScript();
AurPostString("Leaving the hawk", 15, 22, 10.0);
DelayCommand(1.0, ExitToDxunOnderon());
}
// ST: Landed on Korriban
else if (GetGlobalNumber("003EBO_RETURN_DEST") == 6) {
SetGlobalFadeOut();
SetFadeUntilScript();
AurPostString("Leaving the hawk", 15, 22, 10.0);
DelayCommand(1.0, ExitToKorriban());
}
else {
SetGlobalFadeOut();
SetFadeUntilScript();
ShowPartySelectionGUI("check_party_gui", -1, -1, TRUE);
}
}
}

void ExitToDxunOnderon () {
if (GetGlobalBoolean("401_FIRST_ENTER") && (GetGlobalNumber("502OND_End_First") > 0)) {
AurPostString("Atton is selectable", 5, 19, 10.0);
SetNPCSelectability(NPC_ATTON, TRUE);
}
else {
SetNPCSelectability(NPC_ATTON, FALSE);
AurPostString("Atton is NOT selectable", 5, 19, 10.0);
}
AurPostString("Showing party selection", 5, 20, 10.0);
ShowPartySelectionGUI("check_party_gui");
}

void ExitToKorriban() {
SetNPCSelectability(NPC_KREIA, FALSE);
AurPostString("Kreia is NOT selectable", 5, 19, 10.0);
AurPostString("Showing party selection", 5, 20, 10.0);
ShowPartySelectionGUI("check_party_gui");
}

void DoEbo004ExitHawk() {
if (GetEnteringObject() == GetFirstPC()) {
int nDest = GetGlobalNumber("003EBO_RETURN_DEST");
string sDest;

switch (nDest) {
case 0: sDest = "106PER"; break;
case 1: sDest = "201TEL"; break;
case 2: sDest = "262TEL"; break;
case 3: sDest = "301NAR"; break;
case 4: sDest = "401DXN"; break;
case 5: sDest = "601DAN"; break;
case 6: sDest = "701KOR"; break;
case 7: sDest = "801DRO"; break;
case 8: sDest = "ERROR"; break;
case 9: sDest = "901MAL"; break;
case 10: sDest = "ERROR"; break;
default: sDest = "ERROR";
}

if (sDest == "ERROR")
AurPostString("EBO ERROR: No module sepcified!", 5, 15, 10.0);
else
StartNewModule(sDest, "WP_from_ebonhawk");
}
}


Since this script is named exactly the same in both 003EBO (normal Ebon Hawk) and 004EBO (Red Eclipse infested EHawk), I've modified it to work for both areas so it can be used in the override folder. The script determines if the ship can be exited and which party members are available at this location, and opens the party selection screen.

The second script is check_party_gui, also found in compiled form in 003EBO_s.rim. This script is fired by the party selection GUI screen when you have picked your party members, and loads the proper module depending on the 003EBO_RETURN_DEST variable set by the galaxy map, mentioned above. When recreated it looks something like:



// ST: check_party_gui.nss (003EBO_s.rim)

#include "k_inc_hawk"

void ExitEbonHawk() {
int nDest = GetGlobalNumber("003EBO_RETURN_DEST");
string sDest;

switch (nDest) {
case 0: sDest = "106PER"; break;
case 1: sDest = "201TEL"; break;
case 2: sDest = "262TEL"; break;
case 3: sDest = "301NAR"; break;
case 4: sDest = "401DXN"; break;
case 5: sDest = "601DAN"; break;
case 6: sDest = "701KOR"; break;
case 7: sDest = "801DRO"; break;
case 8: sDest = "IN_TRANSIT"; break;
case 9: sDest = "901MAL"; break;
case 10: sDest = "IN_TRANSIT"; break;
default: sDest = "ERROR";
}

if (sDest == "ERROR")
AurPostString("EBO ERROR: No module sepcified!", 5, 15, 10.0);
else if (sDest == "IN_TRANSIT")
AurPostString("Flying through space, wooooooooo!", 5, 15, 10.0);
else
StartNewModule(sDest, "WP_from_ebonhawk");
}

void main() {
SetGlobalFadeIn();
int nParam = GetRunScriptVar();

if (!nParam) {
object oPC = GetFirstPC();

AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, ActionJumpToLocation(GetLocation(GetObjectByTag("WP_from_outside"))));
}
else {
SetGlobalBoolean("003_PARTY_SPAWN", FALSE);
ExitEbonHawk();
}
}

Jyuanii
08-22-2005, 03:53 PM
Thanks stoffe -mkb-, you've been a great help.

RedHawke
08-23-2005, 02:09 AM
I vote that this gets posted as a Tutorial in the Scripting section... any seconds! ;)

Excellent post stoffe! That is really handy! :D

ChAiNz.2da
08-23-2005, 08:19 AM
I vote that this gets posted as a Tutorial in the Scripting section... any seconds! ;)

Excellent post stoffe! That is really handy! :D
Excellent suggestion RedHawke... how's this? :D

http://www.lucasforums.com/showthread.php?t=151295

Thank You stoffe for the very helpful instructions :thumbsup:

Blacknadger
08-30-2005, 08:22 PM
Thanks for explaining how this works stoffe, Iíve found it very useful. I was wondering if you could explain how you would then write a script to make a planet accessible at a later point in the game, rather than from the beginning. I have given it several tries, but I don't seem to be getting anything to work. Thanks in advance.

Edit: I managed to work this out, so please disregard the above question.