Cycle Customization

For developmental things relating to the graphics of the game.
Post Reply
k
Random Identifier & Project Developer
Posts: 345
Joined: Wed Feb 25, 2004 12:54 am
Location: Northern California, USA

Cycle Customization

Post by k »

I take a small break and look what happens. :) Welcome back z-man! And excellent work on the new release about to come out!

Seeing how so much has changed since I last worked on the GUI code I am going to post what I did and we'll go from there. I would have to rewrite it all anyways and figure out the new code formatting thing in Windows. It looks like there have been some more discussions about this whole topic (cycle customizations, movie packs, etc) so we will probably want to solidify a design before working on this some more.

From what I learned while doing this I think we should build a new module for handling all the customizations and let the players mix and match movie packs, movie sounds, default model, textures, etc). I would like to be able to pick (separately) any of the models I have (movie pack and default, default would let me pick the body and wheel textures), any of the walls I have (movie packs and others), and of the floors I have (movie packs and others), etc. The main issue is just how to organize it all. Changing the code to get the current model, texture, and sound settings from a new customization module is fairly straight forward.

On to what I had been working on before 2 out the 10 people at work moved on and my work moved to a much bigger and nicer building... :)

My main goal was to allow users to change cycle and trail colors and the textures used for the cycle, wheels, and trail on the default model (not the movie pack). To keep things simple I decided to create a subdirectory for each set of textures under the textures directory.

Directory Structure:

Code: Select all

+- textures
   +- cycle_body
   +- cycle_wall
   +- cycle_wheel
Here is a list of what I had done so far:
1. Created a new Cycle Configuration menu in the Player menu to let the player pick cycle color, trail color, cycle texture, wheel texture, and trail texture.
2. Created a new Texture menu class that used the File/Directory browsing menu class I had checked in already to display and let the user pick texture files from a directory. The textures are shaded with the currently selected colors.
3. Modified the client and server to pass the three textures and new trail color (problems with the trail color) around to all clients.
4. Created a new System menu that lets you pick the default textures used for all other players (AI and network players).

Things that had not been finished:
1. The current network code does not allow for sending the new trail color when cycles are created at the beginning of each round.
2. The AI code needs some hooks to update colors and textures for existing AI players when the colors and textures are changed in game. New AI players that join at the beginning of a round get the new changes, but existing AI players do not.
3. I hadn't really worked out the trail color with the Team code though that may be because of #1.
4. I forget now if there were other things left to do...
Attachments
New system menu to select the default textures to use for the AI and other network players.
New system menu to select the default textures to use for the AI and other network players.
New cycle config menu with colors and textures.
New cycle config menu with colors and textures.
New player menu with the color selections replaced by the new cycle configuration sub menu.
New player menu with the color selections replaced by the new cycle configuration sub menu.
k
Random Identifier & Project Developer
Posts: 345
Joined: Wed Feb 25, 2004 12:54 am
Location: Northern California, USA

Post by k »

The main problem I ran it to with the new trail color was sending it out to all the other clients. Now that you are back z-man, maybe you can offer some input on this.

When a new round is started the Server sends out a message for each cycle to be created. Two function calls create the contents of the message:
gCycle::WriteCreate(nMessage &m)
gCycle::WriteSync(nMessage &m)

WriteCreate() writes the cycle color as three floats (I think).
WriteSync() writes the cycle state (alive, direction, speed, etc).

The clients read the message in two chunks:
gCycle::gCycle(nMessage &m)
gCycle::ReadSync(nMessage &m)

The problem I ran in to is that because the Create and initial Sync are sent with one message, I can not write the new Trail Color values in gCycle::WriteCreate(nMessage &m) and read them in gCycle::gCycle(nMessage &m). This would break backwards compatability. I also do not want to send the new Trail Color values in WriteSync since the Sync is done every time a cycle changes direction. That would be a waste of bandwidth.

