Visual Weapon Switching
I've said it before, and I'll say it again, I really don't like Quake 3 all that much, but I have to agree with my friends when they say that they like the way it switches weapons. As you choose your new weapon, a set of icons appear near the centre of the screen and you can see the one that you are going to use. Many people don't like to take their eyes off the action at the centre of the screen to look at the icons at the bottom.

Just for the benefit of those friends I add this mod and the next one (fast weapon switching) to my quake2 mods.

Here's a screen shot of the system in action, click to see the full detail.
There is space for 11 icons across the screen, if you have less than 11 items to choose from, the list simply appears smaller. The icons display whenever you use invnext, invprev, invnextw, invprevw, invnextp, invprevp, weapnext, weapprev and weaplast. The icons disappear after 1 second, but if you use an inventory or weapon command again within that time, the icons effectively scroll left or right. There is a marker indicating the selected item, and the name of the selected item appears just above the cross hairs.

Make the following changes. 
For each file (named in bold), find the fragment
of code listed, and make the changes marked by the '// C14' comments
q_shared.h:
#define  STAT_FRAGS        14
#define  STAT_FLASHES      15    // cleared each frame, 1 = health, 2 = armor
#define STAT_CHASE        16
#define STAT_SPECTATOR      17
// C14 Start of New Code
#define STAT_FAST_PREV5   20
#define STAT_FAST_PREV4   21
#define STAT_FAST_PREV3   22
#define STAT_FAST_PREV2   23
#define STAT_FAST_PREV1   24
#define STAT_FAST         25
#define STAT_FAST_NEXT1   26
#define STAT_FAST_NEXT2   27
#define STAT_FAST_NEXT3   28
#define STAT_FAST_NEXT4   29
#define STAT_FAST_NEXT5   30
#define STAT_FAST_NAME    31
// C14 End of New Code
g_cmds.c;
#include "g_local.h"
#include "m_player.h"
// C14 Start of New Code
void trimicons(int *icons)
{
  if (icons[6] == icons[5]) {
    icons[6] = -1;
    icons[4] = -1;
    icons[7] = -1;
    icons[3] = -1;
    icons[8] = -1;
    icons[2] = -1;
    icons[9] = -1;
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[4] == icons[6]) {
    icons[4] = -1;
    icons[7] = -1;
    icons[3] = -1;
    icons[8] = -1;
    icons[2] = -1;
    icons[9] = -1;
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[7] == icons[4]) {
    icons[7] = -1;
    icons[3] = -1;
    icons[8] = -1;
    icons[2] = -1;
    icons[9] = -1;
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[3] == icons[7]) {
    icons[3] = -1;
    icons[8] = -1;
    icons[2] = -1;
    icons[9] = -1;
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[8] == icons[3]) {
    icons[8] = -1;
    icons[2] = -1;
    icons[9] = -1;
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[2] == icons[8]) {
    icons[2] = -1;
    icons[9] = -1;
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[9] == icons[2]) {
    icons[9] = -1;
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[1] == icons[9]) {
    icons[1] = -1;
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[10] == icons[1]) {
    icons[10] = -1;
    icons[0] = -1;
  }
  else if (icons[0] == icons[10]) {
    icons[0] = -1;
  }

}

void c14_SetFastIcons(edict_t *ent, int itemtype)
{
  gclient_t *cl;
  int i, index;
  gitem_t *it;
  int icons[11];
  int iconindex;

  cl = ent->client;

  icons[5] = cl->pers.selected_item;
  for (iconindex = 6; iconindex < 11; iconindex++) {
    icons[iconindex] = -1;
    for (i = 1;  i <= MAX_ITEMS; i++) {
      index = (icons[iconindex-1] + i) % MAX_ITEMS;
      if (!cl->pers.inventory[index])
        continue;
      it = &itemlist[index];
      if (!it->use)
        continue;
      if (!(it->flags & itemtype))
        continue;
      icons[iconindex] = index;
      break;
    }
  }

  for (iconindex = 4; iconindex >= 0; iconindex--) {
    icons[iconindex] = -1;
    for (i = 1;  i <= MAX_ITEMS; i++) {
      index = (icons[iconindex+1] + MAX_ITEMS -  i) % MAX_ITEMS;
      if (!cl->pers.inventory[index])
        continue;
      it = &itemlist[index];
      if (!it->use)
        continue;
      if (!(it->flags & itemtype))
        continue;
      icons[iconindex] = index;
      break;
    }
  }

  trimicons(icons);

  for (i = 0; i < 11; i++) {
    if (icons[i] == -1)
      ent->client->ps.stats[STAT_FAST_PREV5 + i] = 0;
    else
      ent->client->ps.stats[STAT_FAST_PREV5 + i] =
        gi.imageindex((&itemlist[icons[i]])->icon);
  }

  ent->client->fs_frame = level.framenum + 10;
  ent->client->ps.stats[STAT_FAST_NAME] = CS_ITEMS + icons[5];
  return;
}

