Reformat hud.c

This commit is contained in:
Yamagi Burmeister 2011-10-15 10:15:33 +00:00
parent a225b0fb17
commit 78cddcd152
1 changed files with 314 additions and 247 deletions

View File

@ -1,49 +1,58 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (C) 1997-2001 Id Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* HUD, deathmatch scoreboard, help computer and intermission stuff.
*
* =======================================================================
*/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../header/local.h"
/*
======================================================================
* ======================================================================
*
* INTERMISSION
*
* ======================================================================
*/
INTERMISSION
======================================================================
*/
void MoveClientToIntermission (edict_t *ent)
void
MoveClientToIntermission(edict_t *ent)
{
if (deathmatch->value || coop->value)
{
ent->client->showscores = true;
VectorCopy (level.intermission_origin, ent->s.origin);
ent->client->ps.pmove.origin[0] = level.intermission_origin[0]*8;
ent->client->ps.pmove.origin[1] = level.intermission_origin[1]*8;
ent->client->ps.pmove.origin[2] = level.intermission_origin[2]*8;
VectorCopy (level.intermission_angle, ent->client->ps.viewangles);
}
VectorCopy(level.intermission_origin, ent->s.origin);
ent->client->ps.pmove.origin[0] = level.intermission_origin[0] * 8;
ent->client->ps.pmove.origin[1] = level.intermission_origin[1] * 8;
ent->client->ps.pmove.origin[2] = level.intermission_origin[2] * 8;
VectorCopy(level.intermission_angle, ent->client->ps.viewangles);
ent->client->ps.pmove.pm_type = PM_FREEZE;
ent->client->ps.gunindex = 0;
ent->client->ps.blend[3] = 0;
ent->client->ps.rdflags &= ~RDF_UNDERWATER;
// clean up powerup info
/* clean up powerup info */
ent->client->quad_framenum = 0;
ent->client->invincible_framenum = 0;
ent->client->breather_framenum = 0;
@ -60,39 +69,47 @@ void MoveClientToIntermission (edict_t *ent)
ent->s.sound = 0;
ent->solid = SOLID_NOT;
// add the layout
/* add the layout */
if (deathmatch->value || coop->value)
{
DeathmatchScoreboardMessage (ent, NULL);
gi.unicast (ent, true);
DeathmatchScoreboardMessage(ent, NULL);
gi.unicast(ent, true);
}
}
void BeginIntermission (edict_t *targ)
void
BeginIntermission(edict_t *targ)
{
int i, n;
edict_t *ent, *client;
int i, n;
edict_t *ent, *client;
if (level.intermissiontime)
return; // allready activated
{
return; /* allready activated */
}
//ZOID
if (deathmatch->value && ctf->value)
{
CTFCalcScores();
//ZOID
}
game.autosaved = false;
// respawn any dead clients
for (i=0 ; i<maxclients->value ; i++)
/* respawn any dead clients */
for (i = 0; i < maxclients->value; i++)
{
client = g_edicts + 1 + i;
if (!client->inuse)
{
continue;
}
if (client->health <= 0)
{
respawn(client);
}
}
level.intermissiontime = level.time;
@ -102,16 +119,22 @@ void BeginIntermission (edict_t *targ)
{
if (coop->value)
{
for (i=0 ; i<maxclients->value ; i++)
for (i = 0; i < maxclients->value; i++)
{
client = g_edicts + 1 + i;
if (!client->inuse)
{
continue;
// strip players of all keys between units
}
/* strip players of all keys between units */
for (n = 0; n < MAX_ITEMS; n++)
{
if (itemlist[n].flags & IT_KEY)
{
client->client->pers.inventory[n] = 0;
}
}
}
}
@ -120,182 +143,212 @@ void BeginIntermission (edict_t *targ)
{
if (!deathmatch->value)
{
level.exitintermission = 1; // go immediately to the next level
level.exitintermission = 1; /* go immediately to the next level */
return;
}
}
level.exitintermission = 0;
// find an intermission spot
ent = G_Find (NULL, FOFS(classname), "info_player_intermission");
/* find an intermission spot */
ent = G_Find(NULL, FOFS(classname), "info_player_intermission");
if (!ent)
{ // the map creator forgot to put in an intermission point...
ent = G_Find (NULL, FOFS(classname), "info_player_start");
{
/* the map creator forgot to put in an intermission point... */
ent = G_Find(NULL, FOFS(classname), "info_player_start");
if (!ent)
ent = G_Find (NULL, FOFS(classname), "info_player_deathmatch");
{
ent = G_Find(NULL, FOFS(classname), "info_player_deathmatch");
}
}
else
{ // chose one of four spots
{
/* chose one of four spots */
i = rand() & 3;
while (i--)
{
ent = G_Find (ent, FOFS(classname), "info_player_intermission");
if (!ent) // wrap around the list
ent = G_Find (ent, FOFS(classname), "info_player_intermission");
ent = G_Find(ent, FOFS(classname), "info_player_intermission");
if (!ent) /* wrap around the list */
{
ent = G_Find(ent, FOFS(classname), "info_player_intermission");
}
}
}
VectorCopy (ent->s.origin, level.intermission_origin);
VectorCopy (ent->s.angles, level.intermission_angle);
VectorCopy(ent->s.origin, level.intermission_origin);
VectorCopy(ent->s.angles, level.intermission_angle);
// move all clients to the intermission point
for (i=0 ; i<maxclients->value ; i++)
/* move all clients to the intermission point */
for (i = 0; i < maxclients->value; i++)
{
client = g_edicts + 1 + i;
if (!client->inuse)
{
continue;
MoveClientToIntermission (client);
}
MoveClientToIntermission(client);
}
}
/*
==================
DeathmatchScoreboardMessage
==================
*/
void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer)
void
DeathmatchScoreboardMessage(edict_t *ent, edict_t *killer)
{
char entry[1024];
char string[1400];
int stringlength;
int i, j, k;
int sorted[MAX_CLIENTS];
int sortedscores[MAX_CLIENTS];
int score, total;
int picnum;
int x, y;
gclient_t *cl;
edict_t *cl_ent;
char *tag;
char entry[1024];
char string[1400];
int stringlength;
int i, j, k;
int sorted[MAX_CLIENTS];
int sortedscores[MAX_CLIENTS];
int score, total;
int picnum;
int x, y;
gclient_t *cl;
edict_t *cl_ent;
char *tag;
//ZOID
if (ctf->value) {
CTFScoreboardMessage (ent, killer);
if (ctf->value)
{
CTFScoreboardMessage(ent, killer);
return;
}
//ZOID
// sort the clients by score
/* sort the clients by score */
total = 0;
for (i=0 ; i<game.maxclients ; i++)
for (i = 0; i < game.maxclients; i++)
{
cl_ent = g_edicts + 1 + i;
if (!cl_ent->inuse)
{
continue;
}
score = game.clients[i].resp.score;
for (j=0 ; j<total ; j++)
for (j = 0; j < total; j++)
{
if (score > sortedscores[j])
{
break;
}
}
for (k=total ; k>j ; k--)
for (k = total; k > j; k--)
{
sorted[k] = sorted[k-1];
sortedscores[k] = sortedscores[k-1];
sorted[k] = sorted[k - 1];
sortedscores[k] = sortedscores[k - 1];
}
sorted[j] = i;
sortedscores[j] = score;
total++;
}
// print level name and exit rules
/* print level name and exit rules */
string[0] = 0;
stringlength = strlen(string);
// add the clients in sorted order
/* add the clients in sorted order */
if (total > 12)
{
total = 12;
}
for (i=0 ; i<total ; i++)
for (i = 0; i < total; i++)
{
cl = &game.clients[sorted[i]];
cl_ent = g_edicts + 1 + sorted[i];
picnum = gi.imageindex ("i_fixme");
x = (i>=6) ? 160 : 0;
y = 32 + 32 * (i%6);
picnum = gi.imageindex("i_fixme");
x = (i >= 6) ? 160 : 0;
y = 32 + 32 * (i % 6);
// add a dogtag
/* add a dogtag */
if (cl_ent == ent)
{
tag = "tag1";
}
else if (cl_ent == killer)
{
tag = "tag2";
}
else
{
tag = NULL;
}
if (tag)
{
Com_sprintf (entry, sizeof(entry),
"xv %i yv %i picn %s ",x+32, y, tag);
Com_sprintf(entry, sizeof(entry),
"xv %i yv %i picn %s ", x + 32, y, tag);
j = strlen(entry);
if (stringlength + j > 1024)
{
break;
strcpy (string + stringlength, entry);
}
strcpy(string + stringlength, entry);
stringlength += j;
}
// send the layout
Com_sprintf (entry, sizeof(entry),
"client %i %i %i %i %i %i ",
x, y, sorted[i], cl->resp.score, cl->ping, (level.framenum - cl->resp.enterframe)/600);
/* send the layout */
Com_sprintf(entry, sizeof(entry), "client %i %i %i %i %i %i ",
x, y, sorted[i], cl->resp.score, cl->ping,
(level.framenum - cl->resp.enterframe) / 600);
j = strlen(entry);
if (stringlength + j > 1024)
{
break;
strcpy (string + stringlength, entry);
}
strcpy(string + stringlength, entry);
stringlength += j;
}
gi.WriteByte (svc_layout);
gi.WriteString (string);
gi.WriteByte(svc_layout);
gi.WriteString(string);
}
/*
==================
DeathmatchScoreboard
Draw instead of help message.
Note that it isn't that hard to overflow the 1400 byte message limit!
==================
*/
void DeathmatchScoreboard (edict_t *ent)
* Draw instead of help message.
* Note that it isn't that hard to
* overflow the 1400 byte message limit!
*/
void
DeathmatchScoreboard(edict_t *ent)
{
DeathmatchScoreboardMessage (ent, ent->enemy);
gi.unicast (ent, true);
DeathmatchScoreboardMessage(ent, ent->enemy);
gi.unicast(ent, true);
}
/*
==================
Cmd_Score_f
Display the scoreboard
==================
*/
void Cmd_Score_f (edict_t *ent)
* Display the scoreboard
*/
void
Cmd_Score_f(edict_t *ent)
{
ent->client->showinventory = false;
ent->client->showhelp = false;
//ZOID
if (ent->client->menu)
{
PMenu_Close(ent);
//ZOID
}
if (!deathmatch->value && !coop->value)
{
return;
}
if (ent->client->showscores)
{
@ -306,74 +359,75 @@ void Cmd_Score_f (edict_t *ent)
ent->client->showscores = true;
DeathmatchScoreboard (ent);
DeathmatchScoreboard(ent);
}
/*
==================
HelpComputer
Draw help computer.
==================
*/
void HelpComputer (edict_t *ent)
* Draw help computer.
*/
void
HelpComputer(edict_t *ent)
{
char string[1024];
char *sk;
char string[1024];
char *sk;
if (skill->value == 0)
{
sk = "easy";
}
else if (skill->value == 1)
{
sk = "medium";
}
else if (skill->value == 2)
{
sk = "hard";
}
else
{
sk = "hard+";
}
// send the layout
Com_sprintf (string, sizeof(string),
"xv 32 yv 8 picn help " // background
"xv 202 yv 12 string2 \"%s\" " // skill
"xv 0 yv 24 cstring2 \"%s\" " // level name
"xv 0 yv 54 cstring2 \"%s\" " // help 1
"xv 0 yv 110 cstring2 \"%s\" " // help 2
"xv 50 yv 164 string2 \" kills goals secrets\" "
"xv 50 yv 172 string2 \"%3i/%3i %i/%i %i/%i\" ",
sk,
level.level_name,
game.helpmessage1,
game.helpmessage2,
level.killed_monsters, level.total_monsters,
level.found_goals, level.total_goals,
level.found_secrets, level.total_secrets);
/* send the layout */
Com_sprintf(string, sizeof(string),
"xv 32 yv 8 picn help " /* background */
"xv 202 yv 12 string2 \"%s\" " /* skill */
"xv 0 yv 24 cstring2 \"%s\" " /* level name */
"xv 0 yv 54 cstring2 \"%s\" " /* help 1 */
"xv 0 yv 110 cstring2 \"%s\" " /* help 2 */
"xv 50 yv 164 string2 \" kills goals secrets\" "
"xv 50 yv 172 string2 \"%3i/%3i %i/%i %i/%i\" ",
sk,
level.level_name,
game.helpmessage1,
game.helpmessage2,
level.killed_monsters, level.total_monsters,
level.found_goals, level.total_goals,
level.found_secrets, level.total_secrets);
gi.WriteByte (svc_layout);
gi.WriteString (string);
gi.unicast (ent, true);
gi.WriteByte(svc_layout);
gi.WriteString(string);
gi.unicast(ent, true);
}
/*
==================
Cmd_Help_f
Display the current help message
==================
*/
void Cmd_Help_f (edict_t *ent)
* Display the current help message
*/
void
Cmd_Help_f(edict_t *ent)
{
// this is for backwards compatability
/* this is for backwards compatability */
if (deathmatch->value)
{
Cmd_Score_f (ent);
Cmd_Score_f(ent);
return;
}
ent->client->showinventory = false;
ent->client->showscores = false;
if (ent->client->showhelp && (ent->client->resp.game_helpchanged == game.helpchanged))
if (ent->client->showhelp &&
(ent->client->resp.game_helpchanged == game.helpchanged))
{
ent->client->showhelp = false;
return;
@ -381,33 +435,25 @@ void Cmd_Help_f (edict_t *ent)
ent->client->showhelp = true;
ent->client->resp.helpchanged = 0;
HelpComputer (ent);
HelpComputer(ent);
}
/* ======================================================================= */
//=======================================================================
/*
===============
G_SetStats
===============
*/
void G_SetStats (edict_t *ent)
void
G_SetStats(edict_t *ent)
{
gitem_t *item;
int index, cells;
int power_armor_type;
gitem_t *item;
int index, cells;
int power_armor_type;
//
// health
//
/* health */
ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health;
ent->client->ps.stats[STAT_HEALTH] = ent->health;
//
// ammo
//
if (!ent->client->ammo_index /* || !ent->client->pers.inventory[ent->client->ammo_index] */)
/* ammo */
if (!ent->client->ammo_index)
{
ent->client->ps.stats[STAT_AMMO_ICON] = 0;
ent->client->ps.stats[STAT_AMMO] = 0;
@ -415,37 +461,42 @@ void G_SetStats (edict_t *ent)
else
{
item = &itemlist[ent->client->ammo_index];
ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex (item->icon);
ent->client->ps.stats[STAT_AMMO] = ent->client->pers.inventory[ent->client->ammo_index];
ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex(item->icon);
ent->client->ps.stats[STAT_AMMO] =
ent->client->pers.inventory[ent->client->ammo_index];
}
cells = 0;
//
// armor
//
power_armor_type = PowerArmorType (ent);
/* armor */
power_armor_type = PowerArmorType(ent);
if (power_armor_type)
{
cells = ent->client->pers.inventory[ITEM_INDEX(FindItem ("cells"))];
cells = ent->client->pers.inventory[ITEM_INDEX(FindItem("cells"))];
if (cells == 0)
{ // ran out of cells for power armor
{
/* ran out of cells for power armor */
ent->flags &= ~FL_POWER_ARMOR;
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
power_armor_type = 0;;
gi.sound(ent, CHAN_ITEM, gi.soundindex(
"misc/power2.wav"), 1, ATTN_NORM, 0);
power_armor_type = 0;
}
}
index = ArmorIndex (ent);
if (power_armor_type && (!index || (level.framenum & 8) ) )
{ // flash between power armor and other armor icon
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex ("i_powershield");
index = ArmorIndex(ent);
if (power_armor_type && (!index || (level.framenum & 8)))
{
/* flash between power armor and other armor icon */
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex("i_powershield");
ent->client->ps.stats[STAT_ARMOR] = cells;
}
else if (index)
{
item = GetItemByIndex (index);
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex (item->icon);
item = GetItemByIndex(index);
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex(item->icon);
ent->client->ps.stats[STAT_ARMOR] = ent->client->pers.inventory[index];
}
else
@ -454,37 +505,38 @@ void G_SetStats (edict_t *ent)
ent->client->ps.stats[STAT_ARMOR] = 0;
}
//
// pickup message
//
/* pickup message */
if (level.time > ent->client->pickup_msg_time)
{
ent->client->ps.stats[STAT_PICKUP_ICON] = 0;
ent->client->ps.stats[STAT_PICKUP_STRING] = 0;
}
//
// timers
//
/* timers */
if (ent->client->quad_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad");
ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum)/10;
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_quad");
ent->client->ps.stats[STAT_TIMER] =
(ent->client->quad_framenum - level.framenum) / 10;
}
else if (ent->client->invincible_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_invulnerability");
ent->client->ps.stats[STAT_TIMER] = (ent->client->invincible_framenum - level.framenum)/10;
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex(
"p_invulnerability");
ent->client->ps.stats[STAT_TIMER] =
(ent->client->invincible_framenum - level.framenum) / 10;
}
else if (ent->client->enviro_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_envirosuit");
ent->client->ps.stats[STAT_TIMER] = (ent->client->enviro_framenum - level.framenum)/10;
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_envirosuit");
ent->client->ps.stats[STAT_TIMER] =
(ent->client->enviro_framenum - level.framenum) / 10;
}
else if (ent->client->breather_framenum > level.framenum)
{
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_rebreather");
ent->client->ps.stats[STAT_TIMER] = (ent->client->breather_framenum - level.framenum)/10;
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_rebreather");
ent->client->ps.stats[STAT_TIMER] =
(ent->client->breather_framenum - level.framenum) / 10;
}
else
{
@ -492,63 +544,78 @@ void G_SetStats (edict_t *ent)
ent->client->ps.stats[STAT_TIMER] = 0;
}
//
// selected item
//
/* selected item */
if (ent->client->pers.selected_item == -1)
{
ent->client->ps.stats[STAT_SELECTED_ICON] = 0;
}
else
ent->client->ps.stats[STAT_SELECTED_ICON] = gi.imageindex (itemlist[ent->client->pers.selected_item].icon);
{
ent->client->ps.stats[STAT_SELECTED_ICON] =
gi.imageindex(itemlist[ent->client->pers.selected_item].icon);
}
ent->client->ps.stats[STAT_SELECTED_ITEM] = ent->client->pers.selected_item;
//
// layouts
//
/* layouts */
ent->client->ps.stats[STAT_LAYOUTS] = 0;
if (deathmatch->value)
{
if (ent->client->pers.health <= 0 || level.intermissiontime
|| ent->client->showscores)
if ((ent->client->pers.health <= 0) || level.intermissiontime ||
ent->client->showscores)
{
ent->client->ps.stats[STAT_LAYOUTS] |= 1;
if (ent->client->showinventory && ent->client->pers.health > 0)
}
if (ent->client->showinventory && (ent->client->pers.health > 0))
{
ent->client->ps.stats[STAT_LAYOUTS] |= 2;
}
}
else
{
if (ent->client->showscores || ent->client->showhelp)
{
ent->client->ps.stats[STAT_LAYOUTS] |= 1;
if (ent->client->showinventory && ent->client->pers.health > 0)
}
if (ent->client->showinventory && (ent->client->pers.health > 0))
{
ent->client->ps.stats[STAT_LAYOUTS] |= 2;
}
}
//
// frags
//
/* frags */
ent->client->ps.stats[STAT_FRAGS] = ent->client->resp.score;
//
// help icon / current weapon if not shown
//
if (ent->client->resp.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)
/* help icon / current weapon if not shown */
if (ent->client->resp.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)
{
cvar_t *gun;
gun = gi.cvar("cl_gun", "2", 0);
if(gun->value != 2)
ent->client->ps.stats[STAT_HELPICON] = gi.imageindex (ent->client->pers.weapon->icon);
if (gun->value != 2)
{
ent->client->ps.stats[STAT_HELPICON] = gi.imageindex(
ent->client->pers.weapon->icon);
}
else
{
ent->client->ps.stats[STAT_HELPICON] = 0;
}
}
else
{
ent->client->ps.stats[STAT_HELPICON] = 0;
}
//ZOID
SetCTFStats(ent);
//ZOID
}