The only solution I have thought of to get around this is to maybe piggy back the Trail Color values on top of the Cycle Color values. Since the color is sent as three floats (r, b, and b) maybe we could add the Trail Color as a small decimal value to the Cycle Color. Older clients would end up with a slightly different color if at all depending on rounding and new clients could subtract out the decimal and convert it to the Trail Color.
Attachments
Testing the new customizations.  My cycle has a different color body and trail.  The AI cycles have different textures from mine.
Testing the new customizations. My cycle has a different color body and trail. The AI cycles have different textures from mine.
k
Random Identifier & Project Developer
Posts: 345
Joined: Wed Feb 25, 2004 12:54 am
Location: Northern California, USA

Post by k »

Here is some of the code that can be re-used if needed. I think I got all the main changes I made. I can dig around some more if needed.

This was my first time using SDL so I just hacked together code pieces for the Texture Selection menu item. It works fine for me, but I may not be doing things correctly. :)

Code: Select all

// ******************************************************
// Texture Selection
//
// Menu item class that displays the selected texture at
// the bottom right of the screen.  It can be configured
// to tint the texture using the supplied RGB values to
// show what the texture would look like on a cycle body,
// wheel, or trail.
//
// Added by k
// ******************************************************
class gMenuItemTextureSelection: public uMenuItemFileSelection
{
protected:
   tString& targ_;
   tString lastTarget;
   int *rgb_;
   int oldrgb_[3];
   int flag_;
   gRealColor color_;
   gTextureCycle* texture1;
   rTexture* texture2;

public:
   gMenuItemTextureSelection(
         uMenu *m, char *tit, const char *help, tString& targ,
         const char *dir, const char *fileSpec, 
         const char *defaultFileName, const char *defaultFilePath,
         int *RGB, int flag = 0,
         int getFilesFlag = 1, bool formatName = true )
         :uMenuItemFileSelection( m, tit, help, targ, dir, 
               fileSpec, defaultFileName, defaultFilePath, getFilesFlag, formatName ),
               targ_( targ ), rgb_( RGB ), flag_( flag )
   {
      m->RequestSpaceBelow( .2 );
      oldrgb_[0] = 15;
      oldrgb_[1] = 15;
      oldrgb_[2] = 15;
      color_.r = 1.0;
      color_.g = 1.0;
      color_.b = 1.0;
      texture1 = NULL;
      texture2 = NULL;
   }

   virtual ~gMenuItemTextureSelection()
   {
#ifndef DEDICATED
      tDESTROY( texture1 );
      delete texture1;
      tDESTROY( texture2 );
      delete texture2;
#endif
   };

   virtual REAL SpaceRight() { return .2; }