void c14_SetFastWIcons(edict_t *ent)
{
  gclient_t *cl;
  int i, index;
  gitem_t *it;
  int icons[11];
  int iconindex;

  cl = ent->client;

  if (!cl->newweapon)
    return;

  icons[5] = ITEM_INDEX(cl->newweapon);
  for (iconindex = 6; iconindex < 11; iconindex++) {
    icons[iconindex] = -1;
    for (i = 1;  i <= MAX_ITEMS; i++) {
      index = (icons[iconindex-1] + i) % MAX_ITEMS;
      if (!cl->pers.inventory[index])
        continue;
      it = &itemlist[index];
      if (!it->use)
        continue;
      if (!(it->flags & IT_WEAPON))
        continue;
      icons[iconindex] = index;
      break;
    }
  }

  for (iconindex = 4; iconindex >= 0; iconindex--) {
    icons[iconindex] = -1;
    for (i = 1;  i <= MAX_ITEMS; i++) {
      index = (icons[iconindex+1] + MAX_ITEMS - i) % MAX_ITEMS;
      if (!cl->pers.inventory[index])
        continue;
      it = &itemlist[index];
      if (!it->use)
        continue;
      if (!(it->flags & IT_WEAPON))
        continue;
      icons[iconindex] = index;
      break;
    }
  }

  trimicons(icons);

  for (i = 0; i < 11; i++) {
    if (icons[i] == -1)
      ent->client->ps.stats[STAT_FAST_PREV5 + i] = 0;
    else
      ent->client->ps.stats[STAT_FAST_PREV5 + i] =
        gi.imageindex((&itemlist[icons[i]])->icon);
  }

  ent->client->fs_frame = level.framenum + 10;
  ent->client->ps.stats[STAT_FAST_NAME] = CS_ITEMS + icons[5];
  return;
}

// C14 End of New Code
g_cmds.c;
void SelectNextItem (edict_t *ent, int itflags)
{
  gclient_t  *cl;
  int      i, index;
  gitem_t    *it;

  cl = ent->client;

  if (cl->chase_target) {
    ChaseNext(ent);
    return;
  }

  // scan  for the next valid one
  for (i=1 ; i<=MAX_ITEMS ; i++)
  {
    index = (cl->pers.selected_item + i)%MAX_ITEMS;
    if (!cl->pers.inventory[index])
      continue;
    it = &itemlist[index];
    if (!it->use)
      continue;
    if (!(it->flags & itflags))
      continue;

    cl->pers.selected_item = index;
    c14_SetFastIcons(ent, itflags);   // C14 Add this line
    return;
  }

  cl->pers.selected_item = -1;
}

void SelectPrevItem (edict_t *ent, int itflags)
{
  gclient_t  *cl;
  int      i, index;
  gitem_t    *it;

  cl = ent->client;

  if (cl->chase_target) {
    ChasePrev(ent);
    return;
  }

  // scan  for the next valid one
  for (i=1 ; i<=MAX_ITEMS ; i++)
  {
    index = (cl->pers.selected_item + MAX_ITEMS - i)%MAX_ITEMS;
    if (!cl->pers.inventory[index])
      continue;
    it = &itemlist[index];
    if (!it->use)
      continue;
    if (!(it->flags & itflags))
      continue;

    cl->pers.selected_item = index;
    c14_SetFastIcons(ent, itflags);  // C14 Add this line
    return;
  }

  cl->pers.selected_item = -1;
}
g_cmds.c;
void Cmd_WeapPrev_f (edict_t *ent)
{
  gclient_t  *cl;
  int      i, index;
  gitem_t    *it;
  int      selected_weapon;

  cl = ent->client;

  if (!cl->pers.weapon)
    return;

  selected_weapon = ITEM_INDEX(cl->pers.weapon);

  // scan  for the next valid one
  for (i=1 ; i<=MAX_ITEMS ; i++)
  {
    index = (selected_weapon + i)%MAX_ITEMS;
    if (!cl->pers.inventory[index])
      continue;
    it = &itemlist[index];
    if (!it->use)
      continue;
    if (! (it->flags & IT_WEAPON) )
      continue;
    it->use (ent, it);
//    if (cl->pers.weapon == it)       // C14 Remove This Line
//      return;                        // C14 Remove This Line
// C14 Start of New Code
    if (cl->newweapon == it) {
      c14_SetFastWIcons(ent);
      return;  // successful
    }
// C14 End of New Code
  }
}

