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