   virtual void RenderBackground()
   {
#ifndef DEDICATED
      if ( !sr_glOut )
         return;

      uMenuItemFileSelection::RenderBackground();

      //const char * p1 = (const char *) lastTarget;
      //const char * p2 = (const char *) *target;

      bool bTargetChanged = false;
      bool bColorChanged = false;
      if ( strcmp( (const char *) lastTarget, (const char *) *target ) != 0 )
         bTargetChanged = true;
      if ( ( oldrgb_[0] != rgb_[0] ) || ( oldrgb_[1] != rgb_[1] ) || ( oldrgb_[2] != rgb_[2] ) )
         bColorChanged = true;

      // If the target or color changed reload the texture
      if ( bTargetChanged || bColorChanged )
      {
         // Save the target to optimize checking for menu changes
         lastTarget = *target;

         // Save color to check for external changes
         oldrgb_[0] = rgb_[0];
         oldrgb_[1] = rgb_[1];
         oldrgb_[2] = rgb_[2];
         
         // Convert the color for use by the texture
         color_.r = rgb_[0]/15.0;
         color_.g = rgb_[1]/15.0;
         color_.b = rgb_[2]/15.0;
         se_MakeColorValid( color_.r, color_.g, color_.b, 1.0f );

         // Create the texture object.  The wall texture does not need to be reloaded
         // if only the color changed.
         if ( flag_ == 0 || flag_ == 1 )
         {
            // Body and wheel texture
            tDESTROY( texture1 );
            delete texture1;
            texture1 = new gTextureCycle( *target, color_, 1, 0, ( flag_ == 1 ? true : false ) );
         }
         else if ( bTargetChanged )
         {
            // Wall texture
            tDESTROY( texture2 );
            delete texture2;
            texture2 = tNEW(rTexture)( rTEX_WALL, *target, 1, 0 );
         }
      }

      // If a texture is loaded draw it
      if ( texture1 != NULL || texture2 != NULL )
      {
         // Select the texture
         if ( texture1 != NULL )
         {
            // Draw a white background behind the texture
            REAL r = 1.0;
            REAL g = 1.0;
            REAL b = 1.0;
            se_MakeColorValid( r, g, b, 1.0f );
            glColor3f( r, g, b );
            glRectf( .8,-.8,.98,-.98 );

            texture1->Select();
         }
         else
         {
            texture2->Select();

            // Color the wall texture
            glColor3f( color_.r, color_.g, color_.b );
         }

         // Draw the texture at the bottom right of the menu
         if ( ( texture1 != NULL && texture1->Loaded() ) || ( texture2 != NULL && texture2->Loaded() ) )
         {
            BeginQuads();

            TexCoord(0,0);
            Vertex(0.8, -0.8);

            TexCoord(0,1);
            Vertex(0.8, -0.98);

            TexCoord(1,1);
            Vertex(0.98, -0.98);

            TexCoord(1,0);
            Vertex(0.98, -0.8);

            RenderEnd();     
         }
      }
#endif
   }
};
Here is the code for a simple menu I added somewhere in the System menu for selecting the default textures to use for other players:

Code: Select all

tString sg_CycleBodyTexture = "textures/cycle_body.png";
tString sg_CycleWheelTexture = "textures/cycle_wheel.png";
tString sg_CycleWallTexture = "textures/dir_wall.png";
int     sg_CycleWallStretch = 1.0;

static tConfItem<tString> cyclebodytex("CYCLE_BODY_TEXTURE", sg_CycleBodyTexture);
static tConfItem<tString> cyclewheeltex("CYCLE_WHEEL_TEXTURE", sg_CycleWheelTexture);
static tConfItem<tString> cyclewalltex("CYCLE_WALL_TEXTURE", sg_CycleWallTexture);
static tConfItem<int>     cyclewallstretch("CYCLE_WALL_STRETCH", sg_CycleWallStretch);

void sg_TextureMenu()
{
   int rgb[3] = { 15, 15, 15 };

   uMenu textureMenu("$texture_menu");

   uMenuItemInt cwlsm( &textureMenu,"$cycle_wall_stretch_text",
      "$cycle_wall_stretch_help", sg_CycleWallStretch, 1, 10, 1);

   gMenuItemTextureSelection cwltm( &textureMenu,"$cycle_wall_texture_text",
      "$cycle_wall_texture_help", sg_CycleWallTexture, "textures/cycle_wall/", "*.png",
      "$feature_default_text", "textures/dir_wall.png", rgb, 2 );

   gMenuItemTextureSelection cwtm( &textureMenu,"$cycle_wheel_texture_text",
      "$cycle_wheel_texture_help", sg_CycleWheelTexture, "textures/cycle_wheel/", "*.png",
      "$feature_default_text", "textures/cycle_wheel.png", rgb, 1 );

   gMenuItemTextureSelection cbtm( &textureMenu, "$cycle_body_texture_text",
      "$cycle_body_texture_help", sg_CycleBodyTexture, "textures/cycle_body/", "*.png",
      "$feature_default_text", "textures/cycle_body.png", rgb, 0 );

   textureMenu.Enter();

   // request network synchronisation
   ePlayerNetID::Update();

   for (int i=MAX_PLAYERS-1; i>=0; i--)
   {
      if (ePlayer::PlayerIsInGame(i))
      {
         ePlayer* p = ePlayer::PlayerConfig(i);
         if (p->netPlayer)
            p->netPlayer->RequestSync();
      }
   }
}
Here is the modification to the Player Menu to create a new Cycle Configuration menu. This replaces the color selection code in gMenus.cpp:sg_PlayerMenu(int Player):

Code: Select all

   uMenu cycle_menu("$cycle_config_text");

   uMenuItemInt playerCWLS( &cycle_menu,"$cycle_wall_stretch_text",
      "$cycle_wall_stretch_help", p->cycleWallStretch, 1, 10, 1);

   gMenuItemTextureSelection playerCWLT( &cycle_menu,"$cycle_wall_texture_text",
      "$cycle_wall_texture_help", p->cycleWallTexture, "textures/cycle_wall/", "*.png",
      "$feature_default_text", "textures/dir_wall.png", p->trgb, 2 );

   gMenuItemTextureSelection playerCWT( &cycle_menu,"$cycle_wheel_texture_text",
      "$cycle_wheel_texture_help", p->cycleWheelTexture, "textures/cycle_wheel/", "*.png",
      "$feature_default_text", "textures/cycle_wheel.png", p->rgb, 1 );

   gMenuItemTextureSelection playerCBT( &cycle_menu, "$cycle_body_texture_text",
      "$cycle_body_texture_help", p->cycleBodyTexture, "textures/cycle_body/", "*.png",
      "$feature_default_text", "textures/cycle_body.png", p->rgb, 0 );


   ArmageTron_color_menuitem TB(&cycle_menu,"$player_trail_blue_text",
      "$player_trail_blue_help",
      p->trgb,2);

   ArmageTron_color_menuitem TG(&cycle_menu,"$player_trail_green_text",
      "$player_trail_green_help",
      p->trgb,1);

   ArmageTron_color_menuitem TR(&cycle_menu,"$player_trail_red_text",
      "$player_trail_red_help",
      p->trgb,0);


   ArmageTron_color_menuitem B(&cycle_menu,"$player_blue_text",
      "$player_blue_help",
      p->rgb,2);


   ArmageTron_color_menuitem G(&cycle_menu,"$player_green_text",
      "$player_green_help",
      p->rgb,1);

   ArmageTron_color_menuitem R(&cycle_menu,"$player_red_text",
      "$player_red_help",
      p->rgb,0);
Here is a simple music selection menu item that I never did anything with:

Code: Select all

// Music selection menu item
class gMenuItemMusicSelection: public uMenuItemFileSelection
{
public:
   gMenuItemMusicSelection(
         uMenu *m, char *tit, const char *help, tString& targ,
         const char *defaultFileName, const char *defaultFilePath,
         const char *dir = "music/", const char *fileSpec = "*.mod;*.s3m;*.xm;*.it;*.ogg;*.mp3", 
         int getFilesFlag = 1, bool formatName = false )
         :uMenuItemFileSelection( m, tit, help, targ, 
               dir, fileSpec, defaultFileName, defaultFilePath, getFilesFlag, formatName ) {}

   virtual ~gMenuItemMusicSelection() {}
};
Modifications to ePlayer.h for the new textures and trail color:

Code: Select all

class ePlayer: public uPlayerPrototype

   int trgb[3]; // our trail color

   tString  cycleBodyTexture;
   tString  cycleWheelTexture;
   tString  cycleWallTexture;
   int      cycleWallStretch;

Code: Select all

class ePlayerNetID: public nNetObject

   unsigned short tr,tg,tb; // our trail color

   tString  cycleBodyTexture;
   tString  cycleWheelTexture;
   tString  cycleWallTexture;
   int      cycleWallStretch;
Modifications to ePlayer.cpp for the new textures and trail color:

Code: Select all

extern tString sg_CycleBodyTexture;   // from gMenu.cpp
extern tString sg_CycleWheelTexture;  // from gMenu.cpp
extern tString sg_CycleWallTexture;   // from gMenu.cpp
extern int     sg_CycleWallStretch;   // from gMenu.cpp

Code: Select all

ePlayer::ePlayer() {
...
   confname.Clear();
   confname << "COLOR_TRAIL_B_"<< id+1;
   StoreConfitem(tNEW(tConfItem<int>) (confname,
         "$color_trail_b_help",
         trgb[2]));

   confname.Clear();
   confname << "COLOR_TRAIL_G_"<< id+1;
   StoreConfitem(tNEW(tConfItem<int>) (confname,
         "$color_trail_g_help",
         trgb[1]));

   confname.Clear();
   confname << "COLOR_TRAIL_R_"<< id+1;
   StoreConfitem(tNEW(tConfItem<int>) (confname,
         "$color_trail_r_help",
         trgb[0]));

   confname.Clear();
   confname << "CYCLE_BODY_TEXTURE_"<< id+1;
   StoreConfitem(tNEW(tConfItemLine) (confname,
         "$cycle_body_texture_help",
         cycleBodyTexture));

   confname.Clear();
   confname << "CYCLE_WHEEL_TEXTURE_"<< id+1;
   StoreConfitem(tNEW(tConfItemLine) (confname,
         "$cycle_wheel_texture_help",
         cycleWheelTexture));

   confname.Clear();
   confname << "CYCLE_WALL_TEXTURE_"<< id+1;
   StoreConfitem(tNEW(tConfItemLine) (confname,
         "$cycle_wall_texture_help",
         cycleWallTexture));

   confname.Clear();
   confname << "CYCLE_WALL_STRETCH_"<< id+1;
   StoreConfitem(tNEW(tConfItem<int>) (confname,
         "$cycle_wall_stretch_help",
         cycleWallStretch));
...
   trgb[0]=rgb[0];
   trgb[1]=rgb[1];
   trgb[2]=rgb[2];
...
}

Code: Select all

ePlayerNetID::ePlayerNetID(int p):nNetObject(),listID(-1), teamListID(-1)
   ,pID(p), chatSpam_( se_chatSpamSettings ) {
...
   if (p>=0){
      ePlayer *P = ePlayer::PlayerConfig(p);
      if (P){
         name=P->Name();
         r=   P->rgb[0];
         g=   P->rgb[1];
         b=   P->rgb[2];
         tr=  P->trgb[0];
         tg=  P->trgb[1];
         tb=  P->trgb[2];
         pingCharity=::pingCharity;
         cycleBodyTexture = P->cycleBodyTexture;
         cycleWheelTexture = P->cycleWheelTexture;
         cycleWallTexture = P->cycleWallTexture;
         cycleWallStretch = P->cycleWallStretch;
      }
   }
   else{
      name="AI";
      cycleBodyTexture = sg_CycleBodyTexture;
      cycleWheelTexture = sg_CycleWheelTexture;
      cycleWallTexture = sg_CycleWallTexture;
      cycleWallStretch = sg_CycleWallStretch;
   }
...
}

Code: Select all

ePlayerNetID::WriteSync(nMessage &m){
...
   // Cycle trail color and textures added by k
   m.Write(tr);
   m.Write(tg);
   m.Write(tb);
   m << cycleBodyTexture;
   m << cycleWheelTexture;
   m << cycleWallTexture;
   m << cycleWallStretch;
}

Code: Select all

void ePlayerNetID::ReadSync(nMessage &m){
...
   // Cycle trail color and textures added by k
   if (!m.End())
   {
      m.Read(tr);
      m.Read(tg);
      m.Read(tb);
      m >> cycleBodyTexture;
      m >> cycleWheelTexture;
      m >> cycleWallTexture;
      m >> cycleWallStretch;
   }
   else
   {
      tr = r;
      tg = g;
      tb = b;
      cycleBodyTexture = sg_CycleBodyTexture;
      cycleWheelTexture = sg_CycleWheelTexture;
      cycleWallTexture = sg_CycleWallTexture;
      cycleWallStretch = sg_CycleWallStretch;
   }

   // con << "Player info updated.\n";

   // make sure we did not accidentally overwrite values
   // ePlayer::Update();

   // update the team
   if ( nSERVER == sn_GetNetState() )
   {
      if ( nextTeam )
         nextTeam->UpdateProperties();

      if ( currentTeam )
         currentTeam->UpdateProperties();
   }
}

Code: Select all

void ePlayerNetID::TrailColor( REAL&a_r, REAL&a_g, REAL&a_b ) const
{
   if ( ( static_cast<bool>(currentTeam) ) && ( currentTeam->IsHuman() ) )
   {
      REAL w = 5;
      REAL r_w = 2;
      REAL g_w = 1;
      REAL b_w = 2;

      a_r=(r_w*tr + w*currentTeam->TR())/( 15.0 * ( w + r_w ) );
      a_g=(g_w*tg + w*currentTeam->TG())/( 15.0 * ( w + g_w ) );
      a_b=(b_w*tb + w*currentTeam->TB())/( 15.0 * ( w + b_w ) );
   }
   else
   {
      a_r = tr/15.0;
      a_g = tg/15.0;
      a_b = tb/15.0;
   }
}

Modifications to gCycle.h for the new textures and trail color:

Code: Select all

class gCycle: public eNetGameObject

   gTextureCycle  *wheelTex,*bodyTex;
   gTextureCycle  *customTexture;
   rTexture       *wallTexture;
   int            wallStretch;

   gRealColor trailColor_;
Modifications to gCycle.cpp for the new textures and trail color:

Code: Select all

void gCycle::MyInitAfterCreation(){
...
   if (sn_GetNetState()!=nCLIENT){
      if(!player)
      { // distribute AI colors
         // con << current_ai << ':' << take_ai << ':' << maxmindist <<  "\n\n\n";
         con << "test\n";
         color_.r=1;
         color_.g=1;
         color_.b=1;

         trailColor_.r=1;
         trailColor_.g=1;
         trailColor_.b=1;
      }
      else
      {

      player->Color(color_.r,color_.g,color_.b);
      player->TrailColor(trailColor_.r,trailColor_.g,trailColor_.b);
      }

      se_MakeColorValid( color_.r, color_.g, color_.b, 1.0f );
      se_MakeColorValid( trailColor_.r, trailColor_.g, trailColor_.b, 1.0f );  // changed floor value - k
   }

   if (mp)
      customTexture=new gTextureCycle("moviepack/bike.png",color_,0,0);
   else{
      // Make sure selected body texture exists.
      tString s = "";
      tString bodyTexFile = "textures/cycle_body.png";
      if (player)
      {
         s = tDirectories::Data().GetReadPath( player->cycleBodyTexture );
         if(strlen(s) > 0)
            bodyTexFile = player->cycleBodyTexture;
      }

      // Make sure selected wheel texture exists.
      tString wheelTexFile = "textures/cycle_wheel.png";
      if (player)
      {
         s = tDirectories::Data().GetReadPath( player->cycleWheelTexture );
         if(strlen(s) > 0)
            wheelTexFile = player->cycleWheelTexture;
      }

      // Make sure selected wall texture exists.
      tString wallTexFile = "textures/dir_wall.png";
      if (player)
      {
         s = tDirectories::Data().GetReadPath( player->cycleWallTexture );
         if(strlen(s) > 0)
            wallTexFile = player->cycleWallTexture;
      }

      wheelTex = new gTextureCycle( wheelTexFile, color_, 0, 0, true );
      bodyTex = new gTextureCycle( bodyTexFile, color_, 0, 0 );
      wallTexture = new rTexture( rTEX_WALL, wallTexFile, 1, 0 );
      wallStretch = player->cycleWallStretch;
   }
...
}

Code: Select all

gCycle::gCycle(eGrid *grid, const eCoord &pos,const eCoord &d,ePlayerNetID *p,bool autodelete)
...
   wheelTex = NULL;
   bodyTex = NULL;
   wallTexture = NULL;
   wallStretch = 1;
