1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 
13 #ifdef _WIN32
14 #include <io.h>
15 #include <winsock.h>
16 #endif
17 
18 #include "globalincs/systemvars.h"
19 #include "playerman/player.h"
20 #include "stats/stats.h"
21 #include "hud/hud.h"
22 #include "network/multi.h"
23 
24 
25 #define MISSION_STATS_START_Y 80
26 #define ALLTIME_STATS_START_Y 270
27 #define MULTIPLAYER_LIST_START 20
28 
29 
30 player *Active_player;
31 
show_stats_init()32 void show_stats_init()
33 {
34 	if (Game_mode & GM_MULTIPLAYER) {
35 		set_player_stats(MY_NET_PLAYER_NUM);
36 	} else {
37 		Active_player = Player;
38 	}
39 }
40 
41 // write out the label for each stat
show_stats_label(int stage,int sx,int sy,int dy)42 void show_stats_label(int stage, int sx, int sy, int dy)
43 {
44 	switch ( stage ) {
45 		case MISSION_STATS:
46 			gr_printf_menu(sx,sy,XSTR( "Mission Stats", 114));
47 			sy += 2*dy;
48 			gr_printf_menu(sx,sy,XSTR( "Total kills", 115));
49 			sy += 2*dy;
50 			gr_printf_menu(sx,sy,XSTR( "Primary weapon shots", 116));
51 			sy += dy;
52 			gr_printf_menu(sx,sy,XSTR( "Primary weapon hits", 117));
53 			sy += dy;
54 			gr_printf_menu(sx,sy,XSTR( "Primary friendly hits", 118));
55 			sy += dy;
56 			gr_printf_menu(sx,sy,XSTR( "Primary hit %%", 119));
57 			sy += dy;
58 			gr_printf_menu(sx,sy,XSTR( "Primary friendly hit %%", 120));
59 			sy += 2*dy;
60 
61 			gr_printf_menu(sx,sy,XSTR( "Secondary weapon shots", 121));
62 			sy += dy;
63 			gr_printf_menu(sx,sy,XSTR( "Secondary weapon hits", 122));
64 			sy += dy;
65 			gr_printf_menu(sx,sy,XSTR( "Secondary friendly hits", 123));
66 			sy += dy;
67 			gr_printf_menu(sx,sy,XSTR( "Secondary hit %%", 124));
68 			sy += dy;
69 			gr_printf_menu(sx,sy,XSTR( "Secondary friendly hit %%", 125));
70 			sy += 2*dy;
71 
72 			gr_printf_menu(sx,sy,XSTR( "Assists", 126));
73 			sy += 2*dy;
74 
75 			if(Game_mode & GM_MULTIPLAYER){
76 				gr_printf_menu(sx,sy,XSTR( "Player Deaths", 127));
77 				sy += 2*dy;
78 
79 				gr_printf_menu(sx,sy,XSTR( "Mission score", 1526));
80 			}
81 
82 
83 			break;
84 
85 		case ALL_TIME_STATS:
86 			gr_printf_menu(sx,sy,XSTR( "All Time Stats", 128));
87 			sy += 2*dy;
88 			gr_printf_menu(sx,sy,XSTR( "Total kills", 115));
89 			sy += 2*dy;
90 			gr_printf_menu(sx,sy,XSTR( "Primary weapon shots", 116));
91 			sy += dy;
92 			gr_printf_menu(sx,sy,XSTR( "Primary weapon hits", 117));
93 			sy += dy;
94 			gr_printf_menu(sx,sy,XSTR( "Primary friendly hits", 118));
95 			sy += dy;
96 			gr_printf_menu(sx,sy,XSTR( "Primary hit %%", 119));
97 			sy += dy;
98 			gr_printf_menu(sx,sy,XSTR( "Primary friendly hit %%", 120));
99 			sy += 2*dy;
100 
101 			gr_printf_menu(sx,sy,XSTR( "Secondary weapon shots", 121));
102 			sy += dy;
103 			gr_printf_menu(sx,sy,XSTR( "Secondary weapon hits", 122));
104 			sy += dy;
105 			gr_printf_menu(sx,sy,XSTR( "Secondary friendly hits", 123));
106 			sy += dy;
107 			gr_printf_menu(sx,sy,XSTR( "Secondary hit %%", 124));
108 			sy += dy;
109 			gr_printf_menu(sx,sy,XSTR( "Secondary friendly hit %%", 125));
110 			sy += 2*dy;
111 
112 			gr_printf_menu(sx,sy,XSTR( "Assists", 126));
113 			sy += 2*dy;
114 
115 			if(Game_mode & GM_MULTIPLAYER){
116 				gr_printf_menu(sx,sy,XSTR( "Score", 1527));
117 			}
118 			break;
119 		} // end switch
120 }
121 
stats_underline_text(int sx,int sy,char * text)122 void stats_underline_text(int sx, int sy, char *text)
123 {
124 	int w,h,fh;
125 
126 	gr_get_string_size(&w,&h,text);
127 	fh=gr_get_font_height();
128 	gr_line(sx-1, sy+fh, sx+w+1, sy+fh, GR_RESIZE_MENU);
129 }
130 
show_stats_numbers(int stage,int sx,int sy,int dy,int add_mission)131 void show_stats_numbers(int stage, int sx, int sy, int dy,int add_mission)
132 {
133    char		text[30];
134 	float		pct;
135 
136 	sy += 2*dy;
137 	switch ( stage ) {
138 		case MISSION_STATS:
139          // mission kills stats
140 			sprintf(text,"%d",Active_player->stats.m_kill_count_ok);
141 			gr_printf_menu(sx,sy,text);
142 			sy += 2*dy;
143          // mission primary weapon stats
144 			sprintf(text,"%u",Active_player->stats.mp_shots_fired);
145 			gr_printf_menu(sx,sy,text);
146 			sy += dy;
147 			sprintf(text,"%u",Active_player->stats.mp_shots_hit);
148 			gr_printf_menu(sx,sy,text);
149 			sy += dy;
150 			sprintf(text,"%u",Active_player->stats.mp_bonehead_hits);
151 			gr_printf_menu(sx,sy,text);
152 			sy += dy;
153 			if(Active_player->stats.mp_shots_fired>0)
154 				pct=(float)100.0*((float)Active_player->stats.mp_shots_hit/(float)Active_player->stats.mp_shots_fired);
155 			else pct=(float)0.0;
156 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
157 			gr_printf_menu(sx,sy,text);
158 			sy += dy;
159 			if(Active_player->stats.mp_bonehead_hits>0)
160 				pct=(float)100.0*((float)Active_player->stats.mp_bonehead_hits/(float)Active_player->stats.mp_shots_fired);
161 			else pct=(float)0.0;
162 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
163 			gr_printf_menu(sx,sy,text);
164 			sy += 2*dy;
165 
166 			// mission secondary weapon stats
167 			sprintf(text,"%u",Active_player->stats.ms_shots_fired);
168 			gr_printf_menu(sx,sy,text);
169 			sy += dy;
170 			sprintf(text,"%u",Active_player->stats.ms_shots_hit);
171 			gr_printf_menu(sx,sy,text);
172 			sy += dy;
173 			sprintf(text,"%u",Active_player->stats.ms_bonehead_hits);
174 			gr_printf_menu(sx,sy,text);
175 			sy += dy;
176 			if(Active_player->stats.ms_shots_fired>0)
177 				pct=(float)100.0*((float)Active_player->stats.ms_shots_hit/(float)Active_player->stats.ms_shots_fired);
178 			else pct=(float)0.0;
179 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
180 			gr_printf_menu(sx,sy,text);
181 			sy += dy;
182 			if(Active_player->stats.ms_bonehead_hits>0)
183 				pct=(float)100.0*((float)Active_player->stats.ms_bonehead_hits/(float)Active_player->stats.ms_shots_fired);
184 			else pct=(float)0.0;
185 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
186 			gr_printf_menu(sx,sy,text);
187 			sy += 2*dy;
188 
189 			// mission assists and player rescues (respawns)
190 			sprintf(text,"%d",(int)Active_player->stats.m_assists);
191 			gr_printf_menu(sx,sy,text);
192 			sy += 2*dy;
193 
194 			if(Game_mode & GM_MULTIPLAYER){
195 				sprintf(text,"%d",(int)Active_player->stats.m_player_deaths);
196 				gr_printf_menu(sx,sy,text);
197 				sy += 2*dy;
198 
199 				// mission score
200 				gr_printf_menu(sx, sy, "%d", (int)Active_player->stats.m_score);
201 			}
202 
203 
204 			break;
205 
206 		case ALL_TIME_STATS:
207 			 scoring_struct add;
208 
209 			// if we are passed mission_add (the stats for the current mission), copy it to "add", otherwise,
210 			// leave it blank
211 			if (add_mission) {
212 				add.kill_count_ok = Active_player->stats.m_kill_count_ok;
213 				add.p_shots_fired  = Active_player->stats.mp_shots_fired;
214 				add.p_shots_hit = Active_player->stats.mp_shots_hit;
215 				add.p_bonehead_hits = Active_player->stats.mp_bonehead_hits;
216 
217 				add.s_shots_fired = Active_player->stats.ms_shots_fired;
218 				add.s_shots_hit = Active_player->stats.ms_shots_hit;
219 				add.s_bonehead_hits = Active_player->stats.ms_bonehead_hits;
220 			}
221 
222          // mission kills stats
223 			sprintf(text,"%d",Active_player->stats.kill_count_ok + add.kill_count_ok);
224 			hud_num_make_mono(text, gr_get_current_fontnum());
225 			gr_printf_menu(sx,sy,text);
226 			sy += 2*dy;
227          // alltime primary weapon stats
228 			sprintf(text,"%u",Active_player->stats.p_shots_fired + add.p_shots_fired);
229 			gr_printf_menu(sx,sy,text);
230 			sy += dy;
231 			sprintf(text,"%u",Active_player->stats.p_shots_hit + add.p_shots_hit);
232 			gr_printf_menu(sx,sy,text);
233 			sy += dy;
234 			sprintf(text,"%u",Active_player->stats.p_bonehead_hits + add.p_bonehead_hits);
235 			gr_printf_menu(sx,sy,text);
236 			sy += dy;
237 			if((Active_player->stats.p_shots_fired + add.p_shots_fired)>0)
238 				pct=(float)100.0*((float)(Active_player->stats.p_shots_hit+add.p_shots_hit)/(float)(Active_player->stats.p_shots_fired + add.p_shots_fired));
239 			else pct=(float)0.0;
240 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
241 			gr_printf_menu(sx,sy,text);
242 			sy += dy;
243 			if((Active_player->stats.p_bonehead_hits + add.p_bonehead_hits)>0)
244 				pct=(float)100.0*((float)(Active_player->stats.p_bonehead_hits+add.p_bonehead_hits)/(float)(Active_player->stats.p_shots_fired + add.p_shots_fired));
245 			else pct=(float)0.0;
246 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
247 			gr_printf_menu(sx,sy,text);
248 			sy += 2*dy;
249 
250 			// alltime secondary weapon stats
251 			sprintf(text,"%u",Active_player->stats.s_shots_fired + add.s_shots_fired);
252 			gr_printf_menu(sx,sy,text);
253 			sy += dy;
254 			sprintf(text,"%u",Active_player->stats.s_shots_hit + add.s_shots_hit);
255 			gr_printf_menu(sx,sy,text);
256 			sy += dy;
257 			sprintf(text,"%u",Active_player->stats.s_bonehead_hits + add.s_bonehead_hits);
258 			gr_printf_menu(sx,sy,text);
259 			sy += dy;
260 			if((Active_player->stats.s_shots_fired+add.s_shots_fired)>0)
261 				pct=(float)100.0*((float)(Active_player->stats.s_shots_hit + add.s_shots_hit)/(float)(Active_player->stats.s_shots_fired + add.s_shots_fired));
262 			else pct=(float)0.0;
263 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
264 			gr_printf_menu(sx,sy,text);
265 			sy += dy;
266 			if((Active_player->stats.s_bonehead_hits + add.s_bonehead_hits)>0)
267 				pct=(float)100.0*((float)(Active_player->stats.s_bonehead_hits+add.s_bonehead_hits)/(float)(Active_player->stats.s_shots_fired+add.s_shots_fired));
268 			else pct=(float)0.0;
269 			sprintf(text,"%d",(int)pct); strcat_s(text," %%");
270 			gr_printf_menu(sx,sy,text);
271 			sy += 2*dy;
272 
273 			// alltime assists
274 			sprintf(text,"%d",(int)Active_player->stats.assists + add.assists);
275 			gr_printf_menu(sx,sy,text);
276 			sy += 2*dy;
277 
278 			if (Game_mode & GM_MULTIPLAYER) {
279 				gr_printf_menu(sx, sy, "%d", (int)Active_player->stats.score);
280 			}
281 			break;
282 	} // end switch
283 }
284 
find_netplayer_n(int n)285 int find_netplayer_n(int n)
286 {
287 	int idx;
288 	int target;
289    target = n;
290 	n=0;
291    for(idx=0;idx<MAX_PLAYERS;idx++){
292 		if(MULTI_CONNECTED(Net_players[idx])){
293 			n++;
294 			if(n == target)
295 				return idx;
296 		}
297 	}
298 	return -1;
299 }
300 
301 
show_stats_close()302 void show_stats_close()
303 {
304 }
305 
306 // initialize the statistics portion of the player structure for multiplayer.  Only the host of
307 // a netgame needs to be doing this (and if fact, only he *should* be doing this)
init_multiplayer_stats()308 void init_multiplayer_stats( )
309 {
310 	scoring_struct *ptr;
311 
312 	for (int idx=0; idx < MAX_PLAYERS; idx++) {
313 		ptr = &Players[idx].stats;
314 		scoring_level_init( ptr );
315 	}
316 }
317 
set_player_stats(int pid)318 void set_player_stats(int pid)
319 {
320    Active_player = Net_players[pid].m_player;
321 }
322