1 /*
2 ===========================================================================
3 Copyright (C) 1999 - 2005, Id Software, Inc.
4 Copyright (C) 2000 - 2013, Raven Software, Inc.
5 Copyright (C) 2001 - 2013, Activision, Inc.
6 Copyright (C) 2013 - 2015, OpenJK contributors
7 
8 This file is part of the OpenJK source code.
9 
10 OpenJK is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 ===========================================================================
22 */
23 
24 #include "cg_local.h"
25 #include "cg_media.h"
26 #include "../game/objectives.h"
27 #include "../game/b_local.h"
28 
29 #define	SCOREBOARD_WIDTH	(26*BIGCHAR_WIDTH)
30 
31 
32 /*
33 static void Scoreboard_Draw( void )
34 {
35 	vec4_t	newColor;
36 /*
37 		player = g_entities[0];
38 		if( player->client->ps.persistant[PERS_ACCURACY_SHOTS] ) {
39 			accuracy = player->client->ps.persistant[PERS_ACCURACY_HITS] * 100 / player->client->ps.persistant[PERS_ACCURACY_SHOTS];
40 		}
41 */
42 /*	cg.LCARSTextTime = 0;	//	Turn off LCARS screen
43 
44 	// Background
45 	newColor[0] = colorTable[CT_BLACK][0];
46 	newColor[1] = colorTable[CT_BLACK][1];
47 	newColor[2] = colorTable[CT_BLACK][2];
48 	newColor[3] = 0.5;
49 	cgi_R_SetColor(newColor);
50 	CG_DrawPic( 137, 73, 475, 300, cgs.media.whiteShader);	// Background
51 	CG_DrawPic( 120, 99,  18, 256, cgs.media.whiteShader);	// Background
52 	CG_DrawPic(  40, 94,  66, 266, cgs.media.whiteShader);	// Background
53 
54 	// Right side box
55 	cgi_R_SetColor( colorTable[CT_DKBROWN1]);
56 	CG_DrawPic( 120, 354,  32, 32, cgs.media.status_corner_16_18);
57 	CG_DrawPic(  94, 356,  16, 32, cgs.media.status_corner_8_16_b);
58 	CG_DrawPic(  94, 73,  16, 32, cgs.media.status_corner_8_22);
59 
60 	CG_DrawPic(135,73,  302, 22, cgs.media.whiteShader);	// Top
61 
62 	CG_DrawPic(120, 100,  18, 12, cgs.media.whiteShader);	// Middle Top
63 	CG_DrawPic(120, 353,  18, 4,  cgs.media.whiteShader);	// Middle Bottom
64 
65 	CG_DrawPic(130,357,  482, 18, cgs.media.whiteShader);	// Bottom
66 
67 	// Left side box
68 	cgi_R_SetColor( colorTable[CT_DKBROWN1]);
69 	CG_DrawPic(40,73,  56, 22, cgs.media.whiteShader);	// Top
70 
71 	CG_DrawPic(98,95,  8, 17, cgs.media.whiteShader);		// Middle Top
72 	CG_DrawPic(98,353, 8, 7, cgs.media.whiteShader);		// Middle Bottom
73 
74 	CG_DrawPic(40,357, 58, 18, cgs.media.whiteShader);	// Bottom
75 
76 	CG_DrawProportionalString( 356, 208, "%", UI_RIGHT | UI_SMALLFONT, colorTable[CT_LTPURPLE1] );
77 	CG_DrawProportionalString( 610, 72, ingame_text[IGT_MISSIONANALYSIS],UI_RIGHT| CG_BIGFONT, colorTable[CT_LTORANGE] );
78 
79 	CG_PrintScreenGraphics(statsmenu_graphics,SMG_MAX);
80 
81 }
82 */
83 
84 
85 
86 /*
87 =================
88 CG_MissionFailed
89 =================
90 */
91 int statusTextIndex = -1;
CG_MissionFailed(void)92 void CG_MissionFailed(void)
93 {
94 	char text[1024]={0};
95 	int w;
96 	int y = 230;
97 
98 		cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED", text, sizeof(text) );
99 
100 	w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontMedium, 1.2f);
101 		cgi_R_Font_DrawString(320 - w/2, y, text, colorTable[CT_HUD_RED], cgs.media.qhFontMedium, -1, 1.2f);
102 
103 	switch (statusTextIndex)
104 	{
105 		case -1:	//Our HERO DIED!!!
106 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_KYLE", text, sizeof(text) );
107 			break;
108 		case MISSIONFAILED_JAN:
109 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_JAN", text, sizeof(text) );
110 			break;
111 		case MISSIONFAILED_LUKE:
112 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_LUKE", text, sizeof(text) );
113 			break;
114 		case MISSIONFAILED_LANDO:
115 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_LANDO", text, sizeof(text) );
116 			break;
117 		case MISSIONFAILED_R5D2:
118 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_R5D2", text, sizeof(text) );
119 			break;
120 		case MISSIONFAILED_WARDEN:
121 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_WARDEN", text, sizeof(text) );
122 			break;
123 		case MISSIONFAILED_PRISONERS:
124 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_PRISONERS", text, sizeof(text) );
125 			break;
126 		case MISSIONFAILED_EMPLACEDGUNS:
127 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_EMPLACEDGUNS", text, sizeof(text) );
128 			break;
129 		case MISSIONFAILED_LADYLUCK:
130 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_LADYLUCK", text, sizeof(text) );
131 			break;
132 		case MISSIONFAILED_KYLECAPTURE:
133 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_KYLECAPTURE", text, sizeof(text) );
134 			break;
135 		case MISSIONFAILED_TOOMANYALLIESDIED:
136 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_TOOMANYALLIESDIED", text, sizeof(text) );
137 			break;
138 		default:
139 			cgi_SP_GetStringTextString( "INGAME_MISSIONFAILED_UNKNOWN", text, sizeof(text) );
140 			break;
141 	}
142 
143 	w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontMedium, 1.2f);
144 		cgi_R_Font_DrawString(320 - w/2, y+30, text, colorTable[CT_HUD_RED], cgs.media.qhFontMedium, -1, 1.2f);
145 
146 		cgi_SP_GetStringTextString( "INGAME_RELOADMISSION", text, sizeof(text) );
147 	w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 1.0f);
148 		cgi_R_Font_DrawString(320 - w/2, 450, text, colorTable[CT_CYAN], cgs.media.qhFontSmall, -1, 1.0f);
149 
150 }
151 
152 
153 /*
154 =================
155 CG_MissionCompletion
156 =================
157 */
CG_MissionCompletion(void)158 void CG_MissionCompletion(void)
159 {
160 	char text[1024]={0};
161 	int w,x,y;
162 	const int pad = 18;
163 
164 	cgi_SP_GetStringTextString( "INGAME_MISSIONCOMPLETION", text, sizeof(text) );
165 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontMedium, 1.2f);
166 	cgi_R_Font_DrawString(320 - w/2, 53, text, colorTable[CT_LTGOLD1], cgs.media.qhFontMedium, -1, 1.2f);
167 
168 	x = 75;
169 	y =86;
170 	cgi_SP_GetStringTextString( "INGAME_SECRETAREAS", text, sizeof(text) );
171 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
172 	cgi_R_Font_DrawString(x,    y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
173 	cgi_SP_GetStringTextString( "INGAME_SECRETAREAS_OF", text, sizeof(text) );
174 	cgi_R_Font_DrawString(x+w,  y, va("%d %s %d",
175 										cg_entities[0].gent->client->sess.missionStats.secretsFound,
176 										text,
177 										cg_entities[0].gent->client->sess.missionStats.totalSecrets
178 										),
179 							colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
180 
181 	y +=pad;
182 	cgi_SP_GetStringTextString( "INGAME_ENEMIESKILLED", text, sizeof(text) );
183 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
184 	cgi_R_Font_DrawString(x, y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
185 	cgi_R_Font_DrawString(x+w,y, va("%d",cg_entities[0].gent->client->sess.missionStats.enemiesKilled), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
186 	/*
187 	cgi_SP_GetStringTextString( "INGAME_SECRETAREAS_OF", text, sizeof(text) );
188 	cgi_R_Font_DrawString(x+w,y, va("%d %s %d",
189 										cg_entities[0].gent->client->sess.missionStats.enemiesKilled,
190 										text,
191 										cg_entities[0].gent->client->sess.missionStats.enemiesSpawned
192 										),
193 							colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
194 	*/
195 
196 	y +=pad;
197 	y +=pad;
198 	cgi_SP_GetStringTextString( "INGAME_FAVORITEWEAPON", text, sizeof(text) );
199 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
200 	cgi_R_Font_DrawString(x, y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
201 
202 	int wpn=0,i;
203 	int max_wpn = cg_entities[0].gent->client->sess.missionStats.weaponUsed[0];
204 	for (i = 1; i<WP_NUM_WEAPONS; i++)
205 	{
206 		if (cg_entities[0].gent->client->sess.missionStats.weaponUsed[i] > max_wpn)
207 		{
208 			max_wpn = cg_entities[0].gent->client->sess.missionStats.weaponUsed[i];
209 			wpn = i;
210 		}
211 	}
212 
213 	if ( wpn )
214 	{
215 		gitem_t	*wItem= FindItemForWeapon( (weapon_t)wpn);
216 		cgi_SP_GetStringTextString( va("INGAME_%s",wItem->classname ), text, sizeof( text ));
217 	//	cgi_R_Font_DrawString(x+w, y, va("%d",wpn), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
218 		cgi_R_Font_DrawString(x+w, y, text, colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
219 	}
220 
221 	x = 334+70;
222 	y = 86;
223 	cgi_SP_GetStringTextString( "INGAME_SHOTSFIRED", text, sizeof(text) );
224 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
225 	cgi_R_Font_DrawString(x, y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
226 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.shotsFired), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
227 
228 
229 	y +=pad;
230 	cgi_SP_GetStringTextString( "INGAME_HITS", text, sizeof(text) );
231 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
232 	cgi_R_Font_DrawString(x, y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
233 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.hits), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
234 
235 
236 	y +=pad;
237 	cgi_SP_GetStringTextString( "INGAME_ACCURACY", text, sizeof(text) );
238 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
239 	cgi_R_Font_DrawString(x, y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
240 	const float percent = cg_entities[0].gent->client->sess.missionStats.shotsFired? 100.0f * (float)cg_entities[0].gent->client->sess.missionStats.hits / cg_entities[0].gent->client->sess.missionStats.shotsFired : 0;
241 	cgi_R_Font_DrawString(x+w, y, va("%.2f%%",percent), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
242 
243 	if ( cg_entities[0].gent->client->sess.missionStats.weaponUsed[WP_SABER] <= 0 )
244 	{
245 		return; //don't have saber yet, so don't print any stats
246 	}
247 //first column, FORCE POWERS
248 	y =180;
249 	cgi_SP_GetStringTextString( "INGAME_FORCEUSE", text, sizeof(text) );
250 	cgi_R_Font_DrawString(x, y, text, colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
251 
252 	y +=pad;
253 	cgi_SP_GetStringTextString( "INGAME_HEAL", text, sizeof(text) );
254 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
255 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
256 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.forceUsed[FP_HEAL]), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
257 
258 	y +=pad;
259 	cgi_SP_GetStringTextString( "INGAME_SPEED", text, sizeof(text) );
260 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
261 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
262 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.forceUsed[FP_SPEED]), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
263 
264 	y +=pad;
265 	cgi_SP_GetStringTextString( "INGAME_PULL", text, sizeof(text) );
266 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
267 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
268 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.forceUsed[FP_PULL]), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
269 
270 	y +=pad;
271 	cgi_SP_GetStringTextString( "INGAME_PUSH", text, sizeof(text) );
272 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
273 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
274 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.forceUsed[FP_PUSH]), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
275 
276 	y +=pad;
277 	cgi_SP_GetStringTextString("INGAME_MINDTRICK", text, sizeof(text) );
278 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
279 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
280 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.forceUsed[FP_TELEPATHY]), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
281 
282 	y +=pad;
283 	cgi_SP_GetStringTextString( "INGAME_GRIP", text, sizeof(text) );
284 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
285 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
286 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.forceUsed[FP_GRIP]), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
287 
288 	y +=pad;
289 	cgi_SP_GetStringTextString( "INGAME_LIGHTNING", text, sizeof(text) );
290 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
291 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
292 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.forceUsed[FP_LIGHTNING]), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
293 
294 //second column, LIGHT SABER
295 	y = 180;
296 	x = 140;
297 	cgi_SP_GetStringTextString( "INGAME_LIGHTSABERUSE", text, sizeof(text) );
298 	cgi_R_Font_DrawString(x, y, text, colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
299 
300 	y +=pad;
301 	cgi_SP_GetStringTextString( "INGAME_THROWN", text, sizeof(text) );
302 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
303 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
304 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.saberThrownCnt), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
305 
306 	y +=pad;
307 	cgi_SP_GetStringTextString( "INGAME_BLOCKS", text, sizeof(text) );
308 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
309 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
310 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.saberBlocksCnt), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
311 
312 	y +=pad;
313 	cgi_SP_GetStringTextString( "INGAME_LEGATTACKS", text, sizeof(text) );
314 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
315 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
316 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.legAttacksCnt), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
317 
318 	y +=pad;
319 	cgi_SP_GetStringTextString( "INGAME_ARMATTACKS", text, sizeof(text) );
320 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
321 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
322 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.armAttacksCnt), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
323 
324 	y +=pad;
325 	cgi_SP_GetStringTextString( "INGAME_BODYATTACKS", text, sizeof(text) );
326 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
327 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
328 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.torsoAttacksCnt), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
329 
330 	y +=pad;
331 	cgi_SP_GetStringTextString( "INGAME_OTHERATTACKS", text, sizeof(text) );
332 w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 0.8f);
333 	cgi_R_Font_DrawString(x,   y, text, colorTable[CT_LTGOLD1], cgs.media.qhFontSmall, -1, 0.8f);
334 	cgi_R_Font_DrawString(x+w, y, va("%d",cg_entities[0].gent->client->sess.missionStats.otherAttacksCnt), colorTable[CT_WHITE], cgs.media.qhFontSmall, -1, 0.8f);
335 }
336 
337 
338 /*
339 =================
340 CG_DrawScoreboard
341 
342 Draw the normal in-game scoreboard
343 return value is bool to NOT draw centerstring
344 =================
345 */
CG_DrawScoreboard(void)346 qboolean CG_DrawScoreboard( void )
347 {
348 	// don't draw anything if the menu is up
349 	if ( cg_paused.integer )
350 	{
351 		return qfalse;
352 	}
353 
354 	// Character is either dead, or a script has brought up the screen
355 	if (((cg.predicted_player_state.pm_type == PM_DEAD) && (cg.missionStatusDeadTime < level.time))
356 		|| (cg.missionStatusShow))
357 	{
358 		CG_MissionFailed();
359 		return qtrue;
360 	}
361 
362 	return qfalse;
363 }
364 
ScoreBoardReset(void)365 void ScoreBoardReset(void)
366 {
367 }
368 
369 //================================================================================
370 
371