...
}
Other code in gCycle.cpp: The destructor needs to destroy the new textures. The trail color and textures need to be transmitted to the server and other clients.

Other files had some changes as well, but I don't have time to figure out what they are right now. I'm going to keep a backup of this version in case it is ever needed.
Last edited by k on Wed Mar 09, 2005 5:40 pm, edited 1 time in total.
User avatar
Z-Man
God & Project Admin
Posts: 11717
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Looks very good an exciting! I especially like that you abstracted away the generic file selection menuitem. I was dimly aware about the directory scanning code, but I must have overlooked the menuitem. The code for the texture selection menuitem looks clean to me. Only tDESTROY/delete is redundant, one of them should be enough. tDESTROY is, AFAIR, just a wrapper for "delete and set pointer to null".

About the cycle trail color transfer problem: I can't really remember there being a reason to to simply take the values of the body color from the ePlayerNetID directly, so why don't we do that?. I probably wanted to leave the final coloring decision up to the server. But the network message system definitely needs more flexibility anyway.

Now what I don't like ( it's not your fault! ) is that this code is bound to the incredibly ugly current cycle rendering method. I would rather like to have a flexible cycle file format in place where the artist can select meshes and textures and group them together as he likes ( with custom spinning wheels ); the user should then select such a file for his visuals. Of course, he should be able to customize every possible aspect of it, but this customization should be created dynamically from the cycle file so all textures and meshes are customizable. Later, we can extend what is now a texture to a even more flexible "material" that can consist of multiple texture layers blended together, eventually with bump mapping and everything. ( No concrete plans yet, but we should not fix our minds at the thought that a texture automatically is an image file. ) Is this making sense?

I think what I'll add from this code ASAP is the music selection menu, since the background music playing code is already in place, but unused. Only an "official" music piece or a music selection menu was missing :)
User avatar
SuPeRTaRD
Round Winner
Posts: 300
Joined: Fri Nov 05, 2004 11:53 pm
Location: bedlam
Contact:

Post by SuPeRTaRD »

I like where this is going alot, but I dont understand the importance of coloring trails. I like the fact that clients pick thier own trail color, dont see why that needs to change. I usually incorporate that feature into my custom cycle meshes & have certain parts on them that glow the client color choice. blah

its cool that y'all are figguring out the details of switching meshes tho! dont let me discourage U.
k
Random Identifier & Project Developer
Posts: 345
Joined: Wed Feb 25, 2004 12:54 am
Location: Northern California, USA

Post by k »

z-man wrote:About the cycle trail color transfer problem: I can't really remember there being a reason to to simply take the values of the body color from the ePlayerNetID directly, so why don't we do that?. I probably wanted to leave the final coloring decision up to the server. But the network message system definitely needs more flexibility anyway.
I think I tried that and ran in to a problem, but I don't recall what it was. It might have been that the player information was syncronized after the cycle was created. I do remember that sometimes the colors were wrong and sometimes they changed in game for no reason when I used the player object. I was using the player object in gCycle::gCycle(nMessage &m) so maybe there is a better place in the code to do it from after the player object is syncronized.

Edit: The Team code I was adding to support this might have been mucking things up as well.
Last edited by k on Wed Mar 09, 2005 7:26 pm, edited 1 time in total.
k
Random Identifier & Project Developer
Posts: 345
Joined: Wed Feb 25, 2004 12:54 am
Location: Northern California, USA

Post by k »

z-man wrote:Now what I don't like ( it's not your fault! ) is that this code is bound to the incredibly ugly current cycle rendering method...
I'm all for making it very flexible and customizable. I'll leave the dirty details to those who know more about them, but I should be able to help out with more higher level areas like the menu and config code etc..
z-man wrote:I think what I'll add from this code ASAP is the music selection menu, since the background music playing code is already in place, but unused. Only an "official" music piece or a music selection menu was missing :)
Cool. Just so you know I haven't done much testing of the file/directory selection code in Unix. I made sure it compiled and did a little testing with it and it seemed to work fine, but you never know. :wink:
User avatar
Your_mom
Match Winner
Posts: 653
Joined: Sun Jun 06, 2004 1:45 am

