1 /* KJL 99/2/12 - Statistics of current game */
2 #include "3dc.h"
3 #include "inline.h"
4 #include "module.h"
5 #include "stratdef.h"
6 #include "gamedef.h"
7 #include "game_statistics.h"
8 #include "bh_types.h"
9 #include "bh_marin.h"
10 #include "bh_alien.h"
11 #include "bh_corpse.h"
12 #include "bh_debri.h"
13 #include "bh_weap.h"
14 #include "pldghost.h"
15 #include "opengl.h"
16 
17 #define UseLocalAssert Yes
18 #include "ourasert.h"
19 
20 #include "avp_envinfo.h"
21 #include "avp_userprofile.h"
22 
23 #define FIXED_MINUTE (ONE_FIXED*60)
24 
25 #define TABPOINT1	(ScreenDescriptorBlock.SDB_Width/10)
26 #define TABPOINT1A	(ScreenDescriptorBlock.SDB_Width/4)
27 #define TABPOINT2	(ScreenDescriptorBlock.SDB_Width/2)
28 #define TABPOINT3	((ScreenDescriptorBlock.SDB_Width/6)+(ScreenDescriptorBlock.SDB_Width/2))
29 #define TABPOINT4	(((ScreenDescriptorBlock.SDB_Width/6)*2)+(ScreenDescriptorBlock.SDB_Width/2))
30 
31 extern int DebuggingCommandsActive;
32 #define NotCheating ((CheatMode_Active==CHEATMODE_NONACTIVE)&&!DebuggingCommandsActive)
33 
34 AvP_GameStats CurrentGameStatistics;
35 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
36 extern int NormalFrameTime;
37 
38 extern int MarineEpisodeToPlay;
39 extern int PredatorEpisodeToPlay;
40 extern int AlienEpisodeToPlay;
41 extern char LevelName[];
42 
43 extern AvP_Level_Target_Desc LevelStatsTargets[I_MaxDifficulties][AVP_ENVIRONMENT_END_OF_LIST];
44 
45 /* Default structure: */
46 AvP_GameStats_Stored DefaultLevelGameStats = {
47 	{0,0,0,0,0,0,0,0,0,0},
48 	{0,0,0,0,0,0,0,0,0,0},
49 	{0,0,0,0,0,0,0,0,0,0}, /* TrophiesOrLiveHeadBites */
50 	{0,0,0,0,0,0,0,0,0,0},
51 	10000,
52 	0,
53 	100,
54 	0,
55 	0,
56 	12,
57 	0,
58 	0,
59 	12,
60 	999,
61 	999,
62 	0,
63 	999,
64 	0,
65 	/* Padding! */
66 	{
67 		0,0,0,0,0,0,0,0,0,0,
68 		0,0,0,0,0,0,0,0,0,0,
69 		0,0,0,0,0,0,0,0,0,0,
70 		0,0,0,0,0,0,0,0,0,0
71 	}
72 
73 };
74 
75 #define COLOUR_WHITE	(0xffffffff)
76 #define COLOUR_RED		(0xffff0000)
77 #define COLOUR_GREEN	(0xff00ff00)
78 
79 #define NEWLINE_SPACING	((ScreenDescriptorBlock.SDB_Height<400)? 12:15)
80 
CurrentGameStats_Initialise(void)81 void CurrentGameStats_Initialise(void)
82 {
83 	int i;
84 	for (i=0; i<STATS_VICTIM_MAXIMUM; i++)
85 	{
86 		CurrentGameStatistics.Killed[i]=0;
87 		CurrentGameStatistics.Decapitated[i]=0;
88 		CurrentGameStatistics.Trophies[i]=0;
89 		CurrentGameStatistics.LiveHeadBites[i]=0;
90 		CurrentGameStatistics.DeadHeadBites[i]=0;
91 	}
92 	for (i=0; i<MAX_NO_OF_WEAPON_SLOTS; i++) {
93 		CurrentGameStatistics.WeaponTimes[i]=0;
94 		CurrentGameStatistics.ShotsFired[i]=0;
95 		CurrentGameStatistics.ShotsHit[i]=0;
96 	}
97 	for (i=0; i<NUMBER_OF_VISION_MODES; i++) {
98 		CurrentGameStatistics.VisionModeTimes[i]=0;
99 	}
100 	CurrentGameStatistics.Spotted=0;
101 
102 	CurrentGameStatistics.Cloak_ElapsedSeconds=0;
103 	CurrentGameStatistics.Cloak_ElapsedMinutes=0;
104 	CurrentGameStatistics.Cloak_ElapsedHours=0;
105 	CurrentGameStatistics.FieldChargeUsed=0;
106 
107 	CurrentGameStatistics.HealthDamage=0;
108 	CurrentGameStatistics.ArmourDamage=0;
109 
110 	CurrentGameStatistics.IntegralSpeed=0;
111 
112 	AvP.ElapsedSeconds = 0;
113 	AvP.ElapsedMinutes = 0;
114 	AvP.ElapsedHours = 0;
115 
116 }
117 
CurrentGameStats_SpeedSample(unsigned int speed,unsigned int time)118 extern void CurrentGameStats_SpeedSample(unsigned int speed,unsigned int time) {
119 
120 	if (PlayerStatusPtr->IsAlive==0) {
121 		return;
122 	}
123 
124 	CurrentGameStatistics.IntegralSpeed+=(MUL_FIXED(speed,time));
125 
126 }
127 
CurrentGameStats_DamageTaken(unsigned int health,unsigned int armour)128 extern void CurrentGameStats_DamageTaken(unsigned int health,unsigned int armour) {
129 
130 	if (PlayerStatusPtr->IsAlive==0) {
131 		return;
132 	}
133 
134 	CurrentGameStatistics.HealthDamage+=health;
135 	CurrentGameStatistics.ArmourDamage+=armour;
136 
137 }
138 
CurrentGameStats_ChargeUsed(unsigned int charge)139 extern void CurrentGameStats_ChargeUsed(unsigned int charge) {
140 
141 	if (PlayerStatusPtr->IsAlive==0) {
142 		return;
143 	}
144 
145 	CurrentGameStatistics.FieldChargeUsed+=charge;
146 
147 }
148 
CurrentGameStats_VisionMode(enum VISION_MODE_ID mode)149 extern void CurrentGameStats_VisionMode(enum VISION_MODE_ID mode) {
150 
151 	if (PlayerStatusPtr->IsAlive==0) {
152 		return;
153 	}
154 
155 	CurrentGameStatistics.VisionModeTimes[mode]+=NormalFrameTime;
156 
157 }
158 
CurrentGameStats_CloakOn(void)159 extern void CurrentGameStats_CloakOn(void) {
160 
161 	if (PlayerStatusPtr->IsAlive==0) {
162 		return;
163 	}
164 
165 	CurrentGameStatistics.Cloak_ElapsedSeconds += NormalFrameTime;
166 
167 	if(CurrentGameStatistics.Cloak_ElapsedSeconds  >= FIXED_MINUTE)
168 	{
169 		CurrentGameStatistics.Cloak_ElapsedSeconds -= FIXED_MINUTE;
170 		CurrentGameStatistics.Cloak_ElapsedMinutes ++;
171 	}
172 
173 	if(CurrentGameStatistics.Cloak_ElapsedMinutes >= 60)
174 	{
175 		CurrentGameStatistics.Cloak_ElapsedMinutes -= 60;
176 		CurrentGameStatistics.Cloak_ElapsedHours ++;
177 	}
178 
179 }
180 
CurrentGameStats_WeaponFired(enum WEAPON_SLOT slot,unsigned int rounds)181 extern void CurrentGameStats_WeaponFired(enum WEAPON_SLOT slot,unsigned int rounds) {
182 
183 	if (PlayerStatusPtr->IsAlive==0) {
184 		return;
185 	}
186 
187 	if ((slot>=0)&&(slot<=MAX_NO_OF_WEAPON_SLOTS)) {
188 		CurrentGameStatistics.ShotsFired[slot]+=rounds;
189 	}
190 
191 }
192 
CurrentGameStats_WeaponHit(enum WEAPON_SLOT slot,unsigned int rounds)193 extern void CurrentGameStats_WeaponHit(enum WEAPON_SLOT slot,unsigned int rounds) {
194 
195 	if (PlayerStatusPtr->IsAlive==0) {
196 		return;
197 	}
198 
199 	if ((slot>=0)&&(slot<=MAX_NO_OF_WEAPON_SLOTS)) {
200 		CurrentGameStatistics.ShotsHit[slot]+=rounds;
201 	}
202 
203 }
204 
CurrentGameStats_UsingWeapon(enum WEAPON_SLOT slot)205 extern void CurrentGameStats_UsingWeapon(enum WEAPON_SLOT slot) {
206 
207 	if (PlayerStatusPtr->IsAlive==0) {
208 		return;
209 	}
210 
211 	if ((slot>=0)&&(slot<=MAX_NO_OF_WEAPON_SLOTS)) {
212 		CurrentGameStatistics.WeaponTimes[slot]+=NormalFrameTime;
213 	}
214 
215 }
216 
CurrentGameStats_Spotted(void)217 extern void CurrentGameStats_Spotted(void) {
218 
219 	if (PlayerStatusPtr->IsAlive==0) {
220 		return;
221 	}
222 
223 	CurrentGameStatistics.Spotted++;
224 
225 }
226 
PrintSpottedNumber(void)227 extern void PrintSpottedNumber(void) {
228 
229 	/* It must be in this file... */
230 
231 	textprint("Spotted: %d\n",CurrentGameStatistics.Spotted);
232 	textprint("Size %d\n",sizeof(AvP_GameStats_Stored));
233 
234 }
235 
CurrentGameStats_HeadBitten(STRATEGYBLOCK * sbPtr)236 extern void CurrentGameStats_HeadBitten(STRATEGYBLOCK *sbPtr) {
237 
238 	if (PlayerStatusPtr->IsAlive==0) {
239 		return;
240 	}
241 
242 	switch (sbPtr->I_SBtype) {
243 		case I_BehaviourAlien:
244 		{
245 			ALIEN_STATUS_BLOCK *alienStatus = (ALIEN_STATUS_BLOCK *)sbPtr->SBdataptr;
246 
247 			switch (alienStatus->Type)
248 			{
249 				case 0:
250 				default:
251 					CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_XENOMORPH]++;
252 					break;
253 				case 1:
254 					CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_PREDALIEN]++;
255 					break;
256 				case 2:
257 					CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_PRAETORIAN]++;
258 					break;
259 			}
260 
261 			break;
262 		}
263 		case I_BehaviourMarine:
264 		{
265 			MARINE_STATUS_BLOCK *marineStatusPointer;
266 
267 			LOCALASSERT(sbPtr);
268 			LOCALASSERT(sbPtr->containingModule);
269 			marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
270 
271 			if (marineStatusPointer->My_Weapon->Android)
272 			{
273 				CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_ANDROID]++;
274 			}
275 			else if (marineStatusPointer->My_Weapon->ARealMarine)
276 			{
277 				CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_MARINE]++;
278 			}
279 			else
280 			{
281 				CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_CIVILIAN]++;
282 			}
283 			break;
284 		}
285 		case I_BehaviourQueenAlien:
286 		{
287 			CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_QUEEN]++;
288 			break;
289 		}
290 		case I_BehaviourFaceHugger:
291 		{
292 			CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_FACEHUGGER]++;
293 			break;
294 		}
295 		case I_BehaviourXenoborg:
296 		{
297 			CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_XENOBORG]++;
298 			break;
299 		}
300 		case I_BehaviourPredator:
301 		{
302 			CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_PREDATOR]++;
303 			break;
304 		}
305 		case I_BehaviourNetCorpse:
306 		{
307 			NETCORPSEDATABLOCK *corpseDataPtr;
308 
309 		    LOCALASSERT(sbPtr);
310 			corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
311 			LOCALASSERT(corpseDataPtr);
312 
313 			switch (corpseDataPtr->Type)
314 			{
315 				case I_BehaviourAlien:
316 				{
317 					switch (corpseDataPtr->subtype)
318 					{
319 						case 0:
320 						default:
321 							CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_XENOMORPH]++;
322 							break;
323 						case 1:
324 							CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_PREDALIEN]++;
325 							break;
326 						case 2:
327 							CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_PRAETORIAN]++;
328 							break;
329 					}
330 					break;
331 				}
332 				case I_BehaviourMarine:
333 				{
334 
335 					if (corpseDataPtr->Android)
336 					{
337 						CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_ANDROID]++;
338 					}
339 					else if (corpseDataPtr->ARealMarine)
340 					{
341 						CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_MARINE]++;
342 					}
343 					else
344 					{
345 						CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_CIVILIAN]++;
346 					}
347 					break;
348 				}
349 				case I_BehaviourQueenAlien:
350 				{
351 					CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_QUEEN]++;
352 					break;
353 				}
354 				case I_BehaviourFaceHugger:
355 				{
356 					CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_FACEHUGGER]++;
357 					break;
358 				}
359 				case I_BehaviourXenoborg:
360 				{
361 					CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_XENOBORG]++;
362 					break;
363 				}
364 
365 
366 				case I_BehaviourPredator:
367 				{
368 					CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_PREDATOR]++;
369 					break;
370 				}
371 				default:
372 				{
373 					break;
374 				}
375 			}
376 			break;
377 		}
378 		case I_BehaviourNetGhost:
379 		{
380 			NETGHOSTDATABLOCK *ghostData;
381 
382 			LOCALASSERT(sbPtr);
383 			ghostData = (NETGHOSTDATABLOCK *)sbPtr->SBdataptr;
384 			LOCALASSERT(ghostData);
385 
386 			switch (ghostData->type) {
387 				case I_BehaviourMarinePlayer:
388 					CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_MARINE]++;
389 					break;
390 				case I_BehaviourAlienPlayer:
391 					CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_XENOMORPH]++;
392 					break;
393 				case I_BehaviourPredatorPlayer:
394 					CurrentGameStatistics.LiveHeadBites[STATS_VICTIM_PREDATOR]++;
395 					break;
396 				case I_BehaviourNetCorpse:
397 				{
398 					switch (ghostData->subtype) {
399 						case I_BehaviourAlien:
400 						{
401 							switch (ghostData->IOType) {
402 								/* Hey ho, it was free... */
403 								case 0:
404 								default:
405 									CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_XENOMORPH]++;
406 									break;
407 								case 1:
408 									CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_PREDALIEN]++;
409 									break;
410 								case 2:
411 									CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_PRAETORIAN]++;
412 									break;
413 							}
414 							break;
415 						}
416 						case I_BehaviourMarinePlayer:
417 						{
418 							CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_MARINE]++;
419 							break;
420 						}
421 						case I_BehaviourAlienPlayer:
422 						{
423 							CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_XENOMORPH]++;
424 							break;
425 						}
426 						case I_BehaviourPredatorPlayer:
427 						{
428 							CurrentGameStatistics.DeadHeadBites[STATS_VICTIM_PREDATOR]++;
429 							break;
430 						}
431 						default:
432 						{
433 							break;
434 						}
435 					}
436 					break;
437 				}
438 				default:
439 				{
440 					break;
441 				}
442 			}
443 			break;
444 		}
445 		default:
446 		{
447 			break;
448 		}
449 	}
450 
451 }
452 
CurrentGameStats_TrophyCollected(STRATEGYBLOCK * sbPtr)453 extern void CurrentGameStats_TrophyCollected(STRATEGYBLOCK *sbPtr) {
454 
455 	if (PlayerStatusPtr->IsAlive==0) {
456 		return;
457 	}
458 
459 	/* It's always going to be a corpse or a ghost, isn't it? */
460 
461 	switch (sbPtr->I_SBtype) {
462 		case I_BehaviourNetCorpse:
463 		{
464 			NETCORPSEDATABLOCK *corpseDataPtr;
465 
466 		    LOCALASSERT(sbPtr);
467 			corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
468 			LOCALASSERT(corpseDataPtr);
469 
470 			switch (corpseDataPtr->Type)
471 			{
472 				case I_BehaviourAlien:
473 				{
474 					switch (corpseDataPtr->subtype)
475 					{
476 						case 0:
477 						default:
478 							CurrentGameStatistics.Trophies[STATS_VICTIM_XENOMORPH]++;
479 							break;
480 						case 1:
481 							CurrentGameStatistics.Trophies[STATS_VICTIM_PREDALIEN]++;
482 							break;
483 						case 2:
484 							CurrentGameStatistics.Trophies[STATS_VICTIM_PRAETORIAN]++;
485 							break;
486 					}
487 					break;
488 				}
489 				case I_BehaviourMarine:
490 				{
491 
492 					if (corpseDataPtr->Android)
493 					{
494 						CurrentGameStatistics.Trophies[STATS_VICTIM_ANDROID]++;
495 					}
496 					else if (corpseDataPtr->ARealMarine)
497 					{
498 						CurrentGameStatistics.Trophies[STATS_VICTIM_MARINE]++;
499 					}
500 					else
501 					{
502 						CurrentGameStatistics.Trophies[STATS_VICTIM_CIVILIAN]++;
503 					}
504 					break;
505 				}
506 				case I_BehaviourQueenAlien:
507 				{
508 					CurrentGameStatistics.Trophies[STATS_VICTIM_QUEEN]++;
509 					break;
510 				}
511 				case I_BehaviourFaceHugger:
512 				{
513 					CurrentGameStatistics.Trophies[STATS_VICTIM_FACEHUGGER]++;
514 					break;
515 				}
516 				case I_BehaviourXenoborg:
517 				{
518 					CurrentGameStatistics.Trophies[STATS_VICTIM_XENOBORG]++;
519 					break;
520 				}
521 
522 
523 				case I_BehaviourPredator:
524 				{
525 					CurrentGameStatistics.Trophies[STATS_VICTIM_PREDATOR]++;
526 					break;
527 				}
528 				default:
529 				{
530 					break;
531 				}
532 			}
533 			break;
534 		}
535 		case I_BehaviourNetGhost:
536 		{
537 			NETGHOSTDATABLOCK *ghostData;
538 
539 			LOCALASSERT(sbPtr);
540 			ghostData = (NETGHOSTDATABLOCK *)sbPtr->SBdataptr;
541 			LOCALASSERT(ghostData);
542 
543 			switch (ghostData->type) {
544 				case I_BehaviourNetCorpse:
545 				{
546 					switch (ghostData->subtype) {
547 						case I_BehaviourAlien:
548 						{
549 							switch (ghostData->IOType) {
550 								/* Hey ho, it was free... */
551 								case 0:
552 								default:
553 									CurrentGameStatistics.Trophies[STATS_VICTIM_XENOMORPH]++;
554 									break;
555 								case 1:
556 									CurrentGameStatistics.Trophies[STATS_VICTIM_PREDALIEN]++;
557 									break;
558 								case 2:
559 									CurrentGameStatistics.Trophies[STATS_VICTIM_PRAETORIAN]++;
560 									break;
561 							}
562 							break;
563 						}
564 						case I_BehaviourMarinePlayer:
565 						{
566 							CurrentGameStatistics.Trophies[STATS_VICTIM_MARINE]++;
567 							break;
568 						}
569 						case I_BehaviourAlienPlayer:
570 						{
571 							CurrentGameStatistics.Trophies[STATS_VICTIM_XENOMORPH]++;
572 							break;
573 						}
574 						case I_BehaviourPredatorPlayer:
575 						{
576 							CurrentGameStatistics.Trophies[STATS_VICTIM_PREDATOR]++;
577 							break;
578 						}
579 						default:
580 						{
581 							break;
582 						}
583 					}
584 					break;
585 				}
586 				default:
587 				{
588 					break;
589 				}
590 			}
591 			break;
592 		}
593 		case I_BehaviourHierarchicalFragment:
594 		{
595 			HDEBRIS_BEHAV_BLOCK *debrisDataPtr;
596 
597 		    LOCALASSERT(sbPtr);
598 			debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->SBdataptr;
599 			LOCALASSERT(debrisDataPtr);
600 
601 			switch (debrisDataPtr->Type) {
602 				case I_BehaviourAlien:
603 				{
604 					switch (debrisDataPtr->SubType)
605 					{
606 						case 0:
607 						default:
608 							CurrentGameStatistics.Trophies[STATS_VICTIM_XENOMORPH]++;
609 							break;
610 						case 1:
611 							CurrentGameStatistics.Trophies[STATS_VICTIM_PREDALIEN]++;
612 							break;
613 						case 2:
614 							CurrentGameStatistics.Trophies[STATS_VICTIM_PRAETORIAN]++;
615 							break;
616 					}
617 					break;
618 				}
619 				case I_BehaviourMarine:
620 				{
621 
622 					if (debrisDataPtr->Android)
623 					{
624 						CurrentGameStatistics.Trophies[STATS_VICTIM_ANDROID]++;
625 					}
626 					else if (debrisDataPtr->SubType) /* Means ARealMarine for fragments of marines */
627 					{
628 						CurrentGameStatistics.Trophies[STATS_VICTIM_MARINE]++;
629 					}
630 					else
631 					{
632 						CurrentGameStatistics.Trophies[STATS_VICTIM_CIVILIAN]++;
633 					}
634 					break;
635 				}
636 				case I_BehaviourQueenAlien:
637 				{
638 					CurrentGameStatistics.Trophies[STATS_VICTIM_QUEEN]++;
639 					break;
640 				}
641 				case I_BehaviourFaceHugger:
642 				{
643 					CurrentGameStatistics.Trophies[STATS_VICTIM_FACEHUGGER]++;
644 					break;
645 				}
646 				case I_BehaviourXenoborg:
647 				{
648 					CurrentGameStatistics.Trophies[STATS_VICTIM_XENOBORG]++;
649 					break;
650 				}
651 
652 
653 				case I_BehaviourPredator:
654 				{
655 					CurrentGameStatistics.Trophies[STATS_VICTIM_PREDATOR]++;
656 					break;
657 				}
658 				default:
659 				{
660 					break;
661 				}
662 			}
663 			break;
664 		}
665 		case I_BehaviourSpeargunBolt:
666 		{
667 			SPEAR_BEHAV_BLOCK *spearDataPtr;
668 
669 		    LOCALASSERT(sbPtr);
670 			spearDataPtr = (SPEAR_BEHAV_BLOCK *)sbPtr->SBdataptr;
671 			LOCALASSERT(spearDataPtr);
672 
673 			switch (spearDataPtr->Type) {
674 				case I_BehaviourAlien:
675 				{
676 					switch (spearDataPtr->SubType)
677 					{
678 						case 0:
679 						default:
680 							CurrentGameStatistics.Trophies[STATS_VICTIM_XENOMORPH]++;
681 							break;
682 						case 1:
683 							CurrentGameStatistics.Trophies[STATS_VICTIM_PREDALIEN]++;
684 							break;
685 						case 2:
686 							CurrentGameStatistics.Trophies[STATS_VICTIM_PRAETORIAN]++;
687 							break;
688 					}
689 					break;
690 				}
691 				case I_BehaviourMarine:
692 				{
693 
694 					if (spearDataPtr->Android)
695 					{
696 						CurrentGameStatistics.Trophies[STATS_VICTIM_ANDROID]++;
697 					}
698 					else if (spearDataPtr->SubType) /* Means ARealMarine for fragments of marines */
699 					{
700 						CurrentGameStatistics.Trophies[STATS_VICTIM_MARINE]++;
701 					}
702 					else
703 					{
704 						CurrentGameStatistics.Trophies[STATS_VICTIM_CIVILIAN]++;
705 					}
706 					break;
707 				}
708 				case I_BehaviourQueenAlien:
709 				{
710 					CurrentGameStatistics.Trophies[STATS_VICTIM_QUEEN]++;
711 					break;
712 				}
713 				case I_BehaviourFaceHugger:
714 				{
715 					CurrentGameStatistics.Trophies[STATS_VICTIM_FACEHUGGER]++;
716 					break;
717 				}
718 				case I_BehaviourXenoborg:
719 				{
720 					CurrentGameStatistics.Trophies[STATS_VICTIM_XENOBORG]++;
721 					break;
722 				}
723 
724 
725 				case I_BehaviourPredator:
726 				{
727 					CurrentGameStatistics.Trophies[STATS_VICTIM_PREDATOR]++;
728 					break;
729 				}
730 				default:
731 				{
732 					break;
733 				}
734 			}
735 			break;
736 		}
737 		default:
738 		{
739 			break;
740 		}
741 	}
742 }
743 
CurrentGameStats_CreatureKilled(STRATEGYBLOCK * sbPtr,SECTION_DATA * sectionDataPtr)744 extern void CurrentGameStats_CreatureKilled(STRATEGYBLOCK *sbPtr,SECTION_DATA *sectionDataPtr)
745 {
746 
747 	if (PlayerStatusPtr->IsAlive==0) {
748 		return;
749 	}
750 
751 	switch (sbPtr->I_SBtype)
752 	{
753 		case I_BehaviourAlien:
754 		{
755 			ALIEN_STATUS_BLOCK *alienStatus = (ALIEN_STATUS_BLOCK *)sbPtr->SBdataptr;
756 
757 			switch (alienStatus->Type)
758 			{
759 				case 0:
760 				default:
761 					CurrentGameStatistics.Killed[STATS_VICTIM_XENOMORPH]++;
762 					break;
763 				case 1:
764 					CurrentGameStatistics.Killed[STATS_VICTIM_PREDALIEN]++;
765 					break;
766 				case 2:
767 					CurrentGameStatistics.Killed[STATS_VICTIM_PRAETORIAN]++;
768 					break;
769 			}
770 
771 			if (sectionDataPtr)
772 			{
773 				if (sectionDataPtr->sempai)
774 				{
775 					if (sectionDataPtr->sempai->Section_Name)
776 					{
777 						if (!_stricmp(sectionDataPtr->sempai->Section_Name,"head"))
778 						{
779 							CurrentGameStatistics.Decapitated[STATS_VICTIM_XENOMORPH]++;
780 						}
781 					}
782 				}
783 			}
784 
785 			break;
786 		}
787 		case I_BehaviourMarine:
788 		{
789 			MARINE_STATUS_BLOCK *marineStatusPointer;
790 
791 			LOCALASSERT(sbPtr);
792 			LOCALASSERT(sbPtr->containingModule);
793 			marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
794 
795 			if (marineStatusPointer->My_Weapon->Android)
796 			{
797 				CurrentGameStatistics.Killed[STATS_VICTIM_ANDROID]++;
798 			}
799 			else if (marineStatusPointer->My_Weapon->ARealMarine)
800 			{
801 				CurrentGameStatistics.Killed[STATS_VICTIM_MARINE]++;
802 			}
803 			else
804 			{
805 				CurrentGameStatistics.Killed[STATS_VICTIM_CIVILIAN]++;
806 			}
807 			break;
808 		}
809 		case I_BehaviourQueenAlien:
810 		{
811 			CurrentGameStatistics.Killed[STATS_VICTIM_QUEEN]++;
812 			break;
813 		}
814 		case I_BehaviourFaceHugger:
815 		{
816 			CurrentGameStatistics.Killed[STATS_VICTIM_FACEHUGGER]++;
817 			break;
818 		}
819 		case I_BehaviourXenoborg:
820 		{
821 			CurrentGameStatistics.Killed[STATS_VICTIM_XENOBORG]++;
822 			break;
823 		}
824 
825 
826 		case I_BehaviourPredator:
827 		{
828 			CurrentGameStatistics.Killed[STATS_VICTIM_PREDATOR]++;
829 			break;
830 		}
831 
832 		default: ;
833 	}
834 }
835 
836 
DoFailedLevelStatisticsScreen(void)837 void DoFailedLevelStatisticsScreen(void)
838 {
839 	extern int deathFadeLevel;
840 	D3D_FadeDownScreen(deathFadeLevel,0);
841 	DoStatisticsScreen(0);
842 
843 	if (!deathFadeLevel)
844 	{
845 		RenderStringCentred(GetTextString(TEXTSTRING_MULTIPLAYER_PRESSKEYTORESTARTGAME),ScreenDescriptorBlock.SDB_Width/2,ScreenDescriptorBlock.SDB_Height-20,0xffffffff);
846 	}
847 
848 }
849 
850 enum TEXTSTRING_ID TemporaryNameStore[] =
851 {
852 	TEXTSTRING_GAMESTATS_FACEHUGGER_PL,
853 	TEXTSTRING_GAMESTATS_XENOMORPH_PL,
854 	TEXTSTRING_GAMESTATS_PRAETORIAN_PL,
855 	TEXTSTRING_GAMESTATS_QUEEN_PL,
856 	TEXTSTRING_GAMESTATS_XENOBORG_PL,
857 	TEXTSTRING_GAMESTATS_PREDALIEN_PL,
858 	TEXTSTRING_GAMESTATS_PREDATOR_PL,
859 	TEXTSTRING_GAMESTATS_MARINE_PL,
860 	TEXTSTRING_GAMESTATS_CIVILIAN_PL,
861 	TEXTSTRING_GAMESTATS_ANDROID_PL,
862 };
863 
864 enum TEXTSTRING_ID TemporaryNameStore2[] =
865 {
866 	TEXTSTRING_GAMESTATS_FACEHUGGER,
867 	TEXTSTRING_GAMESTATS_XENOMORPH,
868 	TEXTSTRING_GAMESTATS_PRAETORIAN,
869 	TEXTSTRING_GAMESTATS_QUEEN,
870 	TEXTSTRING_GAMESTATS_XENOBORG,
871 	TEXTSTRING_GAMESTATS_PREDALIEN,
872 	TEXTSTRING_GAMESTATS_PREDATOR,
873 	TEXTSTRING_GAMESTATS_MARINE,
874 	TEXTSTRING_GAMESTATS_CIVILIAN,
875 	TEXTSTRING_GAMESTATS_ANDROID,
876 };
877 
878 enum TEXTSTRING_ID VisionModeNames[] =
879 {
880 	TEXTSTRING_GAMESTATS_VM_NORMAL,
881 	TEXTSTRING_GAMESTATS_VM_NAVSENSE,
882 	TEXTSTRING_GAMESTATS_VM_INTENSIFIER,
883 	TEXTSTRING_GAMESTATS_VM_THERMAL,
884 	TEXTSTRING_GAMESTATS_VM_ELECTRICAL,
885 	TEXTSTRING_GAMESTATS_VM_PREDTECH,
886 };
887 
888 
DoStatisticsScreen(int completed_level)889 extern void DoStatisticsScreen(int completed_level)
890 {
891 	// content to be finalised. Language localisation issues: time formats etc.
892 	int y;
893 	char buffer[100];
894 	int level_num;
895 	int colour_to_draw,best;
896 
897 	int targets,targetspassed;
898 
899 	NPC_DATA *NpcData = NULL;
900 
901 	switch (AvP.PlayerType)
902 	{
903 		case I_Marine:
904 			switch (AvP.Difficulty) {
905 				case I_Easy:
906 					NpcData=GetThisNpcData(I_PC_Marine_Easy);
907 					break;
908 				default:
909 				case I_Medium:
910 					NpcData=GetThisNpcData(I_PC_Marine_Medium);
911 					break;
912 				case I_Hard:
913 					NpcData=GetThisNpcData(I_PC_Marine_Hard);
914 					break;
915 				case I_Impossible:
916 					NpcData=GetThisNpcData(I_PC_Marine_Impossible);
917 					break;
918 			}
919 			break;
920 		case I_Alien:
921 			switch (AvP.Difficulty) {
922 				case I_Easy:
923 					NpcData=GetThisNpcData(I_PC_Alien_Easy);
924 					break;
925 				default:
926 				case I_Medium:
927 					NpcData=GetThisNpcData(I_PC_Alien_Medium);
928 					break;
929 				case I_Hard:
930 					NpcData=GetThisNpcData(I_PC_Alien_Hard);
931 					break;
932 				case I_Impossible:
933 					NpcData=GetThisNpcData(I_PC_Alien_Impossible);
934 					break;
935 			}
936 			break;
937 		case I_Predator:
938 			switch (AvP.Difficulty) {
939 				case I_Easy:
940 					NpcData=GetThisNpcData(I_PC_Predator_Easy);
941 					break;
942 				default:
943 				case I_Medium:
944 					NpcData=GetThisNpcData(I_PC_Predator_Medium);
945 					break;
946 				case I_Hard:
947 					NpcData=GetThisNpcData(I_PC_Predator_Hard);
948 					break;
949 				case I_Impossible:
950 					NpcData=GetThisNpcData(I_PC_Predator_Impossible);
951 					break;
952 			}
953 			break;
954 		default:
955 			LOCALASSERT(0);
956 	}
957 
958 	if (PlayerStatusPtr->soundHandle5!=SOUND_NOACTIVEINDEX) {
959 		Sound_Stop(PlayerStatusPtr->soundHandle5);
960 	}
961 
962 	level_num=NumberForCurrentLevel();
963 	targets=0;
964 	targetspassed=0;
965 
966 	/* Print their name. */
967 	sprintf(buffer,"%s",UserProfilePtr->Name);
968 	RenderString(buffer,TABPOINT1,20,COLOUR_WHITE);
969 
970 	if (completed_level) {
971 		RenderStringCentred(GetTextString(TEXTSTRING_GAMESTATS_LEVELCOMPLETED),
972 			ScreenDescriptorBlock.SDB_Width/2,20,COLOUR_GREEN);
973 	} else {
974 		RenderStringCentred(GetTextString(TEXTSTRING_GAMESTATS_LEVELNOTCOMPLETED),
975 			ScreenDescriptorBlock.SDB_Width/2,20,COLOUR_RED);
976 	}
977 
978 	#if 0
979 	RenderStringCentred(GetTextString(TEXTSTRING_GAMESTATS_NAME),TABPOINT1A,40,COLOUR_WHITE);
980 	#endif
981 	RenderStringCentred(GetTextString(TEXTSTRING_GAMESTATS_YOUR),TABPOINT2,40,COLOUR_WHITE);
982 	RenderStringCentred(GetTextString(TEXTSTRING_GAMESTATS_BEST),TABPOINT3,40,COLOUR_WHITE);
983 	RenderStringCentred(GetTextString(TEXTSTRING_GAMESTATS_TARGET),TABPOINT4,40,COLOUR_WHITE);
984 
985 	y = 55;
986 
987 	colour_to_draw=COLOUR_WHITE;
988 
989 	if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
990 		/* Is it a new best? */
991 		best=0;
992 		if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedHours>AvP.ElapsedHours) {
993 			best=1;
994 		} else if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedHours==AvP.ElapsedHours) {
995 			if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedMinutes>AvP.ElapsedMinutes) {
996 				best=1;
997 			} else if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedMinutes==AvP.ElapsedMinutes) {
998 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedSeconds>AvP.ElapsedSeconds) {
999 					best=1;
1000 				} else if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedSeconds==AvP.ElapsedSeconds) {
1001 					best=1;
1002 				}
1003 			}
1004 		}
1005 		if (best) {
1006 			colour_to_draw=COLOUR_GREEN;
1007 			UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedHours=AvP.ElapsedHours;
1008 			UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedMinutes=AvP.ElapsedMinutes;
1009 			UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedSeconds=AvP.ElapsedSeconds;
1010 		}
1011 	}
1012 
1013 	RenderString(GetTextString(TEXTSTRING_GAMESTATS_TIMEELAPSED),TABPOINT1,y,colour_to_draw);
1014 
1015 	sprintf(buffer,"%dh %02dm %02ds",AvP.ElapsedHours,AvP.ElapsedMinutes,AvP.ElapsedSeconds/65536);
1016 	RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw); //y was 50!
1017 
1018 	if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1019 		sprintf(buffer,"%dh %02dm %02ds",
1020 			UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedHours,
1021 			UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedMinutes,
1022 			UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Total_ElapsedSeconds/65536);
1023 		RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw); //y was 50!
1024 	} else {
1025 		RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1026 	}
1027 
1028 	colour_to_draw=COLOUR_WHITE;
1029 
1030 	if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1031 		/* Is it a completed target? */
1032 		best=0;
1033 		if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedHours>-1) {
1034 			targets++;
1035 			if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedHours>AvP.ElapsedHours) {
1036 				best=1;
1037 			} else if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedHours==AvP.ElapsedHours) {
1038 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedMinutes>AvP.ElapsedMinutes) {
1039 					best=1;
1040 				} else if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedMinutes==AvP.ElapsedMinutes) {
1041 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedSeconds>AvP.ElapsedSeconds) {
1042 						best=1;
1043 					} else if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedSeconds==AvP.ElapsedSeconds) {
1044 						best=1;
1045 					}
1046 				}
1047 			}
1048 			if (best) {
1049 				targetspassed++;
1050 				colour_to_draw=COLOUR_RED;
1051 			}
1052 		}
1053 	}
1054 	if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1055 		if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1056 			if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedHours>-1) {
1057 				sprintf(buffer,"%dh %02dm %02ds",
1058 					LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedHours,
1059 					LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedMinutes,
1060 					LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Total_ElapsedSeconds/65536
1061 				);
1062 				RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1063 			} else {
1064 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1065 			}
1066 		} else {
1067 			RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1068 		}
1069 	} else {
1070 		RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1071 	}
1072 
1073 	y+=NEWLINE_SPACING;
1074 	colour_to_draw=COLOUR_WHITE;
1075 
1076 	if (AvP.PlayerType==I_Predator) {
1077 
1078 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1079 			/* Is it a new best? */
1080 			best=0;
1081 			if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedHours>CurrentGameStatistics.Cloak_ElapsedHours) {
1082 				best=1;
1083 			} else if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedHours==CurrentGameStatistics.Cloak_ElapsedHours) {
1084 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedMinutes>CurrentGameStatistics.Cloak_ElapsedMinutes) {
1085 					best=1;
1086 				} else if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedMinutes==CurrentGameStatistics.Cloak_ElapsedMinutes) {
1087 					if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedSeconds>CurrentGameStatistics.Cloak_ElapsedSeconds) {
1088 						best=1;
1089 					} else if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedSeconds==CurrentGameStatistics.Cloak_ElapsedSeconds) {
1090 						best=1;
1091 					}
1092 				}
1093 			}
1094 			if (best) {
1095 				colour_to_draw=COLOUR_GREEN;
1096 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedHours=CurrentGameStatistics.Cloak_ElapsedHours;
1097 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedMinutes=CurrentGameStatistics.Cloak_ElapsedMinutes;
1098 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedSeconds=CurrentGameStatistics.Cloak_ElapsedSeconds;
1099 			}
1100 		}
1101 
1102 		RenderString(GetTextString(TEXTSTRING_GAMESTATS_TIMECLOAKED),TABPOINT1,y,colour_to_draw);
1103 
1104 		sprintf(buffer,"%dh %02dm %02ds",CurrentGameStatistics.Cloak_ElapsedHours,CurrentGameStatistics.Cloak_ElapsedMinutes,CurrentGameStatistics.Cloak_ElapsedSeconds/65536);
1105 		RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1106 
1107 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1108 			sprintf(buffer,"%dh %02dm %02ds",
1109 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedHours,
1110 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedMinutes,
1111 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Cloak_ElapsedSeconds/65536);
1112 			RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw); //y was 50!
1113 		} else {
1114 			RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1115 		}
1116 
1117 		colour_to_draw=COLOUR_WHITE;
1118 
1119 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1120 			/* Is it a completed target? */
1121 			best=0;
1122 			if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedHours>-1) {
1123 				targets++;
1124 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedHours>AvP.ElapsedHours) {
1125 					best=1;
1126 				} else if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedHours==AvP.ElapsedHours) {
1127 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedMinutes>AvP.ElapsedMinutes) {
1128 						best=1;
1129 					} else if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedMinutes==AvP.ElapsedMinutes) {
1130 						if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedSeconds>AvP.ElapsedSeconds) {
1131 							best=1;
1132 						} else if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedSeconds==AvP.ElapsedSeconds) {
1133 							best=1;
1134 						}
1135 					}
1136 				}
1137 				if (best) {
1138 					targetspassed++;
1139 					colour_to_draw=COLOUR_RED;
1140 				}
1141 			}
1142 		}
1143 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1144 			if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1145 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedHours>-1) {
1146 					sprintf(buffer,"%dh %02dm %02ds",
1147 						LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedHours,
1148 						LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedMinutes,
1149 						LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Cloak_ElapsedSeconds/65536
1150 					);
1151 					RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1152 				} else {
1153 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1154 				}
1155 			} else {
1156 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1157 			}
1158 		} else {
1159 			RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1160 		}
1161 
1162 		y+=NEWLINE_SPACING;
1163 		colour_to_draw=COLOUR_WHITE;
1164 	}
1165 
1166 	{
1167 		int i;
1168 		for (i=0; i<STATS_VICTIM_MAXIMUM; i++)
1169 		{
1170 			if ((CurrentGameStatistics.Killed[i])
1171 				||(LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Killed[i]>-1)
1172 				||((AvP.PlayerType==I_Predator)&&(LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]>-1))
1173 				||((AvP.PlayerType==I_Alien)&&(LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]>-1))
1174 				||((AvP.PlayerType==I_Alien)&&(LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.DeadHeadBites[i]>-1))
1175 				) {
1176 				if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1177 					/* Is it a new best? */
1178 					if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Killed[i]<=CurrentGameStatistics.Killed[i]) {
1179 						UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Killed[i]=CurrentGameStatistics.Killed[i];
1180 						colour_to_draw=COLOUR_GREEN;
1181 					}
1182 				}
1183 
1184 				sprintf(buffer,"%s %s",GetTextString(TemporaryNameStore[i]),GetTextString(TEXTSTRING_GAMESTATS_KILLED));
1185 				RenderString(buffer,TABPOINT1,y,colour_to_draw);
1186 
1187 				sprintf(buffer,"%d",CurrentGameStatistics.Killed[i]);
1188 				RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1189 
1190 				if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1191 					sprintf(buffer,"%d",
1192 						UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Killed[i]
1193 					);
1194 					RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1195 				} else {
1196 					RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1197 				}
1198 
1199 				colour_to_draw=COLOUR_WHITE;
1200 				if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1201 					/* Is it a completed target? */
1202 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Killed[i]>-1) {
1203 						targets++;
1204 						if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Killed[i]<=CurrentGameStatistics.Killed[i]) {
1205 							colour_to_draw=COLOUR_RED;
1206 							targetspassed++;
1207 						}
1208 					}
1209 				}
1210 				if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1211 					if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1212 						if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Killed[i]>-1) {
1213 							sprintf(buffer,"%d",
1214 								LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Killed[i]
1215 							);
1216 							RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1217 						} else {
1218 							RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1219 						}
1220 					} else {
1221 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1222 					}
1223 				} else {
1224 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1225 				}
1226 
1227 				y+=NEWLINE_SPACING;
1228 				colour_to_draw=COLOUR_WHITE;
1229 				if (AvP.PlayerType==I_Predator) {
1230 					if ((i!=STATS_VICTIM_XENOBORG)
1231 						&&(i!=STATS_VICTIM_QUEEN)
1232 						&&(i!=STATS_VICTIM_FACEHUGGER)
1233 						&&(i!=STATS_VICTIM_PREDATOR)
1234 						){
1235 
1236 						if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1237 							/* Is it a new best? */
1238 							if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].TrophiesOrLiveHeadBites[i]<=CurrentGameStatistics.Trophies[i]) {
1239 								UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].TrophiesOrLiveHeadBites[i]=CurrentGameStatistics.Trophies[i];
1240 								colour_to_draw=COLOUR_GREEN;
1241 							}
1242 						}
1243 
1244 						sprintf(buffer,"%s %s",GetTextString(TemporaryNameStore2[i]),GetTextString(TEXTSTRING_GAMESTATS_TROPHIESCOLLECTED));
1245 						RenderString(buffer,TABPOINT1,y,colour_to_draw);
1246 
1247 						sprintf(buffer,"%d",CurrentGameStatistics.Trophies[i]);
1248 						RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1249 
1250 						if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1251 							sprintf(buffer,"%d",
1252 								UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].TrophiesOrLiveHeadBites[i]
1253 							);
1254 							RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1255 						} else {
1256 							RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1257 						}
1258 
1259 						colour_to_draw=COLOUR_WHITE;
1260 						if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1261 							/* Is it a completed target? */
1262 							if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]>-1) {
1263 								targets++;
1264 								if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]<=CurrentGameStatistics.Trophies[i]) {
1265 									colour_to_draw=COLOUR_RED;
1266 									targetspassed++;
1267 								}
1268 							}
1269 						}
1270 						if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1271 							if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1272 								if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]>-1) {
1273 									sprintf(buffer,"%d",
1274 										LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]
1275 									);
1276 									RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1277 								} else {
1278 									RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1279 								}
1280 							} else {
1281 								RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1282 							}
1283 						} else {
1284 							RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1285 						}
1286 
1287 						y+=NEWLINE_SPACING;
1288 						colour_to_draw=COLOUR_WHITE;
1289 					}
1290 				} else if (AvP.PlayerType==I_Alien) {
1291 					if ((i!=STATS_VICTIM_ANDROID)
1292 						&&(i!=STATS_VICTIM_XENOMORPH)
1293 						&&(i!=STATS_VICTIM_PREDALIEN)
1294 						&&(i!=STATS_VICTIM_PRAETORIAN)
1295 						&&(i!=STATS_VICTIM_QUEEN)
1296 						&&(i!=STATS_VICTIM_XENOBORG)
1297 						&&(i!=STATS_VICTIM_FACEHUGGER)
1298 						){
1299 
1300 						if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1301 							/* Is it a new best? */
1302 							if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].TrophiesOrLiveHeadBites[i]<=CurrentGameStatistics.LiveHeadBites[i]) {
1303 								UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].TrophiesOrLiveHeadBites[i]=CurrentGameStatistics.LiveHeadBites[i];
1304 								colour_to_draw=COLOUR_GREEN;
1305 							}
1306 						}
1307 
1308 						sprintf(buffer,"%s %s",GetTextString(TemporaryNameStore2[i]),GetTextString(TEXTSTRING_GAMESTATS_LIVEHEADBITES));
1309 						RenderString(buffer,TABPOINT1,y,colour_to_draw);
1310 
1311 						sprintf(buffer,"%d",CurrentGameStatistics.LiveHeadBites[i]);
1312 						RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1313 
1314 						if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1315 							sprintf(buffer,"%d",
1316 								UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].TrophiesOrLiveHeadBites[i]
1317 							);
1318 							RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1319 						} else {
1320 							RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1321 						}
1322 
1323 						colour_to_draw=COLOUR_WHITE;
1324 						if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1325 							/* Is it a completed target? */
1326 							if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]>-1) {
1327 								targets++;
1328 								if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]<=CurrentGameStatistics.LiveHeadBites[i]) {
1329 									colour_to_draw=COLOUR_RED;
1330 									targetspassed++;
1331 								}
1332 							}
1333 						}
1334 						if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1335 							if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1336 								if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]>-1) {
1337 									sprintf(buffer,"%d",
1338 										LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.TrophiesOrLiveHeadBites[i]
1339 									);
1340 									RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1341 								} else {
1342 									RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1343 								}
1344 							} else {
1345 								RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1346 							}
1347 						} else {
1348 							RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1349 						}
1350 
1351 						y+=NEWLINE_SPACING;
1352 						colour_to_draw=COLOUR_WHITE;
1353 
1354 						if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1355 							/* Is it a new best? */
1356 							if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].DeadHeadBites[i]<=CurrentGameStatistics.DeadHeadBites[i]) {
1357 								UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].DeadHeadBites[i]=CurrentGameStatistics.DeadHeadBites[i];
1358 								colour_to_draw=COLOUR_GREEN;
1359 							}
1360 						}
1361 
1362 						sprintf(buffer,"%s %s",GetTextString(TemporaryNameStore2[i]),GetTextString(TEXTSTRING_GAMESTATS_DEADHEADBITES));
1363 						RenderString(buffer,TABPOINT1,y,colour_to_draw);
1364 
1365 						sprintf(buffer,"%d",CurrentGameStatistics.DeadHeadBites[i]);
1366 						RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1367 
1368 						if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1369 							sprintf(buffer,"%d",
1370 								UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].DeadHeadBites[i]
1371 							);
1372 							RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1373 						} else {
1374 							RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1375 						}
1376 
1377 						colour_to_draw=COLOUR_WHITE;
1378 						if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1379 							/* Is it a completed target? */
1380 							if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.DeadHeadBites[i]>-1) {
1381 								targets++;
1382 								if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.DeadHeadBites[i]<=CurrentGameStatistics.DeadHeadBites[i]) {
1383 									colour_to_draw=COLOUR_RED;
1384 									targetspassed++;
1385 								}
1386 							}
1387 						}
1388 						if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1389 							if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1390 								if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.DeadHeadBites[i]>-1) {
1391 									sprintf(buffer,"%d",
1392 										LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.DeadHeadBites[i]
1393 									);
1394 									RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1395 								} else {
1396 									RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1397 								}
1398 							} else {
1399 								RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1400 							}
1401 						} else {
1402 							RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1403 						}
1404 
1405 						y+=NEWLINE_SPACING;
1406 						colour_to_draw=COLOUR_WHITE;
1407 					}
1408 				}
1409 			}
1410 		}
1411 	}
1412 
1413 	/* Speed? */
1414 	{
1415 		unsigned int total_time;
1416 		unsigned int average_speed;
1417 
1418 		float float_speed;
1419 
1420 		total_time=(AvP.ElapsedSeconds>>ONE_FIXED_SHIFT);
1421 		total_time+=(AvP.ElapsedMinutes*60);
1422 		total_time+=((AvP.ElapsedHours*60)*60);
1423 
1424 		if (total_time) {
1425 			average_speed=(CurrentGameStatistics.IntegralSpeed/total_time);
1426 
1427 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1428 				/* Is it a new best? */
1429 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Speed<=average_speed) {
1430 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Speed=average_speed;
1431 					colour_to_draw=COLOUR_GREEN;
1432 				}
1433 			}
1434 
1435 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_AVERAGESPEED),TABPOINT1,y,colour_to_draw);
1436 
1437 			float_speed=(float)average_speed;
1438 			float_speed/=1000;
1439 
1440 			sprintf(buffer,"%.1f m/s",float_speed);
1441 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1442 
1443 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1444 				float_speed=(float)UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Speed;
1445 				float_speed/=1000;
1446 
1447 				sprintf(buffer,"%.1f m/s",float_speed);
1448 
1449 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1450 			} else {
1451 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1452 			}
1453 
1454 			colour_to_draw=COLOUR_WHITE;
1455 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1456 				/* Is it a completed target? */
1457 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Speed>-1) {
1458 					targets++;
1459 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Speed<=average_speed) {
1460 						colour_to_draw=COLOUR_RED;
1461 						targetspassed++;
1462 					}
1463 				}
1464 			}
1465 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1466 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1467 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Speed>-1) {
1468 						float_speed=(float)LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Speed;
1469 						float_speed/=1000;
1470 						sprintf(buffer,"%.1f m/s",float_speed);
1471 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1472 					} else {
1473 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1474 					}
1475 				} else {
1476 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1477 				}
1478 			} else {
1479 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1480 			}
1481 		}
1482 	}
1483 	y+=NEWLINE_SPACING;
1484 	colour_to_draw=COLOUR_WHITE;
1485 	{
1486 		unsigned int percentage;
1487 		/* Health and armour. */
1488 		if (NpcData->StartingStats.Health) {
1489 			percentage=((CurrentGameStatistics.HealthDamage>>ONE_FIXED_SHIFT)*100)/(NpcData->StartingStats.Health);
1490 
1491 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1492 				/* Is it a new best? */
1493 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].HealthDamage>=percentage) {
1494 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].HealthDamage=percentage;
1495 					colour_to_draw=COLOUR_GREEN;
1496 				}
1497 			}
1498 
1499 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_HEALTHDAMAGETAKEN),TABPOINT1,y,colour_to_draw);
1500 
1501 			sprintf(buffer,"%03d%%",percentage);
1502 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1503 
1504 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1505 				sprintf(buffer,"%03d%%",
1506 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].HealthDamage
1507 				);
1508 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1509 			} else {
1510 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1511 			}
1512 
1513 			colour_to_draw=COLOUR_WHITE;
1514 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1515 				/* Is it a completed target? */
1516 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HealthDamage>-1) {
1517 					targets++;
1518 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HealthDamage>=percentage) {
1519 						colour_to_draw=COLOUR_RED;
1520 						targetspassed++;
1521 					}
1522 				}
1523 			}
1524 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1525 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1526 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HealthDamage>-1) {
1527 						sprintf(buffer,"%03d%%",
1528 							LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HealthDamage
1529 						);
1530 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1531 					} else {
1532 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1533 					}
1534 				} else {
1535 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1536 				}
1537 			} else {
1538 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1539 			}
1540 
1541 			y+=NEWLINE_SPACING;
1542 			colour_to_draw=COLOUR_WHITE;
1543 		}
1544 		if ((NpcData->StartingStats.Armour)&&(AvP.PlayerType==I_Marine)) {
1545 			percentage=((CurrentGameStatistics.ArmourDamage>>ONE_FIXED_SHIFT)*100)/(NpcData->StartingStats.Armour);
1546 
1547 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1548 				/* Is it a new best? */
1549 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ArmourDamage>=percentage) {
1550 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ArmourDamage=percentage;
1551 					colour_to_draw=COLOUR_GREEN;
1552 				}
1553 			}
1554 
1555 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_ARMOURDAMAGETAKEN),TABPOINT1,y,colour_to_draw);
1556 
1557 			sprintf(buffer,"%03d%%",percentage);
1558 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1559 
1560 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1561 				sprintf(buffer,"%03d%%",
1562 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ArmourDamage
1563 				);
1564 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1565 			} else {
1566 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1567 			}
1568 
1569 			colour_to_draw=COLOUR_WHITE;
1570 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1571 				/* Is it a completed target? */
1572 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ArmourDamage>-1) {
1573 					targets++;
1574 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ArmourDamage>=percentage) {
1575 						colour_to_draw=COLOUR_RED;
1576 						targetspassed++;
1577 					}
1578 				}
1579 			}
1580 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1581 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1582 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ArmourDamage>-1) {
1583 						sprintf(buffer,"%03d%%",
1584 							LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ArmourDamage
1585 						);
1586 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1587 					} else {
1588 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1589 					}
1590 				} else {
1591 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1592 				}
1593 			} else {
1594 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1595 			}
1596 
1597 			y+=NEWLINE_SPACING;
1598 			colour_to_draw=COLOUR_WHITE;
1599 		}
1600 
1601 	}
1602 	/* Creature specific stats... */
1603 	if (AvP.PlayerType==I_Marine) {
1604 		int headshots=0,kills=0,i;
1605 
1606 		for (i=0; i<STATS_VICTIM_MAXIMUM; i++)
1607 		{
1608 			headshots += CurrentGameStatistics.Decapitated[i];
1609 			kills += CurrentGameStatistics.Killed[i];
1610 		}
1611 		if (kills)
1612 		{
1613 			headshots = (100*headshots)/kills;
1614 		}
1615 		else
1616 		{
1617 			headshots = 0;
1618 		}
1619 
1620 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1621 			/* Is it a new best? */
1622 			if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].HeadShotPercentage<=headshots) {
1623 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].HeadShotPercentage=headshots;
1624 				colour_to_draw=COLOUR_GREEN;
1625 			}
1626 		}
1627 
1628 		RenderString(GetTextString(TEXTSTRING_GAMESTATS_HEADSHOTS),TABPOINT1,y,colour_to_draw);
1629 
1630 		sprintf(buffer,"%03d%%",headshots);
1631 		RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1632 
1633 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1634 			sprintf(buffer,"%03d%%",
1635 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].HeadShotPercentage
1636 			);
1637 			RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1638 		} else {
1639 			RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1640 		}
1641 
1642 		colour_to_draw=COLOUR_WHITE;
1643 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1644 			/* Is it a completed target? */
1645 			if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HeadShotPercentage>-1) {
1646 				targets++;
1647 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HeadShotPercentage<=headshots) {
1648 					colour_to_draw=COLOUR_RED;
1649 					targetspassed++;
1650 				}
1651 			}
1652 		}
1653 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1654 			if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1655 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HeadShotPercentage>-1) {
1656 					sprintf(buffer,"%03d%%",
1657 						LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.HeadShotPercentage
1658 					);
1659 					RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1660 				} else {
1661 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1662 				}
1663 			} else {
1664 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1665 			}
1666 		} else {
1667 			RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1668 		}
1669 
1670 		y+=NEWLINE_SPACING;
1671 		colour_to_draw=COLOUR_WHITE;
1672 		/* Shots fired... */
1673 		{
1674 			unsigned int total_shots;
1675 
1676 			total_shots=0;
1677 
1678 			for (i=0; i<MAX_NO_OF_WEAPON_SLOTS; i++) {
1679 				PLAYER_WEAPON_DATA *weaponPtr;
1680 				TEMPLATE_WEAPON_DATA *twPtr;
1681 
1682 			    weaponPtr = &(PlayerStatusPtr->WeaponSlot[i]);
1683 			    twPtr = &TemplateWeapon[weaponPtr->WeaponIDNumber];
1684 
1685 				if (twPtr->LogShots) {
1686 					total_shots+=CurrentGameStatistics.ShotsFired[i];
1687 				}
1688 			}
1689 
1690 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1691 				/* Is it a new best? */
1692 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ShotsFired>=total_shots) {
1693 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ShotsFired=total_shots;
1694 					colour_to_draw=COLOUR_GREEN;
1695 				}
1696 			}
1697 
1698 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_TOTALSHOTSFIRED),TABPOINT1,y,colour_to_draw);
1699 			sprintf(buffer,"%d\n",(total_shots));
1700 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1701 
1702 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1703 				sprintf(buffer,"%d",
1704 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ShotsFired
1705 				);
1706 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1707 			} else {
1708 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1709 			}
1710 
1711 			colour_to_draw=COLOUR_WHITE;
1712 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1713 				/* Is it a completed target? */
1714 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired>-1) {
1715 					targets++;
1716 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired>=total_shots) {
1717 						colour_to_draw=COLOUR_RED;
1718 						targetspassed++;
1719 					}
1720 				}
1721 			}
1722 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1723 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1724 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired>-1) {
1725 						sprintf(buffer,"%d",
1726 							LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired
1727 						);
1728 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1729 					} else {
1730 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1731 					}
1732 				} else {
1733 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1734 				}
1735 			} else {
1736 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1737 			}
1738 
1739 			y+=NEWLINE_SPACING;
1740 			colour_to_draw=COLOUR_WHITE;
1741 		}
1742 		/* Accuracy... */
1743 		{
1744 			unsigned int total_shots,total_hits,percentage;
1745 
1746 			total_shots=0;
1747 			total_hits=0;
1748 
1749 			for (i=0; i<MAX_NO_OF_WEAPON_SLOTS; i++) {
1750 				PLAYER_WEAPON_DATA *weaponPtr;
1751 				TEMPLATE_WEAPON_DATA *twPtr;
1752 
1753 			    weaponPtr = &(PlayerStatusPtr->WeaponSlot[i]);
1754 			    twPtr = &TemplateWeapon[weaponPtr->WeaponIDNumber];
1755 
1756 				if (twPtr->LogAccuracy) {
1757 					total_shots+=CurrentGameStatistics.ShotsFired[i];
1758 					total_hits+=CurrentGameStatistics.ShotsHit[i];
1759 				}
1760 			}
1761 			if (total_shots) {
1762 				percentage=(100*total_hits)/total_shots;
1763 			} else {
1764 				percentage=0;
1765 			}
1766 
1767 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1768 				/* Is it a new best? */
1769 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Accuracy<=percentage) {
1770 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Accuracy=percentage;
1771 					colour_to_draw=COLOUR_GREEN;
1772 				}
1773 			}
1774 
1775 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_ACCURACY),TABPOINT1,y,colour_to_draw);
1776 
1777 			sprintf(buffer,"%03d%%",percentage);
1778 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1779 
1780 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1781 				sprintf(buffer,"%03d%%",
1782 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Accuracy
1783 				);
1784 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1785 			} else {
1786 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1787 			}
1788 
1789 			colour_to_draw=COLOUR_WHITE;
1790 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1791 				/* Is it a completed target? */
1792 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy>-1) {
1793 					targets++;
1794 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy<=percentage) {
1795 						colour_to_draw=COLOUR_RED;
1796 						targetspassed++;
1797 					}
1798 				}
1799 			}
1800 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1801 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1802 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy>-1) {
1803 						sprintf(buffer,"%03d%%",
1804 							LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy
1805 						);
1806 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1807 					} else {
1808 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1809 					}
1810 				} else {
1811 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1812 				}
1813 			} else {
1814 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1815 			}
1816 
1817 			y+=NEWLINE_SPACING;
1818 			colour_to_draw=COLOUR_WHITE;
1819 		}
1820 		/* Preferred weapon... */
1821 		{
1822 			unsigned int maxtime=0;
1823 			int preferred_slot=-1;
1824 			PLAYER_WEAPON_DATA *weaponPtr;
1825 
1826 			for (i=0; i<MAX_NO_OF_WEAPON_SLOTS; i++) {
1827 				if (CurrentGameStatistics.WeaponTimes[i]>=maxtime) {
1828 					maxtime=CurrentGameStatistics.WeaponTimes[i];
1829 					preferred_slot=i;
1830 				}
1831 			}
1832 			GLOBALASSERT(preferred_slot!=-1);
1833 
1834 		    weaponPtr = &(PlayerStatusPtr->WeaponSlot[preferred_slot]);
1835 
1836 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_PREFERREDWEAPON),TABPOINT1,y,colour_to_draw);
1837 			sprintf(buffer,"%s\n",GetTextString(TemplateWeapon[weaponPtr->WeaponIDNumber].Name));
1838 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1839 
1840 			RenderStringCentred("---",TABPOINT3,y,colour_to_draw);
1841 			RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1842 
1843 			y+=NEWLINE_SPACING;
1844 			colour_to_draw=COLOUR_WHITE;
1845 		}
1846 	} else if (AvP.PlayerType==I_Alien) {
1847 
1848 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1849 			/* Is it a new best? */
1850 			if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Spotted>=CurrentGameStatistics.Spotted) {
1851 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Spotted=CurrentGameStatistics.Spotted;
1852 				colour_to_draw=COLOUR_GREEN;
1853 			}
1854 		}
1855 
1856 		RenderString(GetTextString(TEXTSTRING_GAMESTATS_SPOTTED),TABPOINT1,y,colour_to_draw);
1857 
1858 		sprintf(buffer,"%d",CurrentGameStatistics.Spotted);
1859 		RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1860 
1861 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1862 			sprintf(buffer,"%d",
1863 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Spotted
1864 			);
1865 			RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1866 		} else {
1867 			RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1868 		}
1869 
1870 		colour_to_draw=COLOUR_WHITE;
1871 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1872 			/* Is it a completed target? */
1873 			if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted>-1) {
1874 				targets++;
1875 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted>=CurrentGameStatistics.Spotted) {
1876 					colour_to_draw=COLOUR_RED;
1877 					targetspassed++;
1878 				}
1879 			}
1880 		}
1881 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1882 			if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1883 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted>-1) {
1884 					sprintf(buffer,"%d",
1885 						LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted
1886 					);
1887 					RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1888 				} else {
1889 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1890 				}
1891 			} else {
1892 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1893 			}
1894 		} else {
1895 			RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1896 		}
1897 
1898 		y+=NEWLINE_SPACING;
1899 		colour_to_draw=COLOUR_WHITE;
1900 
1901 	} else if (AvP.PlayerType==I_Predator) {
1902 
1903 		int i;
1904 
1905 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1906 			/* Is it a new best? */
1907 			if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Spotted>=CurrentGameStatistics.Spotted) {
1908 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Spotted=CurrentGameStatistics.Spotted;
1909 				colour_to_draw=COLOUR_GREEN;
1910 			}
1911 		}
1912 
1913 		RenderString(GetTextString(TEXTSTRING_GAMESTATS_SPOTTED),TABPOINT1,y,colour_to_draw);
1914 
1915 		sprintf(buffer,"%d",CurrentGameStatistics.Spotted);
1916 		RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1917 
1918 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1919 			sprintf(buffer,"%d",
1920 				UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Spotted
1921 			);
1922 			RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1923 		} else {
1924 			RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1925 		}
1926 
1927 		colour_to_draw=COLOUR_WHITE;
1928 		if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1929 			/* Is it a completed target? */
1930 			if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted>-1) {
1931 				targets++;
1932 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted>=CurrentGameStatistics.Spotted) {
1933 					colour_to_draw=COLOUR_RED;
1934 					targetspassed++;
1935 				}
1936 			}
1937 		}
1938 		if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1939 			if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1940 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted>-1) {
1941 					sprintf(buffer,"%d",
1942 						LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Spotted
1943 					);
1944 					RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
1945 				} else {
1946 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1947 				}
1948 			} else {
1949 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1950 			}
1951 		} else {
1952 			RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
1953 		}
1954 
1955 		y+=NEWLINE_SPACING;
1956 		colour_to_draw=COLOUR_WHITE;
1957 
1958 		/* FieldCharge... */
1959 		{
1960 			unsigned int percentage;
1961 
1962 			percentage=CurrentGameStatistics.FieldChargeUsed/(PLAYERCLOAK_MAXENERGY/100);
1963 
1964 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1965 				/* Is it a new best? */
1966 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].FieldChargeUsed>=percentage) {
1967 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].FieldChargeUsed=percentage;
1968 					colour_to_draw=COLOUR_GREEN;
1969 				}
1970 			}
1971 
1972 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_FIELDCHARGEUSED),TABPOINT1,y,colour_to_draw);
1973 
1974 			sprintf(buffer,"%03d%%",percentage);
1975 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
1976 
1977 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1978 				sprintf(buffer,"%03d%%",
1979 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].FieldChargeUsed
1980 				);
1981 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
1982 			} else {
1983 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
1984 			}
1985 
1986 			colour_to_draw=COLOUR_WHITE;
1987 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
1988 				/* Is it a completed target? */
1989 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.FieldChargeUsed>-1) {
1990 					targets++;
1991 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.FieldChargeUsed>=percentage) {
1992 						colour_to_draw=COLOUR_RED;
1993 						targetspassed++;
1994 					}
1995 				}
1996 			}
1997 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
1998 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
1999 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.FieldChargeUsed>-1) {
2000 						sprintf(buffer,"%03d%%",
2001 							LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.FieldChargeUsed
2002 						);
2003 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
2004 					} else {
2005 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2006 					}
2007 				} else {
2008 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2009 				}
2010 			} else {
2011 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2012 			}
2013 
2014 			y+=NEWLINE_SPACING;
2015 			colour_to_draw=COLOUR_WHITE;
2016 
2017 		}
2018 		/* Shots fired... */
2019 		{
2020 			unsigned int total_shots;
2021 
2022 			total_shots=0;
2023 
2024 			for (i=0; i<MAX_NO_OF_WEAPON_SLOTS; i++) {
2025 				PLAYER_WEAPON_DATA *weaponPtr;
2026 				TEMPLATE_WEAPON_DATA *twPtr;
2027 
2028 			    weaponPtr = &(PlayerStatusPtr->WeaponSlot[i]);
2029 			    twPtr = &TemplateWeapon[weaponPtr->WeaponIDNumber];
2030 
2031 				if (twPtr->LogShots) {
2032 					total_shots+=CurrentGameStatistics.ShotsFired[i];
2033 				}
2034 			}
2035 
2036 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
2037 				/* Is it a new best? */
2038 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ShotsFired>=total_shots) {
2039 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ShotsFired=total_shots;
2040 					colour_to_draw=COLOUR_GREEN;
2041 				}
2042 			}
2043 
2044 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_TOTALSHOTSFIRED),TABPOINT1,y,colour_to_draw);
2045 
2046 			sprintf(buffer,"%d",(total_shots));
2047 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
2048 
2049 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
2050 				sprintf(buffer,"%d",
2051 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].ShotsFired
2052 				);
2053 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
2054 			} else {
2055 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
2056 			}
2057 
2058 			colour_to_draw=COLOUR_WHITE;
2059 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
2060 				/* Is it a completed target? */
2061 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired>-1) {
2062 					targets++;
2063 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired>=total_shots) {
2064 						colour_to_draw=COLOUR_RED;
2065 						targetspassed++;
2066 					}
2067 				}
2068 			}
2069 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
2070 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
2071 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired>-1) {
2072 						sprintf(buffer,"%d",
2073 							LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.ShotsFired
2074 						);
2075 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
2076 					} else {
2077 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2078 					}
2079 				} else {
2080 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2081 				}
2082 			} else {
2083 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2084 			}
2085 
2086 			y+=NEWLINE_SPACING;
2087 			colour_to_draw=COLOUR_WHITE;
2088 		}
2089 		/* Accuracy... */
2090 		{
2091 			unsigned int total_shots,total_hits,percentage;
2092 
2093 			total_shots=0;
2094 			total_hits=0;
2095 
2096 			for (i=0; i<MAX_NO_OF_WEAPON_SLOTS; i++) {
2097 				PLAYER_WEAPON_DATA *weaponPtr;
2098 				TEMPLATE_WEAPON_DATA *twPtr;
2099 
2100 			    weaponPtr = &(PlayerStatusPtr->WeaponSlot[i]);
2101 			    twPtr = &TemplateWeapon[weaponPtr->WeaponIDNumber];
2102 
2103 				if (twPtr->LogAccuracy) {
2104 					total_shots+=CurrentGameStatistics.ShotsFired[i];
2105 					total_hits+=CurrentGameStatistics.ShotsHit[i];
2106 				}
2107 			}
2108 			if (total_shots) {
2109 				percentage=(100*total_hits)/total_shots;
2110 			} else {
2111 				percentage=0;
2112 			}
2113 
2114 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
2115 				/* Is it a new best? */
2116 				if (UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Accuracy<=percentage) {
2117 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Accuracy=percentage;
2118 					colour_to_draw=COLOUR_GREEN;
2119 				}
2120 			}
2121 
2122 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_ACCURACY),TABPOINT1,y,colour_to_draw);
2123 
2124 			sprintf(buffer,"%03d%%",percentage);
2125 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
2126 
2127 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
2128 				sprintf(buffer,"%03d%%",
2129 					UserProfilePtr->PersonalBests[AvP.Difficulty][level_num].Accuracy
2130 				);
2131 				RenderStringCentred(buffer,TABPOINT3,y,colour_to_draw);
2132 			} else {
2133 				RenderStringCentred("---",TABPOINT3,y,COLOUR_WHITE);
2134 			}
2135 
2136 			colour_to_draw=COLOUR_WHITE;
2137 			if ((completed_level)&&(level_num<AVP_ENVIRONMENT_END_OF_LIST)) {
2138 				/* Is it a completed target? */
2139 				if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy>-1) {
2140 					targets++;
2141 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy<=percentage) {
2142 						colour_to_draw=COLOUR_RED;
2143 						targetspassed++;
2144 					}
2145 				}
2146 			}
2147 			if ((level_num<AVP_ENVIRONMENT_END_OF_LIST)&&(NotCheating)) {
2148 				if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
2149 					if (LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy>-1) {
2150 						sprintf(buffer,"%03d%%",
2151 							LevelStatsTargets[AvP.Difficulty][level_num].StatTargets.Accuracy
2152 						);
2153 						RenderStringCentred(buffer,TABPOINT4,y,colour_to_draw);
2154 					} else {
2155 						RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2156 					}
2157 				} else {
2158 					RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2159 				}
2160 			} else {
2161 				RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2162 			}
2163 
2164 			y+=NEWLINE_SPACING;
2165 			colour_to_draw=COLOUR_WHITE;
2166 		}
2167 		/* Preferred weapon... */
2168 		{
2169 			unsigned int maxtime=0;
2170 			int preferred_slot=-1;
2171 			PLAYER_WEAPON_DATA *weaponPtr;
2172 
2173 			for (i=0; i<MAX_NO_OF_WEAPON_SLOTS; i++) {
2174 				if (CurrentGameStatistics.WeaponTimes[i]>=maxtime) {
2175 					maxtime=CurrentGameStatistics.WeaponTimes[i];
2176 					preferred_slot=i;
2177 				}
2178 			}
2179 			GLOBALASSERT(preferred_slot!=-1);
2180 
2181 		    weaponPtr = &(PlayerStatusPtr->WeaponSlot[preferred_slot]);
2182 
2183 			RenderString(GetTextString(TEXTSTRING_GAMESTATS_PREFERREDWEAPON),TABPOINT1,y,colour_to_draw);
2184 
2185 			sprintf(buffer,"%s",GetTextString(TemplateWeapon[weaponPtr->WeaponIDNumber].Name));
2186 			RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
2187 
2188 			RenderStringCentred("---",TABPOINT3,y,colour_to_draw);
2189 			RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2190 
2191 			y+=NEWLINE_SPACING;
2192 			colour_to_draw=COLOUR_WHITE;
2193 		}
2194 	}
2195 
2196 	/* Vision Mode... */
2197 	{
2198 		int i;
2199 		unsigned int maxtime=0;
2200 		int preferred_slot=-1;
2201 
2202 		for (i=0; i<NUMBER_OF_VISION_MODES; i++) {
2203 			if (CurrentGameStatistics.VisionModeTimes[i]>=maxtime) {
2204 				maxtime=CurrentGameStatistics.VisionModeTimes[i];
2205 				preferred_slot=i;
2206 			}
2207 		}
2208 		GLOBALASSERT(preferred_slot!=-1);
2209 
2210 		RenderString(GetTextString(TEXTSTRING_GAMESTATS_PREFERREDVISIONMODE),TABPOINT1,y,colour_to_draw);
2211 		sprintf(buffer,"%s\n",GetTextString(VisionModeNames[preferred_slot]));
2212 		RenderStringCentred(buffer,TABPOINT2,y,colour_to_draw);
2213 
2214 		RenderStringCentred("---",TABPOINT3,y,colour_to_draw);
2215 		RenderStringCentred("---",TABPOINT4,y,COLOUR_WHITE);
2216 
2217 	}
2218 	y+=NEWLINE_SPACING;
2219 	colour_to_draw=COLOUR_WHITE;
2220 
2221 	/* Unlock a cheat mode? */
2222 
2223 	if (NotCheating) {
2224 		if (targets) {
2225 			if (targets==targetspassed) {
2226 				if (LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate!=CHEATMODE_NONACTIVE) {
2227 					if (UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]!=1) {
2228 						UserProfilePtr->CheatMode[LevelStatsTargets[AvP.Difficulty][level_num].CheatModeToActivate]=2;
2229 						RenderStringCentred(GetTextString(TEXTSTRING_GAMESTATS_CHEATMODEENABLED),ScreenDescriptorBlock.SDB_Width/2,y,COLOUR_GREEN);
2230 					}
2231 				}
2232 			}
2233 		}
2234 	}
2235 }
2236