Jump to content

Home

Adding New Planets to the Galaxy Map in KOTOR 2


Jyuanii

Recommended Posts

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();
   }
}

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Archived

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

×
×
  • Create New...