Welcome to alls! In this tutorial i wanna tell you how you can add new sabercolors to the lightsabers, also with NPC supports, for your mod.
Are you tired about the only six saber color of default?
Now you can add all colors you desire! You need just to follow these istructions.
What you need:
1 Microsoft visual studio 2010 \ 2012
2 OpenJk
3 two new texture for every new color of your saber: one for the line and one for the glow.
You can put in everypoint you desire, but for praticity we put into the same folder of the other saber textures:
Gfx/effects/sabers/
You need to add
COLORNAME_line
And COLORNAME_glow2 textures.
With photoshop or any other software you can easily edit or change a tube, or make your custom tube.
In this case i wanna add a white saber.
So, make as texture white_line and white_glow2.
Second steps:
Go into shaders/ folder
Copy or paste the default sabers.SHADER file by the assest.pk3 of the game.
At the end of shaders add these two new entry:
gfx/effects/sabers/white_glow { cull disable { map gfx/effects/sabers/white_glow2.tga blendFunc GL_ONE GL_ONE rgbGen vertex } } gfx/effects/sabers/white_line { cull disable { map gfx/effects/sabers/white_line.tga blendFunc GL_ONE GL_ONE rgbGen vertex } }
Okay, now the code part!
Open your solution of Openjk and go into cg_weapons.cpp
You will find these part:
cgs.media.redSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/red_glow" ); cgs.media.redSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/red_line" ); cgs.media.orangeSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/orange_glow" ); cgs.media.orangeSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/orange_line" ); cgs.media.yellowSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/yellow_glow" ); cgs.media.yellowSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/yellow_line" ); cgs.media.greenSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/green_glow" ); cgs.media.greenSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/green_line" ); cgs.media.blueSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/blue_glow" ); cgs.media.blueSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/blue_line" ); cgs.media.purpleSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/purple_glow" ); cgs.media.purpleSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/purple_glow" ); // NEW COLORS cgs.media.whiteSaberCoreShader = cgi_R_RegisterShader( "gfx/effects/sabers/white_line" ); cgs.media.whiteSaberGlowShader = cgi_R_RegisterShader( "gfx/effects/sabers/white_glow" );
as you can see, at the end i register two new shader for the saber, the white color!
now you need to co into cg_media.h
// Saber shaders //----------------------------- qhandle_t forceCoronaShader; qhandle_t saberBlurShader; qhandle_t swordTrailShader; qhandle_t yellowDroppedSaberShader; // glow qhandle_t redSaberGlowShader; qhandle_t redSaberCoreShader; qhandle_t orangeSaberGlowShader; qhandle_t orangeSaberCoreShader; qhandle_t yellowSaberGlowShader; qhandle_t yellowSaberCoreShader; qhandle_t greenSaberGlowShader; qhandle_t greenSaberCoreShader; qhandle_t blueSaberGlowShader; qhandle_t blueSaberCoreShader; qhandle_t purpleSaberGlowShader; qhandle_t purpleSaberCoreShader; qhandle_t whiteSaberGlowShader; qhandle_t whiteSaberCoreShader;
as you can see, here 2 new media entries for the shaders of the white saber.
Now the hardest part.
Go into qcommon\qshared.h and add a new function for your new sabercolor.
// Player weapons effects typedef enum { SABER_RED, SABER_ORANGE, SABER_YELLOW, SABER_GREEN, SABER_BLUE, SABER_PURPLE, SABER_WHITE } saber_colors_t;
okay, done with q_shared.
Now you need to associate the function to the shader, so, when character use the SABER_WHITE, the saber will got as tube and glow the new shader.
You can make this into cg_player.cpp
Locate the static void called dosaber
static void CG_DoSaber( vec3_t origin, vec3_t dir, float length, float lengthMax, float radius, saber_colors_t color, int rfx, qboolean doLight ) { vec3_t mid; qhandle_t blade = 0, glow = 0; refEntity_t saber; float radiusmult; if ( length < MIN_SABERBLADE_DRAW_LENGTH ) { // if the thing is so short, just forget even adding me. return; } // Find the midpoint of the saber for lighting purposes VectorMA( origin, length * 0.5f, dir, mid ); switch( color ) { case SABER_RED: glow = cgs.media.redSaberGlowShader; blade = cgs.media.redSaberCoreShader; break; case SABER_ORANGE: glow = cgs.media.orangeSaberGlowShader; blade = cgs.media.orangeSaberCoreShader; break; case SABER_YELLOW: glow = cgs.media.yellowSaberGlowShader; blade = cgs.media.yellowSaberCoreShader; break; case SABER_GREEN: glow = cgs.media.greenSaberGlowShader; blade = cgs.media.greenSaberCoreShader; break; case SABER_BLUE: glow = cgs.media.blueSaberGlowShader; blade = cgs.media.blueSaberCoreShader; break; case SABER_PURPLE: glow = cgs.media.purpleSaberGlowShader; blade = cgs.media.purpleSaberCoreShader; break; // NEW SABERS case SABER_WHITE: glow = cgs.media.whiteSaberGlowShader; blade = cgs.media.whiteSaberCoreShader; break;
Okay! Now... there is something missing right? Ah, yes! The Dlight! And also the support for the new color for .SAB file and .NPC file.
The dinamic light, the light color emitted by the new blade, is setted again into cg_player. Is little complex this part, so be careful.
The first field to edit is the
Static void cg_rgbforsabercolor
static void CG_RGBForSaberColor( saber_colors_t color, vec3_t rgb ) { switch( color ) { case SABER_RED: VectorSet( rgb, 1.0f, 0.2f, 0.2f ); break; case SABER_ORANGE: VectorSet( rgb, 1.0f, 0.5f, 0.1f ); break; case SABER_YELLOW: VectorSet( rgb, 1.0f, 1.0f, 0.2f ); break; case SABER_GREEN: VectorSet( rgb, 0.2f, 1.0f, 0.2f ); break; case SABER_BLUE: VectorSet( rgb, 0.2f, 0.4f, 1.0f ); break; case SABER_PURPLE: VectorSet( rgb, 0.9f, 0.2f, 1.0f ); break; case SABER_WHITE: VectorSet( rgb, 1.0f, 1.0f, 1.0f ); break;
you can see for every blade color three number. They are float, decimal values. The first is the total amount of red saturation, the second is for the green, the third is for the blue. With the union of the three color gradient you can obtain every other kind of colors for the dinamic light.
In case of the white, you need just to put 1.0 as value for every 3 field, and you will get a white saber.
But HOW obtain the exact value of the color that you want emit your saber for Dlight?
I will answer to this now.
Ever into cg_player... you need to decide the color of the trail that trace your blade with the swings! You can set this here:
Locate: static void CG_AddSaberBladeGo
Function!
And go down, go down down until you will find...
#define SABER_TRAIL_TIME 40.0f // if we happen to be timescaled or running in a high framerate situation, we don't want to flood // the system with very small trail slices...but perhaps doing it by distance would yield better results? if ( saberTrail->lastTime > cg.time ) {//after a pause, cg.time jumps ahead in time for one frame //and lastTime gets set to that and will freak out, so, since //it's never valid for saberTrail->lastTime to be > cg.time, //cap it to cg.time here saberTrail->lastTime = cg.time; } if ( cg.time > saberTrail->lastTime + 2 && saberTrail->inAction ) // 2ms { if ( saberTrail->inAction && cg.time < saberTrail->lastTime + 300 ) // if we have a stale segment, don't draw until we have a fresh one { vec3_t rgb1={255,255,255}; if ( cent->gent->client->ps.saber[saberNum].type != SABER_SITH_SWORD && ( WP_SaberBladeUseSecondBladeStyle( &client->ps.saber[saberNum], bladeNum ) || client->ps.saber[saberNum].trailStyle != 1 ) && ( !WP_SaberBladeUseSecondBladeStyle( &client->ps.saber[saberNum], bladeNum ) || client->ps.saber[saberNum].trailStyle2 != 1 ) ) { switch( client->ps.saber[saberNum].blade[bladeNum].color ) { case SABER_RED: VectorSet( rgb1, 255.0f, 0.0f, 0.0f ); break; case SABER_ORANGE: VectorSet( rgb1, 255.0f, 64.0f, 0.0f ); break; case SABER_YELLOW: VectorSet( rgb1, 255.0f, 255.0f, 0.0f ); break; case SABER_GREEN: VectorSet( rgb1, 0.0f, 255.0f, 0.0f ); break; case SABER_BLUE: VectorSet( rgb1, 0.0f, 64.0f, 255.0f ); break; case SABER_PURPLE: VectorSet( rgb1, 220.0f, 0.0f, 255.0f ); break; case SABER_WHITE: VectorSet( rgb1, 255.0f, 255.0f, 255.0f ); break;
at the end, i added a case for SABER_WHITE. The saberwhite emite a trail with a rgb value of 255 for red, green and blue, too, so a white trail! Yes, dinamic light is in decimals, but these value is into 255 parts!
But How you can calculate the correct rgb value for dinamic light and for the swing trail?
Well, the answer is not into the code.
Open Gtk radiant. Yes, you understood! GTK RADIANT!
No, we not need to make a map, relax! you need to make just a light entity.
After you make a light entities, hit the K button, and you can see the color panel, when you can scroll the triangle and set the RGB color you desire for your light.
After you choice the light color value of your light... take paper and pen or pencil and wrote the 3 value of red, green and blue.
For example... 234, 210, 50.
Okay, when you go here in cg_player, for the trail color you need just to report the value of the light color you choose into radiant.
For the dlight, instead, you need just a simple operation:
234\255 = 0.91
210\255 = 0.82
50\255 = 0.19
okay, now you get the three value to put into Dlight code part.
You ended with cg_players.
Now, just a last thing!
The NPC supports.
Go into npc_stats.cpp it contain the parameter of all stats, the code related the paramter you give to the NPC with NPC files.
Locate these function:
saber_colors_t TranslateSaberColor( const char *name )
and add at the end the white if case.
{ if ( !Q_stricmp( name, "red" ) ) { return SABER_RED; } if ( !Q_stricmp( name, "orange" ) ) { return SABER_ORANGE; } if ( !Q_stricmp( name, "yellow" ) ) { return SABER_YELLOW; } if ( !Q_stricmp( name, "green" ) ) { return SABER_GREEN; } if ( !Q_stricmp( name, "blue" ) ) { return SABER_BLUE; } if ( !Q_stricmp( name, "purple" ) ) { return SABER_PURPLE; } if ( !Q_stricmp( name, "white" ) ) { return SABER_WHITE; }
Now, if you make an NPC with “white” as sabercolor definition, the NPC will have a blade with white color!
Now the last thing! A consolle command for use your new saber!
Go into g_svcmds.cpp
Locate the sabercolor_f command and...
static void Svcmd_SaberColor_f() {//FIXME: just list the colors, each additional listing sets that blade int saberNum = atoi(gi.argv(1)); const char *color[MAX_BLADES]; int bladeNum; for ( bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ ) { color[bladeNum] = gi.argv(2+bladeNum); } if ( !VALIDSTRING( color ) || saberNum < 1 || saberNum > 2 ) { gi.Printf( "Usage: saberColor <saberNum> <blade1 color> <blade2 color> ... <blade8 color> \n" ); gi.Printf( "valid saberNums: 1 or 2\n" ); gi.Printf( "valid colors: red, orange, yellow, green, blue, and purple\n" ); return; } saberNum--; gentity_t *self = G_GetSelfForPlayerCmd(); for ( bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ ) { if ( !color[bladeNum] || !color[bladeNum][0] ) { break; } else { self->client->ps.saber[saberNum].blade[bladeNum].color = TranslateSaberColor( color[bladeNum] ); } } if ( saberNum == 0 ) { gi.cvar_set( "g_saber_color", color[0] ); } else if ( saberNum == 1 ) { gi.cvar_set( "g_saber2_color", color[0] ); } }
well. You not need to do nothing here... the sabercolor function will auto recognize every new colors entry. Build the code and Enjoy your new blades!
i see this will works also for menu g_saber color. function
That's all. i checked the ui_saber_color function also for UI menu and that's call the g_saber color values, so this should works also for menus. (ui_saber_color function is coded into code/ui/ui_main.cpp
Recommended Comments
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now