void Cmd_WeapNext_f (edict_t *ent)
{
  gclient_t  *cl;
  int      i, index;
  gitem_t    *it;
  int      selected_weapon;

  cl = ent->client;

  if (!cl->pers.weapon)
    return;

  selected_weapon = ITEM_INDEX(cl->pers.weapon);

  // scan  for the next valid one
  for (i=1 ; i<=MAX_ITEMS ; i++)
  {
    index = (selected_weapon + MAX_ITEMS - i)%MAX_ITEMS;
    if (!cl->pers.inventory[index])
      continue;
    it = &itemlist[index];
    if (!it->use)
      continue;
    if (! (it->flags & IT_WEAPON) )
      continue;
    it->use (ent, it);
//    if (cl->pers.weapon == it)       // C14 Remove This Line
//      return;                        // C14 Remove This Line
// C14 Start of New Code
    if (cl->newweapon == it) {
      c14_SetFastWIcons(ent);
      return;  // successful
    }
// C14 End of New Code
  }
}

void Cmd_WeapLast_f (edict_t *ent)
{
  gclient_t  *cl;
  int      index;
  gitem_t    *it;

  cl = ent->client;

  if (!cl->pers.weapon || !cl->pers.lastweapon)
    return;

  index = ITEM_INDEX(cl->pers.lastweapon);
  if (!cl->pers.inventory[index])
    return;
  it = &itemlist[index];
  if (!it->use)
    return;
  if (! (it->flags & IT_WEAPON) )
    return;
  it->use (ent, it);
// C14 Start of New Code
  if (cl->newweapon == it) {
    c14_SetFastWIcons(ent);
    return;  // successful
  }
// C14 End of New Code

}
g_local.h;
  float    quad_framenum;
  float    invincible_framenum;
  float    breather_framenum;
  float    enviro_framenum;

  int      fs_frame;              // C14 Add this line
p_hud.c;
  if (ent->client->pers.helpchanged && (level.framenum&8) )
    ent->client->ps.stats[STAT_HELPICON] = gi.imageindex ("i_help");
  else if ( (ent->client->pers.hand == CENTER_HANDED || ent->client->ps.fov > 91)
    && ent->client->pers.weapon)
    ent->client->ps.stats[STAT_HELPICON] = gi.imageindex (ent->client->pers.weapon->icon);
  else
    ent->client->ps.stats[STAT_HELPICON] = 0;

  ent->client->ps.stats[STAT_SPECTATOR] = 0;

// C14 Start of New Code
  if (ent->client->fs_frame < level.framenum) {
    ent->client->ps.stats[STAT_FAST_PREV5] = 0;
    ent->client->ps.stats[STAT_FAST_PREV4] = 0;
    ent->client->ps.stats[STAT_FAST_PREV3] = 0;
    ent->client->ps.stats[STAT_FAST_PREV2] = 0;
    ent->client->ps.stats[STAT_FAST_PREV1] = 0;
    ent->client->ps.stats[STAT_FAST] = 0;
    ent->client->ps.stats[STAT_FAST_NEXT1] = 0;
    ent->client->ps.stats[STAT_FAST_NEXT2] = 0;
    ent->client->ps.stats[STAT_FAST_NEXT3] = 0;
    ent->client->ps.stats[STAT_FAST_NEXT4] = 0;
    ent->client->ps.stats[STAT_FAST_NEXT5] = 0;
    ent->client->ps.stats[STAT_FAST_NAME] = 0;
  }
// C14 End of New Code
}
g_spawn.c;
// chase camera
"if 16 "
  "xv 0 "
  "yb -68 "
  "string \"Chasing\" "
  "xv 64 "
  "stat_string 16 "
"endif "

// C14 Start of New Code
"yv 128 "
"if 20 xv 28 pic 20 endif "
"if 21 xv 52 pic 21 endif "
"if 22 xv 76 pic 22 endif "
"if 23 xv 100 pic 23 endif "
"if 24 xv 124 pic 24 endif "
"if 25 xv 148 yv 112 stat_string 31 yv 124 picn fselect yv 128 pic 25 endif "
"if 26 xv 172 pic 26 endif "
"if 27 xv 196 pic 27 endif "
"if 28 xv 220 pic 28 endif "
"if 29 xv 244 pic 29 endif "
"if 30 xv 268 pic 30 endif "
// C14 End of New Code
;
Download the fselect.pcx and put it in your pics directory.
That's all there is to it. You're ready to go.
This mod uses 12 of your STAT variables. Since you only have 32 to play with, and the standard quake uses 18 of them, you might want to cut down the length of your scrolling icon list from 11 to 9 or 7. Personally I wouldn't want to go less than 7. The extra STAT is used for the pickup name that appears above the cross hairs. You can get away with not using that if you centreprint the pickup name at the end of the c14_SetFastIcons and c14_SetFastWIcons functions. This saves a STAT and gives you the name nicely centred on the screen, but it does put lots of stuff into the players console history, which could be annoying.

I hope this is useful,