Created By: Hector 'Xian' Ramos
Difficulty Scale: Easy

  INTRO   In this simple tutorial we are going to add a jetpack. We are going to use two keys for navigation, one for Flying Up and another for Flying Down. The code below is taken directly from my patch, Boba Fett Suit, altough I edited it slightly...   To start, extract theses files to your patch directory, keeping the directory tree intact:   - COG\KYLE.COG - JKL\STATIC.JKL - MISC\ITEMS.DAT - UI\JKSTRINGS.UNI   We are algo going to use two new COGs, Fly_up.cog and Fly_dn.cog. Keep reading...   MAKING THE JETPACK   Open kyle.cog and add these lines to the symbols section:   // Jetpack Begin sound jpdamaged=probegethit02.wav local // Sound to make when player is shot down sound jpfly=crowenginewhine02.wav local // Jetpack engine sound. TIEENGINEWHINE01.wav is another good alternative. Make your own new sound if you want.   template smoke_heavy=+heavysmoke local // Big cloud of smoke for damaged jetpacks template jpsmoke=+jpsmoke local // Jetpack exhaust smoke template jpfire=+jpfire local // Jetpack fire trail   int channel=-1 local // Used for looping jetpack sound int is_on=0 local // Determines jetpack's status int fuel=300 local // Maximum fuel int underwater=0 local // For checking if the player is underwater or not int sectorflags local // Ditto int t_vec_x local // The following int t_vec_y local // are used for int p_vec_x local // the jetpack int p_vec_y local // thrusts   vector thrust_vector local vector player_vector local   flex x local flex y local flex z local   message pulse // New COG message/section for decreasing fuel, applying thrusts, etc // Jetpack End   Now we are going to the bottom of the file, and make a new message/section just before 'end'   # ........................................................................................   pulse:     end   That does nothing as it is, so let's add the code that detects if the player is underwater or not:   # ........................................................................................   pulse:   underwater=0; // Make sure underwater is reset to 0! if(!(GetThingFlags(player) & 0x2000000)) // If these flags are not met, then... underwater=0; // The player is not underwater! else // But if they are met... { if (is_on==1) // and the jetpack is activated... { call stop_engine; // STOP IT! Print("Jetpack can't function while underwater!"); // Alert the player } underwater=1; // Set underwater to 1... }   end   So we basically checked to see if the player has the underwater flags (0x2000000) and if he does not have them, we set underwater to 0. If the player does have these flags, we check to see if the jetpack is on, and then stop it and print a message to the user.   Now, we are going to add the jetpack ignition code. Paste this below the above code, but above 'end':   if(fuel>0 & is_on==0 & GetInv(player,116)>0 & underwater<1) // If player has fuel, is hitting the Fly Up key (Inventory 116) and is NOT underwater, continue... { Print("Jetpack Activated"); // Tell him he turned on his jetpack ClearPhysicsFlags(player, 0x1); // Clear him from the effects of gravity... DetachThing(player); // Detach him is_on=1; // States that the jetpack is on if(channel==-1) // Play the engine sound { channel = PlaySoundThing(jpfly, player, 0.0, -1, -1, 0x81); ChangeSoundVol(channel, 1.0, 0.75); } }   Now we are going to add the actual flying stuff. Paste this below the above code:   // Use fuel, fly if(is_on==1) // If activated { if(fuel>0) // If has fuel { fuel=fuel-1; // Then decrease the fuel by one unit call show_fuel; // Display amount of fuel if(Rand() < 0.3) // Randomize upward drifting smoke { CreateThingAtPos(jp_smoke, GetThingSector(player), GetThingPos(player), '270 0 0'); } CreateThingAtPos(jp_fire, GetThingSector(player), GetThingPos(player), '270 0 0'); // Create fire trail CreateThingAtPos(jp_fire, GetThingSector(player), GetThingPos(player), '270 0 0'); // Twice for cooler effect if (GetInv(player,116)==1) // If Fly Up key (116) is activated... { ApplyForce(player,VectorSet(0.0, 0.0, 80.0)); // Apply upward force } if (GetInv(player,117)==1) // Or if Fly Down key is activated... { ApplyForce(player,VectorSet(0.0, 0.0, -80.0)); // Apply downward force } // The following is a bunch of calculations thrust_vector=GetThingThrust(player); player_vector=VectorScale(GetThingLVec(player), 80.0); t_vec_x=VectorX(thrust_vector); t_vec_y=VectorY(thrust_vector); p_vec_x=VectorX(player_vector); p_vec_y=VectorY(player_vector); if(t_vec_x>0) ApplyForce(player,VectorSet(p_vec_y,-p_vec_x,0)); if(t_vec_x<0) ApplyForce(player,VectorSet(-p_vec_y,p_vec_x,0)); if(t_vec_y>0) ApplyForce(player,player_vector); if(t_vec_y<0) ApplyForce(player,VectorSet(-p_vec_x,-p_vec_y,0)); } else { call stop_engine; // So if there is no fuel left, we are going to stop the engine } if(GetAttachFlags(player)>0) // If player lands on earth { call stop_engine; // Stop the engine } } else { if(fuel<300 && GetAttachFlags(player)>0 && GetThingHealth(player)>0) // If jetpack is off and player is alive and on earth { fuel=fuel+2; // Add some fuel call show_fuel; // Display fuel } if(channel != -1) // Stop engine sound { StopSound(channel, 0.1); channel = -1; } } Return;   That's it. You have seen the calls to stop_engine and show_fuel throughout this code, so we are going to add them now below the above code:   stop_engine: SetPhysicsFlags(player, 0x1); // Add gravity is_on=0; // Nope, it's off if(channel != -1) // Stop the sound { StopSound(channel, 0.1); channel = -1; } SetInv(player,116,0); // Neither Fly Up or SetInv(player,117,0); Fly Down are activated Print("Jetpack Deactivated"); Return;   show_fuel: // Now we have some if statements that check the current amount of fuel and print the correct equivalent percentage. if (fuel==300) Print("Jetpack 100%"); else if (fuel==285) Print("Jetpack 95%"); else if (fuel==270) Print("Jetpack 90%"); else if (fuel==255) Print("Jetpack 85%"); else if (fuel==240) Print("Jetpack 80%"); else if (fuel==225) Print("Jetpack 75%"); else if (fuel==210) Print("Jetpack 70%"); else if (fuel==195) Print("Jetpack 65%"); else if (fuel==180) Print("Jetpack 60%"); else if (fuel==165) Print("Jetpack 55%"); else if (fuel==150) Print("Jetpack 50%"); else if (fuel==135) Print("Jetpack 45%"); else if (fuel==120) Print("Jetpack 40%"); else if (fuel==105) Print("Jetpack 35%"); else if (fuel==90) Print("Jetpack 30%"); else if (fuel==75) Print("Jetpack 25%"); else if (fuel==60) Print("Jetpack 20%"); else if (fuel==45) Print("Jetpack 15%"); else if (fuel==30) Print("Jetpack 10%"); else if (fuel==15) Print("Jetpack 5%"); else if (fuel==0) Print("Jetpack 0%"); Return;   That's all for KYLE.COG. Now we should continue with STATIC.JKL, so we can add the upward drifting smoke and the fire that is spewed downward. Open static.jkl and scroll down to the last empty line. Paste this in...   ##### Templates information #### Section: TEMPLATES   // Remember to update this count! World templates 2   #Name: Based On: Params: // Jetpack Smoke! Drifts upward. +jpsmoke none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.800000 physflags=0x20000 vel=(0.000000/0.000000/0.100000) angvel=(0.000000/90.000000/0.000000) typeflags=0x3e material=jpsmoke.mat range=0.030000 elementsize=0.005000 count=8   // Jetpack Fire! Spewed downward. +jpfire none orient=(0.000000/0.000000/0.000000) type=particle move=physics timer=0.800000 physflags=0x20000 vel=(0.000000/0.000000/-2.500000) angvel=(0.000000/90.000000/0.000000) typeflags=0x3e material=jpfire.mat range=0.030000 elementsize=0.005000 count=8   end ################################   Notice that both of these new templates are based on the original +smoke template from master.tpl. The only big differences are their names (+jpsmoke and +jpfire) and these two edited lines:   vel=(X / Y / Z) material=*.mat   In +jpsmoke we set the velocities to 0.000000/0.000000/0.100000, giving it a slow, upward motion and the material to jpsmoke.mat. For +jpfire we set the velocities to 0.000000/0.000000/-2.500000, giving it a faster, DOWNWARD motion. The material is jpfire.mat. Obviously, neither of these two MATerials exist, so you are going to use MATMASTER to make your own new COLOR MATs, like grey for jpsmoke.mat and orange/red for jpfire.mat. Or simply download Boba Fett Suit and use my MATs (and sound if you want to).   Close and save static.jkl. Open items.dat:   In items.dat we are going to add the inventory numbers 116 and 117, use throughout kyle.cog. 116 will be the Fly Up command and 117 the Fly Down command. Edit items.dat's last few lines so they look like this (new stuff in RED):   goal15 115 0 1000 0x040   # Jetpack - Begin f_jump 116 0 1 0x122 cog=fly_up.cog f_jump 117 0 1 0x122 cog=fly_dn.cog # Jetpack - End   hotkeyOffset 150 0 99999 0x000     # =============== # # MAX Bins = 199 # # =============== #   end   What we did was set the inv. numbers 116 and 117 to use fly_up.cog and fly_dn.cog. f_jump stands for which BM the game will use for displaying these new items. You would see or (depending on your settings) if these commands do show up somewhere. They should be in the inventory when you hit the [ and ] keys, but I'm not sure. With the above example, you can see that the game will search for a file named ic*****, the ***** being the first five letters of the BM you specified in items.dat, and ## being either 8 or 16, depending on your display settings. BM files ending in 8 are 8-bit 256 color files, and the ones ending in 16 are 16-bit truecolor files.   Close items.dat and open jkstrings.uni. This is one big file, so make sure your editor shows the line's number, and scroll down to line 722. It should say:   "ACTIVATE16" 0 "Field Vision"   After that line, add:   "ACTIVATE17" 0 "Fly up" "ACTIVATE18" 0 "Fly down"   Now we have a name for our flying functions, and we can bind some keys to them in Setup. Now scroll back to the top of jkstring.uni and increment the count by two.   We are almost finished. Now we are going to create two totally new COG files. The first one is fly_up.cog and you should paste this into it:   # Jedi Knight Cog Script   symbols   message startup message activated message deactivated   thing player local   end   #####   code   startup: player=GetLocalPlayerThing(); Return;   activated: SetInv (player,116,1); SetInv (player,117,0); Return;   deactivated: SetInv (player,116,0); Return;   end   Save it as fly_up.cog and make a new file, fly_dn.cog, with this inside:   # Jedi Knight Cog Script   symbols   message startup message activated message deactivated   thing player local   end   #####   code   startup: player=GetLocalPlayerThing(); Return;   activated: SetInv (player,116,0); SetInv (player,117,1); Return;   deactivated: SetInv (player,117,0); Return;   end   CONCLUSION   That's all folks. Close it, make a GOB out of it. Make sure to have this structure:   COG\FLY_DN.COG COG\FLY_UP.COG COG\KYLE.COG JKL\STATIC.JKL MISC\ITEMS.DAT UI\JKSTRINGS.UNI   Run JK with the -path command. For example   jk -path jetpack   if you placed the GOB into a jetpack subdirectory of Jedi Knight.   Credits go to Buckley Hopper, I used his original jetpack patch for making my code on Boba Fett Suit. and this tutorial. Expect some more tutorials from me...   E-mail me at Download BOBA FETT SUIT at: