home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / 3D / BRONIE / DUAL_LAU.ZIP / src / p_hud.c < prev    next >
C/C++ Source or Header  |  1997-11-26  |  10KB  |  430 lines

  1. #include "g_local.h"
  2.  
  3.  
  4.  
  5. /*
  6. ======================================================================
  7.  
  8. INTERMISSION
  9.  
  10. ======================================================================
  11. */
  12.  
  13. void MoveClientToIntermission (edict_t *ent)
  14. {
  15.     ent->client->showscores = true;
  16.     VectorCopy (level.intermission_origin, ent->s.origin);
  17.     ent->client->ps.pmove.origin[0] = level.intermission_origin[0]*8;
  18.     ent->client->ps.pmove.origin[1] = level.intermission_origin[1]*8;
  19.     ent->client->ps.pmove.origin[2] = level.intermission_origin[2]*8;
  20.     VectorCopy (level.intermission_angle, ent->client->ps.viewangles);
  21.     ent->client->ps.pmove.pm_type = PM_FREEZE;
  22.     ent->client->ps.gunindex = 0;
  23.     ent->client->ps.blend[3] = 0;
  24.  
  25.     // clean up powerup info
  26.     ent->client->quad_framenum = 0;
  27.     ent->client->invincible_framenum = 0;
  28.     ent->client->breather_framenum = 0;
  29.     ent->client->enviro_framenum = 0;
  30.     ent->client->grenade_blew_up = false;
  31.     ent->client->grenade_time = 0;
  32.  
  33.     ent->viewheight = 0;
  34.     ent->s.modelindex = 0;
  35.     ent->s.modelindex2 = 0;
  36.     ent->s.modelindex3 = 0;
  37.     ent->s.modelindex = 0;
  38.     ent->s.effects = 0;
  39.     ent->s.sound = 0;
  40.     ent->solid = SOLID_NOT;
  41.  
  42.     // add the layout
  43.  
  44.     if (deathmatch->value)
  45.     {
  46.         DeathmatchScoreboardMessage (ent, NULL);
  47.         gi.unicast (ent, true);
  48.     }
  49.  
  50. }
  51.  
  52. void BeginIntermission (edict_t *targ)
  53. {
  54.     int        i;
  55.     edict_t    *ent, *client;
  56.  
  57.     if (level.intermissiontime)
  58.         return;        // allready activated
  59.  
  60.  
  61.     level.intermissiontime = level.time;
  62.     level.changemap = targ->map;
  63.  
  64.     // if on same unit, return immediately
  65.     if (!deathmatch->value && (targ->map && targ->map[0] != '*') )
  66.     {    // go immediately to the next level
  67.         level.exitintermission = 1;
  68.         return;
  69.     }
  70.     level.exitintermission = 0;
  71.  
  72.     // find an intermission spot
  73.     ent = G_Find (NULL, FOFS(classname), "info_player_intermission");
  74.     if (!ent)
  75.     {    // the map creator forgot to put in an intermission point...
  76.         ent = G_Find (NULL, FOFS(classname), "info_player_start");
  77.         if (!ent)
  78.             ent = G_Find (NULL, FOFS(classname), "info_player_deathmatch");
  79.     }
  80.     else
  81.     {    // chose one of four spots
  82.         i = rand() & 3;
  83.         while (i--)
  84.         {
  85.             ent = G_Find (ent, FOFS(classname), "info_player_intermission");
  86.             if (!ent)    // wrap around the list
  87.                 ent = G_Find (ent, FOFS(classname), "info_player_intermission");
  88.         }
  89.     }
  90.  
  91.     VectorCopy (ent->s.origin, level.intermission_origin);
  92.     VectorCopy (ent->s.angles, level.intermission_angle);
  93.  
  94.     // move all clients to the intermission point
  95.     for (i=0 ; i<maxclients->value ; i++)
  96.     {
  97.         client = g_edicts + 1 + i;
  98.         if (!client->inuse)
  99.             continue;
  100.         MoveClientToIntermission (client);
  101.     }
  102. }
  103.  
  104.  
  105. /*
  106. ==================
  107. DeathmatchScoreboardMessage
  108.  
  109. ==================
  110. */
  111. void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer)
  112. {
  113.     char    entry[1024];
  114.     char    string[1400];
  115.     int        stringlength;
  116.     int        i, j, k;
  117.     int        sorted[MAX_CLIENTS];
  118.     int        sortedscores[MAX_CLIENTS];
  119.     int        score, total;
  120.     int        picnum;
  121.     int        x, y;
  122.     gclient_t    *cl;
  123.     edict_t        *cl_ent;
  124.     char    *tag;
  125.  
  126.     // sort the clients by score
  127.     total = 0;
  128.     for (i=0 ; i<game.maxclients ; i++)
  129.     {
  130.         cl_ent = g_edicts + 1 + i;
  131.         if (!cl_ent->inuse)
  132.             continue;
  133.         score = game.clients[i].resp.score;
  134.         for (j=0 ; j<total ; j++)
  135.         {
  136.             if (score > sortedscores[j])
  137.                 break;
  138.         }
  139.         for (k=total ; k>j ; k--)
  140.         {
  141.             sorted[k] = sorted[k-1];
  142.             sortedscores[k] = sortedscores[k-1];
  143.         }
  144.         sorted[j] = i;
  145.         sortedscores[j] = score;
  146.         total++;
  147.     }
  148.  
  149.     // print level name and exit rules
  150.     string[0] = 0;
  151.  
  152.     stringlength = strlen(string);
  153.  
  154.     // add the clients in sorted order
  155.     if (total > 12)
  156.         total = 12;
  157.  
  158.     for (i=0 ; i<total ; i++)
  159.     {
  160.         cl = &game.clients[sorted[i]];
  161.         cl_ent = g_edicts + 1 + sorted[i];
  162.  
  163.         picnum = gi.imageindex ("i_fixme");
  164.         x = (i>=6) ? 160 : 0;
  165.         y = 32 + 32 * (i%6);
  166.  
  167.         // add a dogtag
  168.         if (cl_ent == ent)
  169.             tag = "tag1";
  170.         else if (cl_ent == killer)
  171.             tag = "tag2";
  172.         else
  173.             tag = NULL;
  174.         if (tag)
  175.         {
  176.             Com_sprintf (entry, sizeof(entry),
  177.                 "xv %i yv %i picn %s ",x+32, y, tag);
  178.             j = strlen(entry);
  179.             if (stringlength + j > 1024)
  180.                 break;
  181.             strcpy (string + stringlength, entry);
  182.             stringlength += j;
  183.         }
  184.  
  185.         // send the layout
  186.         Com_sprintf (entry, sizeof(entry),
  187.             "client %i %i %i %i %i %i ",
  188.             x, y, sorted[i], cl->resp.score, cl->ping, (level.framenum - cl->resp.enterframe)/600);
  189.         j = strlen(entry);
  190.         if (stringlength + j > 1024)
  191.             break;
  192.         strcpy (string + stringlength, entry);
  193.         stringlength += j;
  194.     }
  195.  
  196.     gi.WriteByte (svc_layout);
  197.     gi.WriteString (string);
  198. }
  199.  
  200.  
  201. /*
  202. ==================
  203. DeathmatchScoreboard
  204.  
  205. Draw instead of help message.
  206. Note that it isn't that hard to overflow the 1400 byte message limit!
  207. ==================
  208. */
  209. void DeathmatchScoreboard (edict_t *ent)
  210. {
  211.     DeathmatchScoreboardMessage (ent, ent->enemy);
  212.     gi.unicast (ent, true);
  213. }
  214.  
  215.  
  216. /*
  217. ==================
  218. Cmd_Help_f
  219.  
  220. Display the current help message
  221. ==================
  222. */
  223. void Cmd_Help_f (edict_t *ent)
  224. {
  225.     char    string[1024];
  226.     char    *sk;
  227.  
  228.     if (ent->client->showscores && !game.helpchanged)
  229.     {
  230.         ent->client->showscores = false;
  231.         return;
  232.     }
  233.  
  234.     // remove help icon
  235.     game.helpchanged = false;
  236.  
  237.     ent->client->showscores = true;
  238.     ent->client->showinventory = false;
  239.  
  240.     if (deathmatch->value)
  241.     {
  242.         DeathmatchScoreboard (ent);
  243.         return;
  244.     }
  245.  
  246.     if (skill->value == 0)
  247.         sk = "easy";
  248.     else if (skill->value == 1)
  249.         sk = "medium";
  250.     else
  251.         sk = "hard";
  252.  
  253.     // send the layout
  254.     Com_sprintf (string, sizeof(string),
  255.         "xv 32 yv 8 picn help "            // background
  256.         "xv 202 yv 12 string2 \"%s\" "        // skill
  257.         "xv 0 yv 24 cstring2 \"%s\" "        // level name
  258.         "xv 0 yv 54 cstring2 \"%s\" "        // help 1
  259.         "xv 0 yv 110 cstring2 \"%s\" "        // help 2
  260.         "xv 50 yv 164 string2 \" kills     goals    secrets\" "
  261.         "xv 50 yv 172 string2 \"%3i/%3i     %i/%i       %i/%i\" ", 
  262.         sk,
  263.         level.level_name,
  264.         game.helpmessage1,
  265.         game.helpmessage2,
  266.         level.killed_monsters, level.total_monsters, 
  267.         level.found_goals, level.total_goals,
  268.         level.found_secrets, level.total_secrets);
  269.  
  270.     gi.WriteByte (svc_layout);
  271.     gi.WriteString (string);
  272.     gi.unicast (ent, true);
  273. }
  274.  
  275.  
  276.  
  277.  
  278. //=======================================================================
  279.  
  280. /*
  281. ===============
  282. G_SetStats
  283. ===============
  284. */
  285. void G_SetStats (edict_t *ent)
  286. {
  287.     gitem_t        *item;
  288.     int            index, cells;
  289.     int            power_armor_type;
  290.  
  291.     //
  292.     // health
  293.     //
  294.     ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health;
  295.     ent->client->ps.stats[STAT_HEALTH] = ent->health;
  296.  
  297.     //
  298.     // ammo
  299.     //
  300.     if (!ent->client->ammo_index /* || !ent->client->pers.inventory[ent->client->ammo_index] */)
  301.     {
  302.         ent->client->ps.stats[STAT_AMMO_ICON] = 0;
  303.         ent->client->ps.stats[STAT_AMMO] = 0;
  304.     }
  305.     else
  306.     {
  307.         item = &itemlist[ent->client->ammo_index];
  308.         ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex (item->icon);
  309.         ent->client->ps.stats[STAT_AMMO] = ent->client->pers.inventory[ent->client->ammo_index];
  310.     }
  311.     
  312.     //
  313.     // armor
  314.     //
  315.     power_armor_type = PowerArmorType (ent);
  316.     if (power_armor_type)
  317.     {
  318.         cells = ent->client->pers.inventory[ITEM_INDEX(FindItem ("cells"))];
  319.         if (cells == 0)
  320.         {    // ran out of cells for power armor
  321.             ent->flags &= ~FL_POWER_ARMOR;
  322.             gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0);    //FIXME powering down sound
  323.             power_armor_type = 0;;
  324.         }
  325.     }
  326.  
  327.     index = ArmorIndex (ent);
  328.     if (power_armor_type && (!index || (level.framenum & 8) ) )
  329.     {    // flash between power armor and other armor icon
  330.         ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex ("i_powershield");
  331.         ent->client->ps.stats[STAT_ARMOR] = cells;
  332.     }
  333.     else if (index)
  334.     {
  335.         item = GetItemByIndex (index);
  336.         ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex (item->icon);
  337.         ent->client->ps.stats[STAT_ARMOR] = ent->client->pers.inventory[index];
  338.     }
  339.     else
  340.     {
  341.         ent->client->ps.stats[STAT_ARMOR_ICON] = 0;
  342.         ent->client->ps.stats[STAT_ARMOR] = 0;
  343.     }
  344.  
  345.     //
  346.     // pickup message
  347.     //
  348.     if (level.time > ent->client->pickup_msg_time)
  349.     {
  350.         ent->client->ps.stats[STAT_PICKUP_ICON] = 0;
  351.         ent->client->ps.stats[STAT_PICKUP_STRING] = 0;
  352.     }
  353.  
  354.     //
  355.     // timers
  356.     //
  357.     if (ent->client->quad_framenum > level.framenum)
  358.     {
  359.         ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad");
  360.         ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum)/10;
  361.     }
  362.     else if (ent->client->invincible_framenum > level.framenum)
  363.     {
  364.         ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_invulnerability");
  365.         ent->client->ps.stats[STAT_TIMER] = (ent->client->invincible_framenum - level.framenum)/10;
  366.     }
  367.     else if (ent->client->enviro_framenum > level.framenum)
  368.     {
  369.         ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_envirosuit");
  370.         ent->client->ps.stats[STAT_TIMER] = (ent->client->enviro_framenum - level.framenum)/10;
  371.     }
  372.     else if (ent->client->breather_framenum > level.framenum)
  373.     {
  374.         ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_rebreather");
  375.         ent->client->ps.stats[STAT_TIMER] = (ent->client->breather_framenum - level.framenum)/10;
  376.     }
  377.     else
  378.     {
  379.         ent->client->ps.stats[STAT_TIMER_ICON] = 0;
  380.         ent->client->ps.stats[STAT_TIMER] = 0;
  381.     }
  382.  
  383.     //
  384.     // selected item
  385.     //
  386.     if (ent->client->pers.selected_item == -1)
  387.         ent->client->ps.stats[STAT_SELECTED_ICON] = 0;
  388.     else
  389.         ent->client->ps.stats[STAT_SELECTED_ICON] = gi.imageindex (itemlist[ent->client->pers.selected_item].icon);
  390.  
  391.     ent->client->ps.stats[STAT_SELECTED_ITEM] = ent->client->pers.selected_item;
  392.  
  393.     //
  394.     // layouts
  395.     //
  396.     ent->client->ps.stats[STAT_LAYOUTS] = 0;
  397.  
  398.     if (deathmatch->value)
  399.     {
  400.         if (ent->client->pers.health <= 0 || level.intermissiontime
  401.             || ent->client->showscores)
  402.             ent->client->ps.stats[STAT_LAYOUTS] |= 1;
  403.         if (ent->client->showinventory && ent->client->pers.health > 0)
  404.             ent->client->ps.stats[STAT_LAYOUTS] |= 2;
  405.     }
  406.     else
  407.     {
  408.         if (ent->client->showscores)
  409.             ent->client->ps.stats[STAT_LAYOUTS] |= 1;
  410.         if (ent->client->showinventory && ent->client->pers.health > 0)
  411.             ent->client->ps.stats[STAT_LAYOUTS] |= 2;
  412.     }
  413.  
  414.     //
  415.     // frags
  416.     //
  417.     ent->client->ps.stats[STAT_FRAGS] = ent->client->resp.score;
  418.  
  419.     //
  420.     // help icon
  421.     //
  422.     if (game.helpchanged && (level.framenum&8) )
  423.         ent->client->ps.stats[STAT_HELPICON] = gi.imageindex ("i_help");
  424.     else if (ent->client->pers.hand == CENTER_HANDED && ent->client->pers.weapon)
  425.         ent->client->ps.stats[STAT_HELPICON] = gi.imageindex (ent->client->pers.weapon->icon);
  426.     else
  427.         ent->client->ps.stats[STAT_HELPICON] = 0;
  428. }
  429.  
  430.