r3774 - in trunk/data: gfx qcsrc/client qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Fri Jul 4 10:56:24 EDT 2008
Author: blub0
Date: 2008-07-04 10:56:23 -0400 (Fri, 04 Jul 2008)
New Revision: 3774
Added:
trunk/data/gfx/sb_key_carrying_outline.tga
trunk/data/qcsrc/client/sbar.qc
trunk/data/qcsrc/client/sortlist.qc
trunk/data/qcsrc/client/teamplay.qc
Modified:
trunk/data/gfx/sb_key_carrying.tga
trunk/data/qcsrc/client/Main.qc
trunk/data/qcsrc/client/View.qc
trunk/data/qcsrc/client/csqc_constants.qc
trunk/data/qcsrc/client/ctf.qc
trunk/data/qcsrc/client/main.qh
trunk/data/qcsrc/client/ons.qc
trunk/data/qcsrc/client/progs.src
trunk/data/qcsrc/server/keyhunt.qc
trunk/data/qcsrc/server/keyhunt.qh
Log:
(experimental) CSQC Hud - can be turned off with "sbar_usecsqc 0"
Added victim's KeyHunt HUD
There may be some discrepancies between the new and the old hud.
After all, it's not a real "copy".
Modified: trunk/data/gfx/sb_key_carrying.tga
===================================================================
(Binary files differ)
Added: trunk/data/gfx/sb_key_carrying_outline.tga
===================================================================
(Binary files differ)
Property changes on: trunk/data/gfx/sb_key_carrying_outline.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/client/Main.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -15,8 +15,23 @@
{
};
+float last_pingrequest;
+float parse_ping;
+float ping_line;
+entity pingList;
+float pingbuf;
+
void CSQC_Init(void)
-{
+{
+ float i;
+ last_pingrequest = 0;
+ parse_ping = 0;
+ ping_line = 0;
+
+ pingList = spawn();
+ pingList.sort_next = NULL;
+ pingList.sort_prev = NULL;
+
menu_visible = FALSE;
menu_show = menu_show_error;
menu_action = menu_sub_null;
@@ -26,13 +41,30 @@
registercmd("ons_map");
//registercmd("menu_action");
+ registercvar("sbar_usecsqc", "1");
+
gametype = 0;
gps_start = world;
+
+ pingbuf = buf_create();
+ for(i = 0; i < maxclients; ++i)
+ bufstr_add(pingbuf, "-", false);
}
// CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
void CSQC_Shutdown(void)
{
+ entity next;
+
+ buf_del(pingbuf);
+
+ while(pingList.sort_next)
+ {
+ next = pingList.sort_next;
+ pingList.sort_next = next.sort_next;
+ remove(next);
+ }
+ remove(pingList);
}
// CSQC_ConsoleCommand : Used to parse commands in the console that have been registered with the "registercmd" function
@@ -87,38 +119,6 @@
void(float bIsNewEntity) CSQC_Ent_Update =
{
self.enttype = ReadByte();
-
- /*if (self.enttype == ENT_CLIENT)
- {
- setmodelindex(self, ReadShort());
- self.origin_x = ReadCoord();
- self.origin_y = ReadCoord();
- self.origin_z = ReadCoord();
- self.angles_x = ReadCoord();
- self.angles_y = ReadCoord();
- self.angles_z = ReadCoord();
- self.velocity_x = ReadCoord();
- self.velocity_y = ReadCoord();
- self.velocity_z = ReadCoord();
- pmove_org = self.origin;
- pmove_vel = self.velocity;
- self.avelocity_x = ReadCoord();
- self.avelocity_y = ReadCoord();
- self.avelocity_z = ReadCoord();
- self.movetype = ReadShort();
- self.frame = ReadShort();
- self.flags = ReadShort();
- self.colormap = ReadShort();
- setorigin(self, self.origin); // relink
- if (bIsNewEntity)
- {
- setsize(self, '0 0 0', '0 0 0');
- self.drawmask = MASK_NORMAL;
- //self.think = Client_Think;
- //self.nextthink = time;
- }
- self.ctf_state = ReadByte();
- }*/
if(self.enttype == ENT_CLIENT_ENTCS)
{
self.sv_entnum = ReadByte();
@@ -165,7 +165,8 @@
local float len;
local float file;
local vector mi_min, mi_max;
-
+
+ draw_enginesbar = true;
gametype = cvar("gametype");
if(gametype == GAME_ONSLAUGHT) {
if(!strcasecmp(substring(mapname, 0, 5), "maps/"))
@@ -211,6 +212,10 @@
precache_pic("gfx/ons-cp-blue.tga");
precache_pic("gfx/ons-frame.tga");
precache_pic("gfx/ons-frame-team.tga");
+ } else if(gametype == GAME_KEYHUNT) {
+ precache_pic("gfx/sb_key_carrying");
+ precache_pic("gfx/sb_key_carrying_outline");
+ draw_enginesbar = false;
}
}
// CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided. To execute standard behavior, simply execute localcmd with the string.
@@ -223,10 +228,75 @@
Gamemode_Init();
}
}
+
+void PingRequest()
+{
+ float i;
+ entity next;
+
+ last_pingrequest = time + 5;
+
+ parse_ping = 0;
+ ping_line = 0;
+ for(i = 0; i < maxclients; ++i)
+ {
+ if(strlen(getplayerkey(i, "name")))
+ ++parse_ping;
+ }
+
+ while(pingList.sort_next)
+ {
+ next = pingList.sort_next;
+ pingList.sort_next = next.sort_next;
+ remove(next);
+ }
+ pingList.sort_prev = NULL;
+
+ localcmd("\nping\n");
+}
+
// CSQC_Parse_Print : Provides the print string in the first parameter that the server provided. To execute standard behavior, simply execute print with the string.
void CSQC_Parse_Print(string strMessage)
{
- print(strMessage);
+ if(!parse_ping)
+ print(strMessage);
+ else if(strMessage != "Client ping times:\n")
+ {
+ float ping, i, p;
+ entity tmp;
+
+ // pingList.sort_prev = last element
+
+ ping = stof(strMessage);
+
+ /*strMessage = substring(strMessage, 5, 999);
+ print(strcat("Ping for # ", ftos(ping_line), " of ", ftos(parse_ping), " = ", ftos(ping), " player: "));
+ print(strMessage);
+ print(" searching... ");*/
+ for(i = 0; i < maxclients; ++i)
+ {
+ if(strlen(getplayerkey(i, "name"))) {
+ ++p;
+ if(p > ping_line)
+ break;
+ }
+ }
+ if(i >= maxclients)
+ i = maxclients-1;
+
+ bufstr_set(pingbuf, i, ftos(ping));
+ /*print(getplayerkey(i, "name"));
+ print("\n");*/
+
+ /*tmp = spawn();
+ tmp.sort_next = tmp.sort_prev = NULL;
+ pingList.sort_prev.sort_next = tmp;
+ pingList.sort_prev = tmp;*/
+
+ ++ping_line;
+ if(ping_line >= parse_ping)
+ parse_ping = false;
+ }
}
// CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided. To execute standard behavior, simply execute cprint with the string.
void CSQC_Parse_CenterPrint(string strMessage)
Modified: trunk/data/qcsrc/client/View.qc
===================================================================
--- trunk/data/qcsrc/client/View.qc 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/client/View.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -1,17 +1,48 @@
//include "main.qh"
+float sbar_alpha_fg;
+float last_weapon;
+float activeweapon;
+float weapontime;
+float sbar_hudselector;
+float teamplay;
+float myteam;
+
+float numteams; // NOTE: This is changed in Sbar_SortFrags, so use it only AFTER that
+
+void CSQC_common_hud(void);
+
+void CSQC_kh_hud(void);
+void CSQC_ctf_hud(void);
void CSQC_UpdateView(void)
{
+ sbar_alpha_fg = cvar("sbar_alpha_fg" );
+ sbar_hudselector = cvar("sbar_hudselector");
+ activeweapon = getstati(STAT_ACTIVEWEAPON);
+ teamplay = cvar("teamplay");
+
+ if(last_weapon != activeweapon) {
+ weapontime = time;
+ last_weapon = activeweapon;
+ }
+
+ if(last_pingrequest < time) {
+ PingRequest();
+ }
+
// ALWAYS Clear Current Scene First
R_ClearScene();
// Assign Standard Viewflags
// Draw the World (and sky)
R_SetView(VF_DRAWWORLD, 1);
+
// Draw the Crosshair
R_SetView(VF_DRAWCROSSHAIR, 1);
+
// Draw the Engine Status Bar (the default Quake HUD)
- R_SetView(VF_DRAWENGINESBAR, 1);
+ draw_enginesbar = !cvar("sbar_usecsqc");
+ R_SetView(VF_DRAWENGINESBAR, draw_enginesbar);
// Set the console size vars
vid_conwidth = cvar("vid_conwidth");
@@ -24,25 +55,8 @@
mousepos = mousepos*0.5 + getmousepos();
*/
- // Update the camera
- //UpdateCamera();
- /*self.origin_z += getstati(STAT_VIEWHEIGHT);
- R_SetView(VF_ORIGIN, self.origin);
- self.origin_z -= getstati(STAT_VIEWHEIGHT);
- R_SetView(VF_ANGLES, input_angles);*/
-
- // Setup Entities to be Rendered (include all base types; normal, engine and viewmodels)
R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
- /* Sample for 3D polygon rendering, do it before R_RenderScene!
- R_BeginPolygon("gfx/ctf_ic_atk.tga", 0);
- R_PolygonVertex('-5000 -5000 5200', '0 0', '1 1 1', 1);
- R_PolygonVertex(' 5000 -5000 5200', '1 0', '1 1 1', 1);
- R_PolygonVertex(' 5000 5000 -5200', '1 1', '1 1 1', 1);
- R_PolygonVertex('-5000 5000 -5200', '0 1', '1 1 1', 1);
- R_EndPolygon();
- */
-
// Render the Scene
R_RenderScene();
@@ -61,11 +75,114 @@
{
ctf_view();
} else */
+ if(!draw_enginesbar)
+ {
+ CSQC_common_hud();
+ }
+
if(gametype == GAME_ONSLAUGHT)
{
//drawstring('0 0', minimapname, '8 8 0', '1 1 1', 1, 0);
- drawsetcliparea(0,0,800,600);
+ //drawsetcliparea(0,0,800,600);
ons_view();
- drawresetcliparea();
+ //drawresetcliparea();
}
}
+
+void Sbar_Draw();
+void CSQC_common_hud(void)
+{
+ // Sbar_SortFrags(); done in Sbar_Draw
+ Sbar_Draw();
+}
+
+// KeyHunt HUD by victim
+void CSQC_kh_hud(void)
+{
+ // HUD 0 has the weapons on the right hand side - temporarily shown when needed
+ // HUD 1 has the weapons on the bottom - permanently
+
+ // use the following two binds to check the icons move correctly
+ // bind g "toggle sbar_flagstatus_right; echo Menu right $sbar_flagstatus_right" // move the icons
+ // bind h "toggle sbar_hudselector; echo HUD $sbar_hudselector" // change the HUD
+
+ float kh_keys, kh_keys_status, kh_teams_set;
+ float kh_margin_x, kh_margin_y;
+ string kh_carrying, kh_outline;
+ vector red_pos, blue_pos, yellow_pos, pink_pos, kh_size;
+ vector red, blue, yellow, pink;
+
+ kh_keys = cvar("kh_keys"); // set in keyhunt.qc
+ kh_keys_status = cvar("kh_keys_status"); // set in keyhunt.qc
+ kh_teams_set = cvar("_teams_available"); // set in keyhunt.qc
+
+// kh_margin_x = 10;
+ kh_margin_y = 8;
+ kh_margin_x = (cvar("sbar_flagstatus_right") * sbar_hudselector * (vid_conwidth - 66)) + 10;
+ // sbar_flagstatus_right 0/1; sbar_hudselector 0/1; screen width - key width + margin
+
+ red_pos_x = blue_pos_x = yellow_pos_x = pink_pos_x = kh_margin_x;
+
+ red_pos_y = kh_margin_y + 120*3;
+ blue_pos_y = kh_margin_y + 120*2;
+ yellow_pos_y = kh_margin_y + 120;
+ pink_pos_y = kh_margin_y + 0;
+
+ red = '1 0 0';
+ blue = '0 0 1';
+ yellow = '1 1 0';
+ pink = '1 0 1';
+
+ kh_size = '45 116';
+
+ kh_carrying = "gfx/sb_key_carrying";
+ kh_outline = "gfx/sb_key_carrying_outline";
+
+ // drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
+ // vector position = '0 0'; // 'x y' 0 0 (the origin) is in the top left. X 0 - 799, Y 0 - 599
+
+ // vector size = '0 0'; // 'x y' changes the x & y dimensions. '0 0' gives the default pic size
+ // vector rgb = '0 0 0'; // 'r g b' range 0 - 1
+
+ if (kh_keys_status & 1) // red
+ drawpic (red_pos, kh_carrying, kh_size, red, 0.2, 0); // show 20% alpha key
+ else
+ drawpic (red_pos, kh_outline, kh_size, red, 0.4, 0); // show key outline
+
+ if (kh_keys & 1) //red, added by victim
+ drawpic (red_pos, kh_carrying, kh_size, red, 1.0, 0); // show solid key
+
+
+ if (kh_keys_status & 2) // blue
+ drawpic (blue_pos, kh_carrying, kh_size, blue, 0.2, 0);
+ else
+ drawpic (blue_pos, kh_outline, kh_size, blue, 0.4, 0);
+
+ if (kh_keys & 2)
+ drawpic (blue_pos, kh_carrying, kh_size, blue, 1.0, 0);
+
+
+ if (kh_teams_set & 4) // yellow and pink
+ {
+ if (kh_keys_status & 4) // yellow
+ drawpic (yellow_pos, kh_carrying, kh_size, yellow, 0.2, 0);
+ else
+ drawpic (yellow_pos, kh_outline, kh_size, yellow, 0.4, 0);
+
+ if (kh_keys & 4) //red, added by victim
+ drawpic (yellow_pos, kh_carrying, kh_size, yellow, 1.0, 0);
+ }
+
+
+ if (kh_teams_set & 8) // pink only
+ {
+ if (kh_keys_status & 8) // pink
+ drawpic (pink_pos, kh_carrying, kh_size, pink, 0.2, 0);
+ else
+ drawpic (pink_pos, kh_outline, kh_size, pink, 0.4, 0);
+
+ if (kh_keys & 8) //red, added by victim
+ drawpic (pink_pos, kh_carrying, kh_size, pink, 1.0, 0);
+ }
+
+}
Modified: trunk/data/qcsrc/client/csqc_constants.qc
===================================================================
--- trunk/data/qcsrc/client/csqc_constants.qc 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/client/csqc_constants.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -59,6 +59,8 @@
const float STAT_ITEMS = 15;
const float STAT_VIEWHEIGHT = 16;
+const float STAT_TIMELIMIT = 236;
+
// Sound Constants
const float CHAN_AUTO = 0;
const float CHAN_WEAPON = 1;
@@ -159,3 +161,28 @@
const float BUTTON_14 = 65536;
const float BUTTON_15 = 131072;
const float BUTTON_16 = 262144;
+
+
+const float NEX_IT_UZI = 1;
+const float NEX_IT_SHOTGUN = 2;
+const float NEX_IT_GRENADE_LAUNCHER = 4;
+const float NEX_IT_ELECTRO = 8;
+const float NEX_IT_CRYLINK = 16;
+const float NEX_IT_NEX = 32;
+const float NEX_IT_HAGAR = 64;
+const float NEX_IT_ROCKET_LAUNCHER = 128;
+const float NEX_IT_SHELLS = 256;
+const float NEX_IT_BULLETS = 512;
+const float NEX_IT_ROCKETS = 1024;
+const float NEX_IT_CELLS = 2048;
+const float NEX_IT_LASER = 4094;
+const float NEX_IT_STRENGTH = 8192;
+const float NEX_IT_INVINCIBLE = 16384;
+const float NEX_IT_SPEED = 32768;
+const float NEX_IT_SLOWMO = 65536;
+
+const float DRAWFLAG_NORMAL = 0;
+const float DRAWFLAG_ADDITIVE = 1;
+const float DRAWFLAG_MODULATE = 2;
+const float DRAWFLAG_2XMODULATE = 3;
+const float DRAWFLAG_NUMFLAGS = 4;
Modified: trunk/data/qcsrc/client/ctf.qc
===================================================================
--- trunk/data/qcsrc/client/ctf.qc 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/client/ctf.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -33,15 +33,10 @@
if(getstati(STAT_CTF_STATE) == CTF_STATE_COMMANDER) {
drawstring(ps, "\x1D\x1E\x1E\x1E\x1E Order Menu \x1E\x1E\x1E\x1E\x1F", '8 8 0', '1 1 0', 1, 0); ps += po;
drawstring(ps, strcat("Order: ", ctf_temp_1), '8 8 0', '1 1 0', 1, 0); ps += po;
- //drawstring(ps, strcat("N1 = ", ftos(player_localnum), " - N2 = ", ftos(player_localentnum)), '8 8 0', '1 1 0', 1, 0); ps += po;
drawcolorcodedstring(ps, "1) ^3previous page", '8 8 0', 1, 0); ps += po;
drawcolorcodedstring(ps, "2) ^3next page", '8 8 0', 1, 0); ps += po;
- //drawcolorcodedstring(ps, strcat("Clients to go: ", ftos(maxclients)), '8 8 0', 1, 0); ps += po;
for((n = 2), (p = i = 0); i < maxclients && n > 0; ++i) {
frags = getplayerkey(i, "frags");
- /*print(strcat(ftos(i), "/", ftos(p), "/", ftos(n), "/", getplayerkey(i, "viewentity"), "\n"));
- print(strcat(" - name: ", getplayerkey(i, "name"), " - frags: ", frags, "\n"));
- print(strcat(" - color: ", getplayerkey(i, "topcolor"), " - ", color, "\n"));*/
if(!frags || (i+1) == player_localentnum)
continue;
if(frags == "-666" || getplayerkey(i, "topcolor") != color)
@@ -56,7 +51,6 @@
drawcolorcodedstring(ps, strcat(ftos(n), ") ", getplayerkey(i, "name"), " : ", ftos(getstatf(STAT_CTF_STATE))), '8 8 0', 1, 0); ps += po;
}
}
- //drawstring(ps, strcat("LocalEntNum = ", ftos(player_localnum)), '8 8 0', '1 1 0', 1, 0); ps += po;
drawstring(ps, "ESC) Exit Menu", '8 8 0', '1 1 0', 1, 0); ps += po;
} else {
menu_close();
Modified: trunk/data/qcsrc/client/main.qh
===================================================================
--- trunk/data/qcsrc/client/main.qh 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/client/main.qh 2008-07-04 14:56:23 UTC (rev 3774)
@@ -20,13 +20,6 @@
// Onslaught
// Map coordinate base calculations need these
-/*vector mi_redicon;
-vector mi_blueicon;
-vector mi_redbase;
-vector mi_bluebase;
-vector mi_scale;*/
-//vector mi_min;
-//vector mi_max;
vector mi_center;
vector mi_scale;
// Minimap
@@ -39,6 +32,10 @@
float gametype;
entity gps_start;
+float draw_enginesbar;
+//float sorted_players;
+//float sorted_teams;
+
// Defs
.float ctf_state;
.float health;
@@ -47,5 +44,8 @@
const float COLOR_TEAM_RED = 64;
const float COLOR_TEAM_BLUE = 208;
-const float COLOR_TEAM1 = 64;
-const float COLOR_TEAM2 = 208;
+const float COLOR_TEAM1 = 4; // red
+const float COLOR_TEAM2 = 13; // blue
+const float COLOR_TEAM3 = 12; // yellow
+const float COLOR_TEAM4 = 9; // pink
+const float COLOR_SPECTATOR = 1337;
Modified: trunk/data/qcsrc/client/ons.qc
===================================================================
--- trunk/data/qcsrc/client/ons.qc 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/client/ons.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -3,7 +3,7 @@
ons_showmap = !ons_showmap;
};
-vector(vector coord) mapCoords =
+vector(vector coord) mapcoords =
{
local vector ret;
ret = coord; // put that up to ret's definition and it's '0 0 0' ... stupid fteqcc
@@ -37,19 +37,12 @@
{
if(ons_showmap) {
local float color;
- local vector coord, dir, rgb;
+ local vector coord, rgb;
- color = stof(getplayerkey(player_localentnum-1, "topcolor"));
+ color = stof(getplayerkey(player_localentnum-1, "colors")) & 15;
- /*dir = pmove_org - mi_redbase;
-
- dir_x *= mi_scale_x;
- dir_y *= -mi_scale_y;
+ coord = mapcoords(pmove_org);
- coord = '272 50' + mi_redicon + dir*mi_scale_z;
- coord_z = 0;*/
- coord = mapCoords(pmove_org);
-
drawpic('272 50', minimapname, '256 256', '1 1 1', 1, 0);
drawpic('257 35', "gfx/ons-frame.tga", '286 286', '1 1 1', 1, 0);
if(color == COLOR_TEAM_RED)
@@ -68,7 +61,7 @@
for(tm = gps_start; tm != world; tm = tm.chain)
{
//print(strcat("GPS: ", ftos(tm.sv_entnum), " - ", vtos(tm.origin), "\n"));
- drawplayer(mapCoords(tm.origin), tm.angles, rgb);
+ drawplayer(mapcoords(tm.origin), tm.angles, rgb);
}
}
};
Modified: trunk/data/qcsrc/client/progs.src
===================================================================
--- trunk/data/qcsrc/client/progs.src 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/client/progs.src 2008-07-04 14:56:23 UTC (rev 3774)
@@ -6,8 +6,13 @@
csqc_builtins.qc
main.qh
+
+sortlist.qc
+teamplay.qc
+
ons.qc
ctf.qc
Main.qc
View.qc
+sbar.qc
Added: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc (rev 0)
+++ trunk/data/qcsrc/client/sbar.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -0,0 +1,832 @@
+
+float sb_lines; // still don't know what to do with that NOTE: check dp's sbar.c to see what that should be
+
+vector sbar;
+
+entity sortedPlayers;
+entity sortedTeams;
+
+.float sb_frags;
+.float sb_team;
+.float sb_player;
+
+void Sbar_FinaleOverlay()
+{
+}
+
+void Sbar_DrawWeapon(float nr, float fade, float active)
+{
+ vector pos, vsize, color;
+ float value;
+
+ value = (active) ? 1 : 0.6;
+ color_x = color_y = color_z = value;
+
+ if(sbar_hudselector == 1)
+ {
+ // width = 300, height = 100
+ const float w_width = 32, w_height = 12, w_space = 2, font_size = 8;
+
+ pos_x = (vid_conwidth - w_width * 9) * 0.5 + w_width * nr;
+ pos_y = (vid_conheight - w_height);
+ pos_z = 0;
+ vsize_x = w_width;
+ vsize_y = w_height;
+ vsize_z = 0;
+ drawpic(pos, strcat("gfx/inv_weapon", ftos(nr)), vsize, color, value * fade * sbar_alpha_fg, 0);
+ pos_x += w_space;
+ pos_y += w_space;
+ vsize_x = font_size;
+ vsize_y = font_size;
+ vsize_z = 0;
+ drawstring(pos, ftos(nr+1), vsize, '1 1 0', sbar_alpha_fg, 0);
+
+ }
+ else
+ {
+ // width = 300, height = 100
+ const float w2_width = 300, w2_height = 100, w2_space = 10;
+ const float w2_scale = 0.4;
+
+ pos_x = vid_conwidth - (w2_width + w2_space) * w2_scale;
+ pos_y = (w2_height + w2_space) * w2_scale * nr + w2_space;
+ pos_z = 0;
+ vsize_x = w2_width * w2_scale;
+ vsize_y = w2_height * w2_scale;
+ vsize_z = 0;
+
+ drawpic(pos, strcat("gfx/inv_weapon", ftos(nr)), vsize, color, value * fade * sbar_alpha_fg, 0);
+ }
+}
+void Sbar_DrawXNum (vector pos, float num, float digits, float lettersize, vector rgb, float a, float dflags)
+{
+ float l, i;
+ string str, tmp;
+ float minus;
+ vector vsize;
+
+ vsize_x = vsize_y = lettersize;
+ vsize_z = 0;
+
+ if(num < 0)
+ {
+ minus = true;
+ num = -num;
+ pos_x -= lettersize;
+ } else
+ minus = false;
+
+ if(digits < 0)
+ {
+ tmp = ftos(num);
+ digits = -digits;
+ str = strcat(substring("0000000000", 0, digits - strlen(tmp)), tmp);
+ } else
+ str = ftos(num);
+
+ l = strlen(str);
+
+ if(l > digits)
+ {
+ str = substring(str, l-digits, 999);
+ l = strlen(str);
+ } else if(l < digits)
+ pos_x += (digits-l) * lettersize;
+
+ if(minus)
+ {
+ drawpic(sbar + pos, "gfx/num_minus", vsize, rgb, a * sbar_alpha_fg, dflags);
+ pos_x += lettersize;
+ }
+
+ for(i = 0; i < l; ++i)
+ {
+ drawpic(sbar + pos, strcat("gfx/num_", substring(str, i, 1)), vsize, rgb, a * sbar_alpha_fg, dflags);
+ pos_x += lettersize;
+ }
+}
+
+float Sbar_PlayerCmp(entity l, entity r)
+{
+ if(teamplay)
+ {
+ if(l.sb_team < r.sb_team)
+ return true;
+ else if(l.sb_team > r.sb_team)
+ return false;
+ }
+ if(l.sb_frags > r.sb_frags)
+ return true;
+ else if(l.sb_frags < r.sb_frags)
+ return false;
+ return (l.sb_player > r.sb_player);
+}
+float Sbar_TeamCmp(entity l, entity r)
+{
+ if(l.sb_frags > r.sb_frags)
+ return true;
+ else if(l.sb_frags < r.sb_frags)
+ return false;
+ return (l.sb_player > r.sb_player);
+}
+
+void Sbar_SortFrags()
+{
+ float i;
+ entity tmp;
+ entity t1, t2, t3, t4, ts;
+
+ Sort_Remove(sortedPlayers);
+ sortedPlayers = Sort_New(Sbar_PlayerCmp);
+
+ numteams = 0;
+ if(teamplay)
+ {
+ Sort_Remove(sortedTeams);
+
+ t1 = spawn();
+ t2 = spawn();
+ t3 = spawn();
+ t4 = spawn();
+ ts = spawn();
+
+ t1.sb_team = COLOR_TEAM1;
+ t2.sb_team = COLOR_TEAM2;
+ t3.sb_team = COLOR_TEAM3;
+ t4.sb_team = COLOR_TEAM4;
+ ts.sb_team = COLOR_SPECTATOR;
+
+ t1.sb_player = t2.sb_player = t3.sb_player = t4.sb_player = ts.sb_player = 0;
+ t1.sb_frags = t2.sb_frags = t3.sb_frags = t4.sb_frags = 0;
+ sortedTeams = Sort_New(Sbar_TeamCmp);
+
+ for(i = 0; i < maxclients; ++i)
+ {
+ if(strlen(getplayerkey(i, "name")) <= 0)
+ continue;
+
+ tmp = spawn();
+ tmp.sb_player = i;
+ tmp.sb_frags = stof(getplayerkey(i, "frags"));
+ if(tmp.sb_frags == -666)
+ tmp.sb_team = COLOR_SPECTATOR;
+ else
+ tmp.sb_team = GetPlayerColor(i);
+
+ switch(tmp.sb_team)
+ {
+ case COLOR_TEAM1: t1.sb_frags += tmp.sb_frags; t1.sb_player++; break;
+ case COLOR_TEAM2: t2.sb_frags += tmp.sb_frags; t2.sb_player++; break;
+ case COLOR_TEAM3: t3.sb_frags += tmp.sb_frags; t3.sb_player++; break;
+ case COLOR_TEAM4: t4.sb_frags += tmp.sb_frags; t4.sb_player++; break;
+ case COLOR_SPECTATOR: ts.sb_frags += tmp.sb_frags; ts.sb_player++; break;
+ }
+
+ if(i == player_localentnum-1)
+ myteam = tmp.sb_team;
+
+ Sort_Add(sortedPlayers, tmp);
+ }
+ if(t1.sb_player) ++numteams;
+ if(t2.sb_player) ++numteams;
+ if(t3.sb_player) ++numteams;
+ if(t4.sb_player) ++numteams;
+
+ Sort_Add(sortedTeams, t1);
+ Sort_Add(sortedTeams, t2);
+ Sort_Add(sortedTeams, t3);
+ Sort_Add(sortedTeams, t4);
+ Sort_Add(sortedTeams, ts);
+
+ } else {
+ for(i = 0; i < maxclients; ++i)
+ {
+ if(strlen(getplayerkey(i, "name")) <= 0)
+ continue;
+
+ tmp = spawn();
+ tmp.sb_player = i;
+ tmp.sb_frags = stof(getplayerkey(i, "frags"));
+ if(tmp.sb_frags == -666)
+ tmp.sb_team = COLOR_SPECTATOR;
+ else
+ tmp.sb_team = COLOR_TEAM1;
+ Sort_Add(sortedPlayers, tmp);
+ }
+ }
+}
+
+void Sbar_PrintScoreboardItem(vector pos, entity pl, float is_self, float mask)
+{
+ vector tmp;
+ string str;
+
+ tmp_y = tmp_z = 0;
+ pos_x += 56;
+
+ str = bufstr_get(pingbuf, pl.sb_player);
+ tmp_x = 4*8 - strlen(str) * 8 - 56;
+ drawstring(pos + tmp, str, '8 8 0', '0.8 0.8 0.8', 0.8, 0);
+
+ if(!(mask & 1))
+ {
+ str = ftos(pl.sb_frags);
+ tmp_x = 4*8 - strlen(str) * 8;
+ drawstring(pos + tmp, str, '8 8 0', '1 1 1', 1, 0);
+ }
+
+ if(is_self)
+ drawstring(pos + '40 0 0', "\x0D", '8 8 0', '1 1 1', 1, 0);
+ str = getplayerkey(pl.sb_player, "name");
+ tmp_x = 5*8 - strlen(str) * 8 + 56;
+ drawcolorcodedstring(pos + '48 0 0', str, '8 8 0', 1, 0);
+}
+void Sbar_PrintScoreboardTeamItem(vector pos, entity tm, vector rgb, string name)
+{
+ vector tmp;
+ string str;
+
+ tmp_y = tmp_z = 0;
+ pos_x += 56;
+
+ str = ftos(tm.sb_frags);
+ tmp_x = 4*8 - strlen(str) * 8;
+ drawstring(pos + tmp, str, '8 8 0', rgb, 1, 0);
+
+ drawstring(pos + '48 0 0', name, '8 8 0', rgb, 1, 0);
+}
+
+void Sbar_DrawScoreboard()
+{
+ // Assume: frags are already sorted
+ float xmin, xmax, ymin, ymax;
+ vector pos, teammin, teammax, rgb;
+ entity pl, tm;
+ float specs;
+ specs = false;
+
+ xmin = vid_conwidth / 4;
+ xmax = vid_conwidth - xmin;
+ ymin = 64;
+ ymax = vid_conheight - 50;
+
+ pos_x = xmin;
+ pos_y = ymin;
+ pos_z = 0;
+
+ teammin = teammax = '0 0 0';
+ teammin_x = xmin - 2;
+ teammax_x = xmax - 2;
+
+ drawstring(pos, "ping", '8 8 0', '1 1 1', 1, 0);
+ drawstring(pos + '48 0 0', "frags", '8 8 0', '1 1 1', 1, 0);
+ drawstring(pos + '104 0 0', "name", '8 8 0', '1 1 1', 1, 0);
+ pos += '0 16 0';
+
+ if(teamplay)
+ {
+ //for(t = 0; t < 4; ++t)
+ for(tm = sortedTeams.sort_next; tm; tm = tm.sort_next)
+ {
+ if(!tm.sb_player || tm.sb_team == COLOR_SPECTATOR) // no players in it?
+ continue;
+
+ teammin_y = pos_y - 2;
+ teammax_y = pos_y + 2 + 10 * (tm.sb_player+1);
+ rgb = GetTeamRGB(tm.sb_team);
+ drawfill(teammin, teammax - teammin, rgb, 0.2, DRAWFLAG_NORMAL);
+ Sbar_PrintScoreboardTeamItem(pos, tm, rgb, GetTeamName(tm.sb_team));
+ pos += '0 12 0';
+ //for(i = 0; i < maxclients; ++i)
+ for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+ {
+ if(pl.sb_team != tm.sb_team)
+ continue;
+ Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 0);
+ pos += '0 10 0';
+ }
+
+ pos += '0 12 0';
+ }
+
+ // rgb := tempvector :)
+ rgb = pos + '0 12 0';
+ //pos += '64 24 0';
+ pos_y += 24;
+ //for(i = 0; i < maxclients; ++i)
+ for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+ {
+ if(pl.sb_team != COLOR_SPECTATOR)
+ continue;
+ //drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
+ Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 1);
+ pos += '0 10 0';
+ specs = true;
+ }
+
+ if(specs)
+ drawstring(rgb, "Spectators", '8 8 0', '1 1 1', 1, 0);
+ } else {
+ //for(i = 0; i < maxclients; ++i)
+ for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+ {
+ if(pl.sb_team != COLOR_TEAM1)
+ continue;
+ //drawstring(pos, ftos(pl.sb_frags), '8 8 0', '1 1 1', 1, 0);
+ //drawcolorcodedstring(pos + '64 0 0', getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
+ Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 0);
+ pos += '0 12 0';
+ }
+ rgb = pos + '0 12 0';
+ //pos += '64 24 0';
+ pos_y += 24;
+ for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+ {
+ if(pl.sb_team != COLOR_SPECTATOR)
+ continue;
+ specs = true;
+ //drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
+ Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 1);
+ pos += '0 12 0';
+ }
+ if(specs)
+ drawstring(rgb, "Spectators", '8 8 0', '1 1 1', 1, 0);
+ }
+}
+
+
+void Sbar_Score(float margin)
+{
+ float timelimit, timeleft, minutes, seconds, distribution, myplace;
+ vector sbar_save, place;
+ entity tm, pl, me;
+ sbar_save = sbar;
+
+ sbar_y = vid_conheight - (32+12);
+ sbar_x -= margin;
+
+ place = '-48 -12 0';
+ if(teamplay)
+ {
+ // Layout:
+ //
+ // team1 team3 team4
+ //
+ // TEAM2
+ //for(i = 0; i < 4; ++i)
+ for(tm = sortedTeams.sort_next; tm; tm = tm.sort_next)
+ {
+ if(tm.sb_team == COLOR_SPECTATOR || !tm.sb_player) // no players? don't display
+ continue;
+ // -32*4 = -128
+ if(tm.sb_team == myteam)
+ Sbar_DrawXNum('-128 0', tm.sb_frags, 4, 32, GetTeamRGB(tm.sb_team), 1, DRAWFLAG_NORMAL);
+ else
+ {
+ Sbar_DrawXNum(place, tm.sb_frags, 4, 12, GetTeamRGB(tm.sb_team), 1, DRAWFLAG_NORMAL);
+ place_x -= 4*12;
+ }
+ }
+ } else {
+ // me vector := [team/connected frags id]
+ myplace = 0;
+ for(me = sortedPlayers.sort_next; me; me = me.sort_next)
+ {
+ if(me.sb_team != COLOR_SPECTATOR)
+ ++myplace;
+ if(me.sb_player == player_localentnum - 1)
+ break;
+ }
+ pl = sortedPlayers.sort_next;
+ if(pl == me)
+ pl = pl.sort_next;
+
+ if(pl && myplace != 1)
+ {
+ distribution = me.sb_frags - pl.sb_frags;
+ } else if(pl) {
+ distribution = me.sb_frags - pl.sb_frags;
+ } else
+ distribution = 0;
+
+ if(myplace == 1)
+ Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+ else if(myplace == 2)
+ Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
+ else
+ Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 0 0', 1, DRAWFLAG_NORMAL);
+
+ if(distribution >= 0)
+ {
+ Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 1 1', 1, DRAWFLAG_NORMAL);
+ Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 1 1', 1, DRAWFLAG_NORMAL);
+ } else if(distribution >= -5)
+ {
+ Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 1 0', 1, DRAWFLAG_NORMAL);
+ Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 1 0', 1, DRAWFLAG_NORMAL);
+ } else {
+ Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 0 0', 1, DRAWFLAG_NORMAL);
+ Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 0 0', 1, DRAWFLAG_NORMAL);
+ }
+ }
+ timelimit = getstatf(STAT_TIMELIMIT);
+ if(timelimit)
+ {
+ timeleft = max(0, timelimit * 60 - time);
+ minutes = floor(timeleft / 60);
+ seconds = floor(timeleft - minutes*60);
+ if(minutes >= 5)
+ {
+ Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+ drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 1', sbar_alpha_fg, 0);
+ Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+ } else if(minutes >= 1)
+ {
+ Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
+ drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 0', sbar_alpha_fg, 0);
+ Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
+ } else {
+ Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 0 0', 1, DRAWFLAG_NORMAL);
+ }
+ } else {
+ minutes = floor(time / 60);
+ seconds = floor(time - minutes*60);
+ Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+ drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 1', sbar_alpha_fg, 0);
+ Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+ }
+ sbar = sbar_save;
+}
+
+void Sbar_MiniscoreItem(vector pos, entity pl, float is_self)
+{
+ float x;
+ pos_x += 72;
+
+ if(teamplay)
+ drawfill(pos + '0 1 0', '40 6 0', GetTeamRGB(pl.sb_team)*0.5, 1, DRAWFLAG_NORMAL);
+ else
+ drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
+ x = pos_x;
+ pos_x += 5*8;
+ pos_x -= strlen(ftos(pl.sb_frags))*8;
+ drawstring(pos, ftos(pl.sb_frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ pos_x = x;
+ if(is_self)
+ {
+ pos_x += 48;
+ drawstring(pos, "\x0D", '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ pos_x += 8;
+ } else
+ pos_x += 56;
+ drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
+}
+
+void Sbar_MiniscoreTeamItem(vector pos, float color, float frags, float is_self)
+{
+ float x;
+ pos_x += 72;
+
+ if(teamplay)
+ drawfill(pos + '0 1 0', '40 6 0', GetTeamRGB(color)*0.5, 1, DRAWFLAG_NORMAL);
+ else
+ drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
+ x = pos_x;
+ pos_x += 5*8;
+ pos_x -= strlen(ftos(frags))*8;
+ drawstring(pos, ftos(frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ pos_x = x;
+ if(is_self)
+ {
+ pos_x += 48;
+ drawstring(pos, "\x0D", '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ pos_x += 8;
+ } else
+ pos_x += 56;
+ drawstring(pos, GetTeamName(color), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+}
+
+void Sbar_MiniDeathmatchOverlay(vector pos)
+{
+ float i, numlines, up, down;
+ entity me, tm, pl;
+ float miniscoreboard_size;
+ miniscoreboard_size = cvar("sbar_miniscoreboard_size");
+
+ if(miniscoreboard_size == 0)
+ return;
+ pos_y = vid_conheight - 8;
+
+ if(miniscoreboard_size < 0)
+ numlines = (vid_conheight - sbar_y + 7) / 8;
+ else
+ numlines = miniscoreboard_size;
+
+ // give up if there isn't enough room
+ if(pos_x >= vid_conwidth || pos_y >= vid_conheight || numlines < 1)
+ return;
+
+ // me vector := [team/connected frags id]
+ for(me = sortedPlayers.sort_next; me; me = me.sort_next)
+ {
+ if(me.sb_player == player_localentnum - 1)
+ break;
+ }
+
+ if(teamplay)
+ numlines -= numteams;
+
+ // figure out how many players above and below we can show
+ up = floor(numlines/2);
+ down = up;
+ if((up + down) > numlines)
+ down = numlines - up;
+
+ // render bottom-up
+ for(pl = me.sort_next; pl && down > 0; pl = pl.sort_next)
+ {
+ if(pl.sb_team == COLOR_SPECTATOR)
+ continue;
+ Sbar_MiniscoreItem(pos, pl, false);
+ pos_y -= 9;
+ --down;
+ }
+ Sbar_MiniscoreItem(pos, me, true);
+ pos_y -= 9;
+ up += down; // if there weren't enough lines below... add them
+ for(pl = me.sort_prev; pl != sortedPlayers && up > 0; pl = pl.sort_prev)
+ {
+ if(pl.sb_team == COLOR_SPECTATOR)
+ continue;
+ Sbar_MiniscoreItem(pos, pl, false);
+ pos_y -= 9;
+ --up;
+ }
+
+ if(teamplay)
+ {
+ for(tm = sortedTeams.sort_next; tm.sort_next; tm = tm.sort_next);
+ for(; tm != sortedTeams; tm = tm.sort_prev)
+ {
+ if(!tm.sb_player || tm.sb_team == COLOR_SPECTATOR) // no players?
+ continue;
+ Sbar_MiniscoreTeamItem(pos, tm.sb_team, tm.sb_frags, (tm.sb_team == me.sb_team));
+ pos_y -= 9;
+ }
+ }
+}
+
+void Sbar_Draw (void)
+{
+ float i;
+ float x, fade;
+ float stat_items;
+
+ Sbar_SortFrags();
+
+ sb_lines = 24;
+
+ if (sb_showscores)
+ Sbar_DrawScoreboard();
+ else if (intermission == 1)
+ {
+ Sbar_DrawScoreboard();
+ return;
+ }
+ else if (intermission == 2)
+ Sbar_FinaleOverlay();
+ else
+ {
+ if (sb_showscores || (getstati(STAT_HEALTH) <= 0 && cvar("cl_deathscoreboard")))
+ {
+ sbar_x = (vid_conwidth - 640.0)*0.5;
+ sbar_y = vid_conheight - 47;
+ //Sbar_DrawAlphaPic (sbar_x, sbar_y, sb_scorebar, sbar_alpha_bg.value);
+ drawpic('0 0', "gfx/scorebar", '0 0 0', '1 1 1', cvar("sbar_alpha_bg"), 0);
+ Sbar_DrawScoreboard ();
+ }
+ else
+ {
+ if (sb_lines && sbar_hudselector == 1)
+ {
+ stat_items = getstati(STAT_ITEMS);
+
+ sbar_x = (vid_conwidth - 320.0)*0.5;
+ sbar_y = vid_conheight - 24.0 - 16.0;
+ sbar_z = 0;
+
+ fade = 3.2 - 2 * (time - weapontime);
+ fade = bound(0.7, fade, 1);
+
+ x = 1.0;
+ for(i = 0; i < 8; ++i)
+ {
+ if(stat_items & x)
+ {
+ Sbar_DrawWeapon(i+1, fade, (i + 2 == activeweapon));
+ }
+ x *= 2;
+ }
+ x *= 2*2*2*2;
+ if(stat_items & x)
+ {
+ Sbar_DrawWeapon(0, fade, (activeweapon == 1));
+ }
+
+ // armor
+ x = getstati(STAT_ARMOR);
+ if (x > 0)
+ {
+ // "gfx/sb_armor"
+ //Sbar_DrawStretchPic (72, 0, sb_armor[0], sbar_alpha_fg.value, 24, 24);
+ drawpic(sbar + '72 0', "gfx/sb_armor", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+ if(x > 200)
+ Sbar_DrawXNum('0 0', x, 3, 24, '0 1 0', 1, 0);
+ else if(x > 100)
+ Sbar_DrawXNum('0 0', x, 3, 24, '0.2 1 0', 1, 0);
+ else if(x > 50)
+ Sbar_DrawXNum('0 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+ else if(x > 25)
+ Sbar_DrawXNum('0 0', x, 3, 24, '1 1 0.2', 1, 0);
+ else
+ Sbar_DrawXNum('0 0', x, 3, 24, '0.7 0 0', 1, 0);
+ }
+
+ // health
+ x = getstati(STAT_HEALTH);
+ if (x != 0)
+ {
+ // "gfx/sb_health"
+ //Sbar_DrawStretchPic (184, 0, sb_health, sbar_alpha_fg.value, 24, 24);
+ drawpic(sbar + '184 0', "gfx/sb_health", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+ if(x > 200)
+ Sbar_DrawXNum('112 0', x, 3, 24, '0 1 0', 1, 0);
+ else if(x > 100)
+ Sbar_DrawXNum('112 0', x, 3, 24, '0.2 1 0', 1, 0);
+ else if(x > 50)
+ Sbar_DrawXNum('112 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+ else if(x > 25)
+ Sbar_DrawXNum('112 0', x, 3, 24, '1 1 0.2', 1, 0);
+ else
+ Sbar_DrawXNum('112 0', x, 3, 24, '0.7 0 0', 1, 0);
+ }
+
+ // ammo
+ x = getstati(STAT_AMMO);
+ if ((stat_items & (NEX_IT_SHELLS | NEX_IT_BULLETS | NEX_IT_ROCKETS | NEX_IT_CELLS)) || x != 0)
+ {
+ if (stat_items & NEX_IT_SHELLS)
+ drawpic(sbar + '296 0', "gfx/sb_shells", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+ else if (stat_items & NEX_IT_BULLETS)
+ drawpic(sbar + '296 0', "gfx/sb_bullets", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+ else if (stat_items & NEX_IT_ROCKETS)
+ drawpic(sbar + '296 0', "gfx/sb_rocket", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+ else if (stat_items & NEX_IT_CELLS)
+ drawpic(sbar + '296 0', "gfx/sb_cells", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+ if(x > 10)
+ Sbar_DrawXNum('224 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+ else
+ Sbar_DrawXNum('224 0', x, 3, 24, '0.7 0 0', 1, 0);
+ }
+
+ if (sbar_x + 320 + 160 <= vid_conwidth)
+ Sbar_MiniDeathmatchOverlay(sbar + '320 0');
+ if (sbar_x > 0)
+ Sbar_Score(16);
+ // The margin can be at most 8 to support 640x480 console size:
+ // 320 + 2 * (144 + 16) = 640
+ }
+ else if (sb_lines)
+ {
+
+ stat_items = getstati(STAT_ITEMS);
+
+ sbar_x = (vid_conwidth - 640.0)*0.5;
+ sbar_y = vid_conheight - 47;
+ sbar_z = 0;
+
+ fade = 3 - 2 * (time - weapontime);
+
+ x = 1.0;
+ for(i = 0; i < 8; ++i)
+ {
+ if(stat_items & x)
+ {
+ Sbar_DrawWeapon(i+1, fade, (i + 2 == activeweapon));
+ }
+ x *= 2;
+ }
+ x *= 2*2*2*2;
+ if(stat_items & x)
+ {
+ Sbar_DrawWeapon(0, fade, (activeweapon == 1));
+ }
+
+ if (sb_lines > 24)
+ drawpic(sbar, "gfx/sbar", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+ else
+ drawpic(sbar, "gfx/sbar_minimal", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+
+ // armor
+ // (340-3*24) = 268
+ Sbar_DrawXNum('268 12', getstati(STAT_ARMOR), 3, 24, '0.6 0.7 0.8', 1, 0);
+
+ // health
+ // (154-3*24) = 82
+ x = getstati(STAT_HEALTH);
+ if(x > 100)
+ Sbar_DrawXNum('82 12', x, 3, 24, '1 1 1', 1, 0);
+ else if(x <= 25 && time - floor(time) > 0.5)
+ Sbar_DrawXNum('82 12', x, 3, 24, '0.7 0 0', 1, 0);
+ else
+ Sbar_DrawXNum('81 12', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+
+ // AK dont draw ammo for the laser
+ x = getstati(STAT_AMMO);
+ if(activeweapon != 12)
+ {
+ // (519-3*24) = 447
+ if (stat_items & NEX_IT_SHELLS)
+ drawpic(sbar + '519 0', "gfx/sb_shells", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+ else if (stat_items & NEX_IT_BULLETS)
+ drawpic(sbar + '519 0', "gfx/sb_bullets", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+ else if (stat_items & NEX_IT_ROCKETS)
+ drawpic(sbar + '519 0', "gfx/sb_rocket", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+ else if (stat_items & NEX_IT_CELLS)
+ drawpic(sbar + '519 0', "gfx/sb_cells", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+ if(x > 10)
+ Sbar_DrawXNum('447 12', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+ else
+ Sbar_DrawXNum('447 12', x, 3, 24, '0.7 0 0', 1, 0);
+ }
+
+ if (sb_lines > 24)
+ drawpic(sbar, "gfx/sbar_overlay", '0 0 0', '1 1 1', 1, DRAWFLAG_MODULATE);
+
+ if (sbar_x + 600 + 160 <= vid_conwidth)
+ Sbar_MiniDeathmatchOverlay (sbar + '600 0');
+
+ if (sbar_x > 0)
+ Sbar_Score(-16);
+ // Because:
+ // Mini scoreboard uses 12*4 per other team, that is, 144
+ // pixels when there are four teams...
+ // Nexuiz by default sets vid_conwidth to 800... makes
+ // sbar_x == 80...
+ // so we need to shift it by 64 pixels to the right to fit
+ // BUT: then it overlaps with the image that gets drawn
+ // for viewsize 100! Therefore, just account for 3 teams,
+ // that is, 96 pixels mini scoreboard size, needing 16 pixels
+ // to the right!
+ }
+
+
+ if(gametype == GAME_KEYHUNT)
+ {
+ CSQC_kh_hud();
+ } else if(gametype == GAME_CTF)
+ {
+ CSQC_ctf_hud();
+ }
+ }
+ }
+}
+
+void CSQC_ctf_hud(void)
+{
+ // cvar("sbar_flagstatus_right") move the flag icons right
+ // cvar("sbar_flagstatus_pos") pixel position of the nexuiz flagstatus icons
+ float redflag, blueflag;
+ float stat_items;
+ vector pos;
+
+ stat_items = getstati(STAT_ITEMS);
+ redflag = (stat_items/32768) & 3;
+ blueflag = (stat_items/131072) & 3;
+
+ pos_x = (cvar("sbar_flagstatus_right")) ? vid_conwidth - 10 - sbar_x - 64 : 10 - sbar_x;
+ pos_z = 0;
+
+ if(sbar_hudselector == 1)
+ pos_y = (vid_conheight - sbar_y) - cvar("sbar_flagstatus_pos") - 64;
+ else
+ pos_y = -117;
+
+ pos += sbar;
+
+ switch(redflag)
+ {
+ case 1: drawpic(pos, "gfx/sb_flag_red_taken", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
+ case 2: drawpic(pos, "gfx/sb_flag_red_lost", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
+ case 3: drawpic(pos, "gfx/sb_flag_red_carrying", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
+ }
+
+ pos_y -= 64;
+
+ switch(blueflag)
+ {
+ case 1: drawpic(pos, "gfx/sb_flag_blue_taken", '0 0 0', '1 1 1', 1, 0); break;
+ case 2: drawpic(pos, "gfx/sb_flag_blue_lost", '0 0 0', '1 1 1', 1, 0); break;
+ case 3: drawpic(pos, "gfx/sb_flag_blue_carrying", '0 0 0', '1 1 1', 1, 0); break;
+ }
+}
Added: trunk/data/qcsrc/client/sortlist.qc
===================================================================
--- trunk/data/qcsrc/client/sortlist.qc (rev 0)
+++ trunk/data/qcsrc/client/sortlist.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -0,0 +1,63 @@
+
+
+.float(entity,entity) sort_cmp;
+.entity sort_next, sort_prev;
+
+entity Sort_New(float(entity,entity) cmp)
+{
+ entity sort;
+ sort = spawn();
+ sort.sort_cmp = cmp;
+ sort.sort_next = NULL;
+ return sort;
+}
+
+void Sort_Remove(entity sort)
+{
+ entity next;
+ while(sort.sort_next)
+ {
+ next = sort.sort_next;
+ remove(sort);
+ sort = next;
+ }
+ remove(sort);
+}
+
+void Sort_Add(entity sort, entity ent)
+{
+ entity next, parent;
+ parent = sort;
+ next = sort.sort_next;
+ while(next && sort.sort_cmp(next, ent))
+ {
+ parent = next;
+ next = next.sort_next;
+ }
+ ent.sort_next = next;
+ ent.sort_prev = parent;
+ parent.sort_next = ent;
+ if(next)
+ next.sort_prev = ent;
+}
+
+entity Sort_Get(entity sort, float i)
+{
+ for(; sort.sort_next && i > 0; --i)
+ sort = sort.sort_next;
+ return sort;
+}
+
+void Sort_DoSort(entity sort)
+{
+ entity newsort, next, tmp;
+ newsort = Sort_New(sort.sort_cmp);
+ next = sort.sort_next;
+ while(next)
+ {
+ tmp = next.sort_next;
+ Sort_Add(newsort, next);
+ next = tmp;
+ }
+ sort.sort_next = newsort.sort_next;
+}
Added: trunk/data/qcsrc/client/teamplay.qc
===================================================================
--- trunk/data/qcsrc/client/teamplay.qc (rev 0)
+++ trunk/data/qcsrc/client/teamplay.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -0,0 +1,41 @@
+
+float TeamByColor(float color)
+{
+ switch(color)
+ {
+ case COLOR_TEAM1: return 0;
+ case COLOR_TEAM2: return 1;
+ case COLOR_TEAM3: return 2;
+ case COLOR_TEAM4: return 3;
+ default: return 0;
+ }
+}
+
+float GetPlayerColor(float i)
+{
+ return stof(getplayerkey(i, "colors")) & 15;
+}
+
+vector GetTeamRGB(float color)
+{
+ switch(color)
+ {
+ default: return '1 1 1';
+ case COLOR_TEAM1: return '1 0 0'; // red
+ case COLOR_TEAM2: return '0 0 1'; // blue
+ case COLOR_TEAM3: return '1 1 0'; // yellow
+ case COLOR_TEAM4: return '1 0 1'; // pink
+ }
+}
+
+string GetTeamName(float color)
+{
+ switch(color)
+ {
+ default: return "Spectators";
+ case COLOR_TEAM1: return "Red Team";
+ case COLOR_TEAM2: return "Blue Team";
+ case COLOR_TEAM3: return "Yellow Team";
+ case COLOR_TEAM4: return "Pink Team";
+ }
+}
Modified: trunk/data/qcsrc/server/keyhunt.qc
===================================================================
--- trunk/data/qcsrc/server/keyhunt.qc 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/server/keyhunt.qc 2008-07-04 14:56:23 UTC (rev 3774)
@@ -23,6 +23,15 @@
string kh_Controller_Waitmsg;
+.float siren_time; // time delay the siren
+.float stuff_time; // time delay to stuffcmd a cvar
+
+float test[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+//test[0] = status of dropped keys, test[1 - 16] = player #
+//replace 17 with cvar("maxplayers") or similar !!!!!!!!!
+//for(i = 0; i < maxplayers; ++i)
+// test[i] = "0";
+
float kh_Team_ByID(float t)
{
if(t == 0) return COLOR_TEAM1;
@@ -47,11 +56,12 @@
string kh_sound_destroy = "sound/kh/destroy.wav";
string kh_sound_drop = "sound/kh/drop.wav";
string kh_sound_collect = "sound/kh/collect.wav";
+string kh_sound_alarm = "sound/kh/alarm.wav"; // the new siren/alarm
float kh_sprite_dropped, kh_sprite_finish, kh_sprite_red, kh_sprite_blue, kh_sprite_pink, kh_sprite_yellow, kh_sprite_friend;
float kh_key_dropped, kh_key_carried;
-float kh_GetCarrierSprite(float t, float e)
+float kh_GetCarrierSprite(float t, float e) // runs all the time
{
if(t == e) return kh_sprite_friend;
if(t == COLOR_TEAM1) return kh_sprite_red;
@@ -61,7 +71,7 @@
return 0;
}
-void kh_Controller_SetThink(float t, string msg, kh_Think_t func)
+void kh_Controller_SetThink(float t, string msg, kh_Think_t func) // runs occasionaly
{
kh_Controller_Thinkfunc = func;
kh_controller.cnt = t;
@@ -75,7 +85,7 @@
kh_controller.nextthink = time; // force
}
-void kh_Controller_Think()
+void kh_Controller_Think() // called a lot
{
entity e;
if(intermission_running)
@@ -108,7 +118,7 @@
// frags f: take from cvar * f
// frags 0: no frags
-void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)
+void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner) // update the score when a key is captured
{
string s;
if(intermission_running)
@@ -117,7 +127,7 @@
UpdateFrags(player, frags_player);
if(key && key.owner && frags_owner)
UpdateFrags(key.owner, frags_owner);
- if(!cvar("sv_eventlog"))
+ if(!cvar("sv_eventlog")) //output extra info to the console or text file
return;
s = strcat(":keyhunt:", what, ":", ftos(player.playerid));
s = strcat(s, ":", ftos(frags_player));
@@ -131,7 +141,7 @@
GameLogEcho(s, FALSE);
}
-vector kh_AttachedOrigin(entity e)
+vector kh_AttachedOrigin(entity e) // runs when a team captures the flag, it can run 2 or 3 times.
{
if(e.tag_entity)
{
@@ -142,7 +152,7 @@
return e.origin;
}
-void kh_Key_Attach(entity key)
+void kh_Key_Attach(entity key) // runs when a player picks up a key and several times when a key is assigned to a player at the start of a round
{
#ifdef KH_PLAYER_USE_ATTACHMENT
entity first;
@@ -172,7 +182,7 @@
}
#else
setattachment(key, key.owner, "");
- setorigin(key, '0 0 1' * KH_KEY_ZSHIFT); // fixing x, y in think
+ setorigin(key, '0 0 1' * KH_KEY_ZSHIFT); // fixing x, y in think
key.angles_y -= key.owner.angles_y;
#endif
key.flags = 0;
@@ -184,8 +194,24 @@
key.modelindex = kh_key_carried;
}
-void kh_Key_Detach(entity key)
+void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs several times times when all the keys are captured
{
+ float i;
+ i = test[key.owner.playerid];
+ if(key.netname == "^1red key")
+ i -= 1;
+ if(key.netname == "^4blue key")
+ i -= 2;
+ if(key.netname == "^3yellow key")
+ i -= 4;
+ if(key.netname == "^6pink key")
+ i -= 8;
+ test[key.owner.playerid] = i;
+
+ kh_show_temp();
+
+ stuffcmd(key.owner, strcat("set kh_keys ", ftos(test[key.owner.playerid]), "\n")); // send to current player
+
#ifdef KH_PLAYER_USE_ATTACHMENT
entity first;
first = key.owner.kh_next;
@@ -224,7 +250,7 @@
key.kh_previous_owner = key.owner;
}
-void kh_Key_AssignTo(entity key, entity player)
+void kh_Key_AssignTo(entity key, entity player) // runs every time a key is picked up or assigned. Runs prior to kh_key_attach
{
if(key.owner == player)
return;
@@ -258,6 +284,22 @@
if(key.kh_next)
key.kh_next.kh_prev = key;
+ float i;
+ i = test[key.owner.playerid];
+ if(key.netname == "^1red key")
+ i += 1;
+ if(key.netname == "^4blue key")
+ i += 2;
+ if(key.netname == "^3yellow key")
+ i += 4;
+ if(key.netname == "^6pink key")
+ i += 8;
+ test[key.owner.playerid] = i;
+
+ kh_show_temp();
+
+ stuffcmd(player, strcat("set kh_keys ", ftos(test[key.owner.playerid]), "\n")); // send to current player
+
kh_Key_Attach(key);
if(key.kh_next == world)
@@ -283,7 +325,7 @@
self.team = attacker.team;
}
-void kh_Key_Spawn(entity initial_owner, float angle)
+void kh_Key_Spawn(entity initial_owner, float angle) // runs every time a new flag is created, ie after all the keys have been collected
{
entity key;
key = spawn();
@@ -326,7 +368,7 @@
key.kh_worldkeynext = kh_worldkeylist;
kh_worldkeylist = key;
- sprint(initial_owner, strcat("You got the ^2", key.netname, "\n"));
+ centerprint(initial_owner, strcat("You are starting with the ", key.netname, "\n")); // message to player at start of round
WaypointSprite_Spawn("", 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, FALSE);
key.waypointsprite_attachedforcarrier.waypointsprite_for_player = kh_Key_waypointsprite_for_player;
@@ -334,7 +376,7 @@
kh_Key_AssignTo(key, initial_owner);
}
-void kh_Key_Remove(entity key)
+void kh_Key_Remove(entity key) // runs after when all the keys have been collected or when a key has been dropped for more than X seconds
{
entity o;
o = key.owner;
@@ -365,7 +407,7 @@
}
// -1 when no team completely owns all keys yet
-float kh_Key_AllOwnedByWhichTeam()
+float kh_Key_AllOwnedByWhichTeam() // constantly called. check to see if all the keys are owned by the same team
{
entity key;
float teem;
@@ -383,14 +425,19 @@
return teem;
}
-void kh_Key_Collect(entity key, entity player)
+void kh_Key_Collect(entity key, entity player) //a player picks up a dropped key
{
sound(player, CHAN_AUTO, kh_sound_collect, 1, ATTN_NORM);
if(key.kh_dropperteam != player.team)
kh_Scores_Event(player, key, "collect", cvar("g_balance_keyhunt_score_collect"), 0);
key.kh_dropperteam = 0;
- bprint(player.netname, "^7 collected the ", key.netname, "\n");
+ bprint(player.netname, "^7 picked up the ", key.netname, "\n");
+
+ kh_show_temp();
+
+ stuffcmd(player, strcat("set kh_keys ", ftos(test[key.owner.playerid]), "\n")); // send to current player
+
kh_Key_AssignTo(key, player);
if(kh_Key_AllOwnedByWhichTeam() != -1)
@@ -400,7 +447,7 @@
}
}
-void kh_Key_DropAll(entity player, float suicide)
+void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies
{
entity key;
entity mypusher;
@@ -413,7 +460,7 @@
while((key = player.kh_next))
{
kh_Scores_Event(player, key, "losekey", 0, 0);
- bprint(player.netname, "^7 lost the ", key.netname, "\n");
+ bprint(player.netname, "^7 died and lost the ", key.netname, "\n");
kh_Key_AssignTo(key, world);
makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random());
key.velocity = W_CalculateProjectileVelocity(player.velocity, cvar("g_balance_keyhunt_dropvelocity") * v_forward);
@@ -426,7 +473,7 @@
}
}
-void kh_Key_Touch()
+void kh_Key_Touch() // runs many, many times when a key has been dropped and can be picked up
{
if(intermission_running)
return;
@@ -439,17 +486,26 @@
return;
if(other == self.enemy)
if(time < self.kh_droptime + cvar("g_balance_keyhunt_delay_collect"))
- return; // you just dropped it!
+ return; // you just dropped it!
kh_Key_Collect(self, other);
}
-void kh_Key_Think()
+void kh_Key_Think() // runs all the time
{
entity head;
+ entity player; // needed by FOR_EACH_PLAYER
if(intermission_running)
return;
+ if(time > self.stuff_time)
+ {
+ FOR_EACH_PLAYER(player)
+ stuffcmd(player, strcat("set kh_keys_status ", ftos(test[0]), "\n")); // send key status to all players
+
+ self.stuff_time = time + 1; // repeat in 1 second
+ }
+
#ifdef KH_KEY_ATTACHMENT_DEBUG
if(self.kh_prev == self.owner)
{
@@ -472,7 +528,7 @@
if(time >= self.owner.kh_droptime + cvar("g_balance_keyhunt_delay_drop"))
{
self.owner.kh_droptime = time;
- self.kh_droptime = time; // prevent collecting this one for some time
+ self.kh_droptime = time; // prevent collecting this one for some time
self.enemy = self.owner;
self.pusher = world;
kh_Scores_Event(self.owner, self, "dropkey", 0, 0);
@@ -494,6 +550,12 @@
if(self.owner)
if(kh_Key_AllOwnedByWhichTeam() != -1)
{
+ if(self.siren_time < time)
+ {
+ sound(world, CHAN_AUTO, kh_sound_alarm, 1, ATTN_NORM); // play a simple alarm
+ self.siren_time = time + 2.5; // repeat every 2.5 seconds
+ }
+
entity key;
vector p;
p = self.owner.origin;
@@ -522,7 +584,7 @@
self.nextthink = time + 0.05;
}
-void kh_WinnerTeam(float teem)
+void kh_WinnerTeam(float teem) // runs when a team wins
{
// all key carriers get some points
vector firstorigin, lastorigin, midpoint;
@@ -569,13 +631,13 @@
te_lightning2(world, lastorigin, firstorigin);
}
midpoint = midpoint * (1 / kh_teams);
- te_customflash(midpoint, 1000, 1, TeamColor(teem) * 0.5 + '0.5 0.5 0.5'); // make the color >=0.5 in each component
+ te_customflash(midpoint, 1000, 1, TeamColor(teem) * 0.5 + '0.5 0.5 0.5'); // make the color >=0.5 in each component
sound(world, CHAN_AUTO, kh_sound_capture, 1, ATTN_NONE);
kh_FinishRound();
}
-void kh_LoserTeam(float teem, entity lostkey)
+void kh_LoserTeam(float teem, entity lostkey) // runs when a player pushes a flag carrier off the map
{
entity player, key, attacker;
float players;
@@ -655,7 +717,7 @@
kh_FinishRound();
}
-void kh_FinishRound()
+void kh_FinishRound() // runs when a team captures the keys
{
// prepare next round
kh_interferemsg_time = 0;
@@ -666,7 +728,7 @@
kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round"), "Round starts in ", kh_StartRound);
}
-string kh_CheckEnoughPlayers()
+string kh_CheckEnoughPlayers() // checks enough player are present, runs after every completed round
{
float i, players, teem;
entity player;
@@ -693,7 +755,7 @@
return result;
}
-void kh_WaitForPlayers()
+void kh_WaitForPlayers() // delay start of the round until enough players are present
{
string teams_missing;
teams_missing = kh_CheckEnoughPlayers();
@@ -703,7 +765,7 @@
kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), kh_WaitForPlayers);
}
-void kh_StartRound()
+void kh_StartRound() // runs at the start of each round
{
string teams_missing;
float i, players, teem;
@@ -743,12 +805,12 @@
kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_tracking"), "Scanning frequency range...", kh_EnableTrackingDevice);
}
-void kh_setstatus()
+void kh_setstatus() // runs all the time
{
if(kh_teams)
{
float kh_KEY;
- kh_KEY = (IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST); // the one impossible combination
+ kh_KEY = (IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST); // the one impossible combination
if(self.kh_next)
self.items = self.items | kh_KEY;
else
@@ -756,7 +818,7 @@
}
}
-void kh_EnableTrackingDevice()
+void kh_EnableTrackingDevice() // runs after each round
{
entity player;
@@ -767,7 +829,7 @@
kh_tracking_enabled = TRUE;
}
-float kh_Key_waypointsprite_for_player(entity e)
+float kh_Key_waypointsprite_for_player(entity e) // ??
{
if(!kh_tracking_enabled)
return 0;
@@ -775,10 +837,10 @@
return kh_sprite_dropped;
if(!self.owner.owner)
return kh_sprite_dropped;
- return 0; // draw only when key is not owned
+ return 0; // draw only when key is not owned
}
-float kh_KeyCarrier_waypointsprite_for_player(entity e)
+float kh_KeyCarrier_waypointsprite_for_player(entity e) // runs all the time
{
if(e.classname != "player" || self.team != e.team)
if(!kh_tracking_enabled)
@@ -800,7 +862,7 @@
return kh_GetCarrierSprite(self.team, e.team);
}
-float kh_HandleFrags(entity attacker, entity targ, float f)
+float kh_HandleFrags(entity attacker, entity targ, float f) // adds to the player score
{
if(attacker == targ)
return f;
@@ -825,12 +887,13 @@
return f;
}
-void kh_init()
+void kh_init() // sets up th KH environment
{
precache_sound(kh_sound_capture);
precache_sound(kh_sound_destroy);
precache_sound(kh_sound_drop);
precache_sound(kh_sound_collect);
+ precache_sound(kh_sound_alarm); // the new siren
precache_model("models/sprites/key-dropped.sp2");
precache_model("models/sprites/keycarrier-finish.sp2");
@@ -892,3 +955,35 @@
remove(kh_controller);
kh_controller = world;
}
+
+void kh_show_temp()
+{
+ entity player;
+ float i, j;
+
+ switch(kh_teams)
+ {
+ case 2:
+ j = 3;
+ break;
+ case 3:
+ j = 7;
+ break;
+ case 4:
+ j = 15;
+ break;
+ case 5:
+ j = 31;
+ break;
+ }
+
+ j = 0; // reset/blank j
+ for(i=1; i<17; ++i) // replace 17 with cvar("maxplayers"); !!!!!!!!!
+ j += test[i];
+
+ test[0] = j;
+
+ FOR_EACH_PLAYER(player)
+ stuffcmd(player, strcat("set kh_keys_status ", ftos(test[0]), "\n")); // send key status to all players
+
+}
\ No newline at end of file
Modified: trunk/data/qcsrc/server/keyhunt.qh
===================================================================
--- trunk/data/qcsrc/server/keyhunt.qh 2008-07-03 13:25:33 UTC (rev 3773)
+++ trunk/data/qcsrc/server/keyhunt.qh 2008-07-04 14:56:23 UTC (rev 3774)
@@ -25,6 +25,8 @@
float kh_HandleFrags(entity attacker, entity targ, float f);
float kh_Key_AllOwnedByWhichTeam();
+void kh_show_temp(); // added by victim
+
#define STR_ITEM_KH_KEY "item_kh_key"
typedef void(void) kh_Think_t;
var kh_Think_t kh_Controller_Thinkfunc;
More information about the nexuiz-commits
mailing list