Post by Your_mom »

Who would want something like that :P (http://guru3.sytes.net/viewtopic.php?t=1478) :wink:

very nice k i cant wait till you guys get this working the user interface looks pretty easy. mabey then i could get all the models and skins organized seriusly you should see what my armagetron folder looks like get rid of moviepackx moViepackx1 moviepackorig moviepackwrking and all the files dir_wall7x dir_wallflames etc etc its pretty messy cant wait till i can play with this :D
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Re: Cycle Customization

Post by Jonathan »

Finally someone actually tries to do it. :)
k wrote:Directory Structure:

Code: Select all

+- textures
   +- cycle_body
   +- cycle_wall
   +- cycle_wheel
I prefer packages (and I think it's a better choice, especially long term), like this:

Code: Select all

packages/
    default/
        ...
    package1/
        ...
    package2/
        ...
ˌɑrməˈɡɛˌtrɑn
User avatar
Z-Man
God & Project Admin
Posts: 11717
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Re: Cycle Customization

Post by Z-Man »

Jonathan wrote:Finally someone actually tries to do it. :)
k wrote:Directory Structure:

Code: Select all

+- textures
   +- cycle_body
   +- cycle_wall
   +- cycle_wheel
I prefer packages (and I think it's a better choice, especially long term), like this:

Code: Select all

packages/
    default/
        ...
    package1/
        ...
    package2/
        ...
Agreed. The original organization is optimal for the concept of selecting the body, wheel and wall textures separately, though, since it makes it easier not to choose a wall texture for a wheel. Maybe the textures should be wrapped in metadata description file ( text files too, of course ) that say which mesh they are supposed to be put on, and the texture selection code can respect that information. With a possibility to override, of course.

About the trail color: I was afraid of something like this. Usually, when I can't remember a reason why something is done the way it is, that reason is scary :) I'll investigate what path the color information takes and when it is changed.
User avatar
n54
MVP
Posts: 1587
Joined: Sun Dec 21, 2003 12:40 pm

Post by n54 »

I might be wrong here but from what I understand you are talking about a system with everything (from any theme) collected in big folders according to what it is. This is an efficient solution from the developers viewpoint, coding etc.

I'd rather have a system where I can distribute a theme as a zipped folder of files which the users can simply uncompress into one correct folder (called "themes" or similar) and it just works. This is easier for the user (just extract, no need to move files to the correct folder) and gives me as theme-creator the ability to distribute a theme as a complete package even with a corresponding config file (like the original moviepack has). Doing it this way also ensures that all the files are together with any readme.txt with whatever copyright information, credits, tips and explanations etc. included. It also ensures that files do not get accidentaly overwritten and that we don't need to use anything but default filenames.

If you want the benefit of the initial example with everything according to what it is I think the place for this structure is not in the filesystem itself but rather something akin to xml files... i.e. a data structure rather than a file structure.

This way one can combine the best of both; theme-defined file structure and value-based choice structure (where some of the values represent the theme in its entirety). It requires more coding (and perhaps themes having a file containing a list of what is in the theme) but it will make distribution of themes easier and more familiar for people who have skinned or themed other applications, and it will make installing a theme a nobrainer for any user.
User avatar
Z-Man
God & Project Admin
Posts: 11717
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Absolutely. Sorry for not making this clear: the justification for the one-folder-per-filetype was only to say that with the rest of the code as it is now, that's the easiest and most logical way to do it. Of course, we should not do that, because the current code is crap ( my code, not k's ). We definitely should use an approach where all files from a package sit in a subfolder and relations between packages and files should be handled with metafiles.
User avatar
n54
MVP
Posts: 1587
Joined: Sun Dec 21, 2003 12:40 pm

Post by n54 »

Oh ok lol :oops: :D
Post Reply