1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 * Intermission screens.
30 *-----------------------------------------------------------------------------
46 // Data needed to add patches to full screen intermission pics.
47 // Patches are statistics messages, and animations.
48 // Loads of by-pixel layout and placement, offsets etc.
52 // Different vetween registered DOOM (1994) and
53 // Ultimate DOOM - Final edition (retail, 1995?).
54 // This is supposedly ignored for commercial
55 // release (aka DOOM II), which had 34 maps
56 // in one episode. So there.
63 //U #define PAUSELEN (TICRATE*2)
64 //U #define SCORESTEP 100
65 //U #define ANIMPERIOD 32
66 // pixel distance from "(YOU)" to "PLAYER N"
67 //U #define STARDIST 10
73 #define WI_SPACINGY 33
75 // SINGLE-PLAYER STUFF
80 // proff/nicolas 09/20/98 -- changed for hi-res
82 //#define SP_TIMEY (SCREENHEIGHT-32)
87 #define NG_STATSX (32 + V_NamePatchWidth(star)/2 + 32*!dofrags)
89 #define NG_SPACINGX 64
92 // Used to display the frags matrix at endgame
97 #define DM_SPACINGX 40
99 #define DM_TOTALSX 269
101 #define DM_KILLERSX 10
102 #define DM_KILLERSY 100
103 #define DM_VICTIMSX 5
104 #define DM_VICTIMSY 50
107 // These animation variables, structures, etc. are used for the
108 // DOOM/Ultimate DOOM intermission screen animations. This is
109 // totally different from any sprite or texture/flat animations
112 ANIM_ALWAYS
, // determined by patch entry
113 ANIM_RANDOM
, // occasional
114 ANIM_LEVEL
// continuous
116 typedef unsigned animenum_t
;
120 int x
; // x/y coordinate pair structure
127 // There is another anim_t used in p_spec.
133 // period in tics between animations
136 // number of animation frames
139 // location of animation
143 // RANDOM: period deviation (<256),
148 // RANDOM: random base period,
152 /* actual graphics for frames of animations
157 // following must be initialized to zero before use!
159 // next value of bcnt (used in conjunction with period)
162 // last drawn animation frame
165 // next frame number to animate
168 // used by RANDOM and LEVEL when animating
173 static point_t lnodes
[NUMEPISODES
][NUMMAPS
] =
175 // Episode 0 World Map
177 { 185, 164 }, // location of level 0 (CJ)
178 { 148, 143 }, // location of level 1 (CJ)
179 { 69, 122 }, // location of level 2 (CJ)
180 { 209, 102 }, // location of level 3 (CJ)
181 { 116, 89 }, // location of level 4 (CJ)
182 { 166, 55 }, // location of level 5 (CJ)
183 { 71, 56 }, // location of level 6 (CJ)
184 { 135, 29 }, // location of level 7 (CJ)
185 { 71, 24 } // location of level 8 (CJ)
188 // Episode 1 World Map should go here
190 { 254, 25 }, // location of level 0 (CJ)
191 { 97, 50 }, // location of level 1 (CJ)
192 { 188, 64 }, // location of level 2 (CJ)
193 { 128, 78 }, // location of level 3 (CJ)
194 { 214, 92 }, // location of level 4 (CJ)
195 { 133, 130 }, // location of level 5 (CJ)
196 { 208, 136 }, // location of level 6 (CJ)
197 { 148, 140 }, // location of level 7 (CJ)
198 { 235, 158 } // location of level 8 (CJ)
201 // Episode 2 World Map should go here
203 { 156, 168 }, // location of level 0 (CJ)
204 { 48, 154 }, // location of level 1 (CJ)
205 { 174, 95 }, // location of level 2 (CJ)
206 { 265, 75 }, // location of level 3 (CJ)
207 { 130, 48 }, // location of level 4 (CJ)
208 { 279, 23 }, // location of level 5 (CJ)
209 { 198, 48 }, // location of level 6 (CJ)
210 { 140, 25 }, // location of level 7 (CJ)
211 { 281, 136 } // location of level 8 (CJ)
218 // Animation locations for episode 0 (1).
219 // Using patches saves a lot of space,
220 // as they replace 320x200 full screen frames.
222 static anim_t epsd0animinfo
[] =
224 { ANIM_ALWAYS
, TICRATE
/3, 3, { 224, 104 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
225 { ANIM_ALWAYS
, TICRATE
/3, 3, { 184, 160 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
226 { ANIM_ALWAYS
, TICRATE
/3, 3, { 112, 136 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
227 { ANIM_ALWAYS
, TICRATE
/3, 3, { 72, 112 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
228 { ANIM_ALWAYS
, TICRATE
/3, 3, { 88, 96 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
229 { ANIM_ALWAYS
, TICRATE
/3, 3, { 64, 48 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
230 { ANIM_ALWAYS
, TICRATE
/3, 3, { 192, 40 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
231 { ANIM_ALWAYS
, TICRATE
/3, 3, { 136, 16 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
232 { ANIM_ALWAYS
, TICRATE
/3, 3, { 80, 16 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
233 { ANIM_ALWAYS
, TICRATE
/3, 3, { 64, 24 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 }
236 static anim_t epsd1animinfo
[] =
238 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 1, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
239 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 2, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
240 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 3, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
241 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 4, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
242 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 5, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
243 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 6, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
244 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 7, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
245 { ANIM_LEVEL
, TICRATE
/3, 3, { 192, 144 }, 8, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
246 { ANIM_LEVEL
, TICRATE
/3, 1, { 128, 136 }, 8, 0, { 0, 0, 0 }, 0, 0, 0, 0 }
249 static anim_t epsd2animinfo
[] =
251 { ANIM_ALWAYS
, TICRATE
/3, 3, { 104, 168 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
252 { ANIM_ALWAYS
, TICRATE
/3, 3, { 40, 136 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
253 { ANIM_ALWAYS
, TICRATE
/3, 3, { 160, 96 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
254 { ANIM_ALWAYS
, TICRATE
/3, 3, { 104, 80 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
255 { ANIM_ALWAYS
, TICRATE
/3, 3, { 120, 32 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 },
256 { ANIM_ALWAYS
, TICRATE
/4, 3, { 40, 0 }, 0, 0, { 0, 0, 0 }, 0, 0, 0, 0 }
259 static int NUMANIMS
[NUMEPISODES
] =
261 sizeof(epsd0animinfo
)/sizeof(anim_t
),
262 sizeof(epsd1animinfo
)/sizeof(anim_t
),
263 sizeof(epsd2animinfo
)/sizeof(anim_t
)
266 static anim_t
*anims
[NUMEPISODES
] =
279 // Locally used stuff.
284 // States for single-player
290 #define SP_PAR ST_TIME
295 #define SHOWNEXTLOCDELAY 4
296 //#define SHOWLASTLOCDELAY SHOWNEXTLOCDELAY
299 // used to accelerate or skip a stage
300 int acceleratestage
; // killough 3/28/98: made global
305 // specifies current state
306 static stateenum_t state
;
308 // contains information passed into intermission
309 static wbstartstruct_t
* wbs
;
311 static wbplayerstruct_t
* plrs
; // wbs->plyr[]
313 // used for general timing
316 // used for timing of background animation
319 // signals to refresh everything for one frame
320 static int firstrefresh
;
323 static int cnt_total_time
;
325 static int cnt_pause
;
332 // You Are Here graphic
333 static const char* yah
[2] = { "WIURH0", "WIURH1" };
336 static const char* splat
= "WISPLAT";
339 static const char percent
[] = {"WIPCNT"};
340 static const char colon
[] = {"WICOLON"};
343 static const patch_t
* num
[10];
346 static const char wiminus
[] = {"WIMINUS"};
348 // "Finished!" graphics
349 static const char finished
[] = {"WIF"};
351 // "Entering" graphic
352 static const char entering
[] = {"WIENTER"};
355 static const char sp_secret
[] = {"WISCRT2"};
357 // "Kills", "Scrt", "Items", "Frags"
358 static const char kills
[] = {"WIOSTK"};
359 static const char secret
[] = {"WIOSTS"};
360 static const char items
[] = {"WIOSTI"};
361 static const char frags
[] = {"WIFRGS"};
364 static const char time1
[] = {"WITIME"};
365 static const char par
[] = {"WIPAR"};
366 static const char sucks
[] = {"WISUCKS"};
368 // "killers", "victims"
369 static const char killers
[] = {"WIKILRS"};
370 static const char victims
[] = {"WIVCTMS"};
372 // "Total", your face, your dead face
373 static const char total
[] = {"WIMSTT"};
374 static const char star
[] = {"STFST01"};
375 static const char bstar
[] = {"STFDEAD0"};
377 // "red P[1..MAXPLAYERS]"
378 static const char facebackp
[] = {"STPB0"};
385 static void WI_endDeathmatchStats(void);
386 static void WI_endNetgameStats(void);
387 void WI_unloadData(void);
388 #define WI_endStats WI_endNetgameStats
390 /* ====================================================================
392 * Purpore: Returns the name of the graphic lump containing the name of
394 * Args: Episode and level, and buffer (must by 9 chars) to write to
397 void WI_levelNameLump(int epis
, int map
, char* buf
, int bsize
)
399 if (gamemode
== commercial
) {
400 snprintf(buf
, bsize
,"CWILV%s%d",(map
/10>0?"":"0"), map
); //ANOTHER ROCKHACK "CWILV%2.2d"
401 //snprintf(buf,bsize, "CWILV%2.2d", map);
403 snprintf(buf
,bsize
, "WILV%d%d", epis
, map
);
407 // ====================================================================
409 // Purpose: Put the full-screen background up prior to patches
413 static void WI_slamBackground(void)
415 char name
[9]; // limited to 8 characters
417 if (gamemode
== commercial
|| (gamemode
== retail
&& wbs
->epsd
== 3))
418 strcpy(name
, "INTERPIC");
420 snprintf(name
, sizeof(name
), "WIMAP%d", wbs
->epsd
);
423 V_DrawNamePatch(0, 0, FB
, name
, CR_DEFAULT
, VPT_STRETCH
);
426 // ====================================================================
428 // Purpose: Draw animations on intermission background screen
429 // Args: ev -- event pointer, not actually used here.
430 // Returns: False -- dummy routine
432 // The ticker is used to detect keys
433 // because of timing issues in netgames.
434 boolean
WI_Responder(event_t
* ev
)
440 // ====================================================================
442 // Purpose: Draw the "Finished" level name before showing stats
452 /* cph - get the graphic lump name and use it */
453 WI_levelNameLump(wbs
->epsd
, wbs
->last
, lname
, sizeof(lname
));
454 // CPhipps - patch drawing updated
455 V_DrawNamePatch((320 - V_NamePatchWidth(lname
))/2, y
,
456 FB
, lname
, CR_DEFAULT
, VPT_STRETCH
);
459 y
+= (5*V_NamePatchHeight(lname
))/4;
461 // CPhipps - patch drawing updated
462 V_DrawNamePatch((320 - V_NamePatchWidth(finished
))/2, y
,
463 FB
, finished
, CR_DEFAULT
, VPT_STRETCH
);
466 // ====================================================================
468 // Purpose: Draw introductory "Entering" and level name
477 /* cph - get the graphic lump name */
478 WI_levelNameLump(wbs
->epsd
, wbs
->next
, lname
, sizeof(lname
));
481 // CPhipps - patch drawing updated
482 V_DrawNamePatch((320 - V_NamePatchWidth(entering
))/2,
483 y
, FB
, entering
, CR_DEFAULT
, VPT_STRETCH
);
486 y
+= (5*V_NamePatchHeight(lname
))/4;
488 // CPhipps - patch drawing updated
489 V_DrawNamePatch((320 - V_NamePatchWidth(lname
))/2, y
, FB
,
490 lname
, CR_DEFAULT
, VPT_STRETCH
);
494 /* ====================================================================
496 * Purpose: Draw patches at a location based on episode/map
497 * Args: n -- index to map# within episode
498 * c[] -- array of names of patches to be drawn
502 WI_drawOnLnode
// draw stuff at a location by episode/map#
504 const char* const c
[] )
507 boolean fits
= false;
516 int lump
= W_GetNumForName(c
[i
]);
517 const patch_t
* p
= W_CacheLumpNum(lump
);
519 left
= lnodes
[wbs
->epsd
][n
].x
- SHORT(p
->leftoffset
);
520 top
= lnodes
[wbs
->epsd
][n
].y
- SHORT(p
->topoffset
);
521 right
= left
+ SHORT(p
->width
);
522 bottom
= top
+ SHORT(p
->height
);
523 W_UnlockLumpNum(lump
);
536 } while (!fits
&& i
!=2);
540 // CPhipps - patch drawing updated
541 V_DrawNamePatch(lnodes
[wbs
->epsd
][n
].x
, lnodes
[wbs
->epsd
][n
].y
,
542 FB
, c
[i
], CR_DEFAULT
, VPT_STRETCH
);
547 //jff 8/3/98 use logical output routine
548 printf("Could not place patch on level %d", n
+1);
553 // ====================================================================
554 // WI_initAnimatedBack
555 // Purpose: Initialize pointers and styles for background animation
559 void WI_initAnimatedBack(void)
564 if (gamemode
== commercial
) // no animation for DOOM2
570 for (i
=0;i
<NUMANIMS
[wbs
->epsd
];i
++)
572 a
= &anims
[wbs
->epsd
][i
];
577 // specify the next time to draw it
578 if (a
->type
== ANIM_ALWAYS
)
579 a
->nexttic
= bcnt
+ 1 + (M_Random()%a
->period
);
581 if (a
->type
== ANIM_RANDOM
)
582 a
->nexttic
= bcnt
+ 1 + a
->data2
+(M_Random()%a
->data1
);
584 if (a
->type
== ANIM_LEVEL
)
585 a
->nexttic
= bcnt
+ 1;
590 // ====================================================================
591 // WI_updateAnimatedBack
592 // Purpose: Figure out what animation we do on this iteration
596 void WI_updateAnimatedBack(void)
601 if (gamemode
== commercial
)
607 for (i
=0;i
<NUMANIMS
[wbs
->epsd
];i
++)
609 a
= &anims
[wbs
->epsd
][i
];
611 if (bcnt
== a
->nexttic
)
616 if (++a
->ctr
>= a
->nanims
) a
->ctr
= 0;
617 a
->nexttic
= bcnt
+ a
->period
;
622 if (a
->ctr
== a
->nanims
)
625 a
->nexttic
= bcnt
+a
->data2
+(M_Random()%a
->data1
);
628 a
->nexttic
= bcnt
+ a
->period
;
632 // gawd-awful hack for level anims
633 if (!(state
== StatCount
&& i
== 7)
634 && wbs
->next
== a
->data1
)
637 if (a
->ctr
== a
->nanims
) a
->ctr
--;
638 a
->nexttic
= bcnt
+ a
->period
;
647 // ====================================================================
648 // WI_drawAnimatedBack
649 // Purpose: Actually do the animation (whew!)
653 void WI_drawAnimatedBack(void)
658 if (gamemode
==commercial
) //jff 4/25/98 Someone forgot commercial an enum
664 for (i
=0 ; i
<NUMANIMS
[wbs
->epsd
] ; i
++)
666 a
= &anims
[wbs
->epsd
][i
];
669 // CPhipps - patch drawing updated
670 V_DrawMemPatch(a
->loc
.x
, a
->loc
.y
, FB
, a
->p
[a
->ctr
], CR_DEFAULT
, VPT_STRETCH
);
675 // ====================================================================
677 // Purpose: Draws a number. If digits > 0, then use that many digits
678 // minimum, otherwise only use as many as necessary
679 // Args: x, y -- location
680 // n -- the number to be drawn
681 // digits -- number of digits minimum or zero
682 // Returns: new x position after drawing (note we are going to the left)
684 static int WI_drawNum (int x
, int y
, int n
, int digits
)
686 int fontwidth
= SHORT(num
[0]->width
);
694 // make variable-length zeros 1 digit long
699 // figure out # of digits in #
715 // if non-number, do not draw it
719 // draw the new number
723 // CPhipps - patch drawing updated
724 V_DrawMemPatch(x
, y
, FB
, num
[ n
% 10 ], CR_DEFAULT
, VPT_STRETCH
);
728 // draw a minus sign if necessary
730 // CPhipps - patch drawing updated
731 V_DrawNamePatch(x
-=8, y
, FB
, wiminus
, CR_DEFAULT
, VPT_STRETCH
);
737 // ====================================================================
739 // Purpose: Draws a percentage, really just a call to WI_drawNum
740 // after putting a percent sign out there
741 // Args: x, y -- location
742 // p -- the percentage value to be drawn, no negatives
745 static void WI_drawPercent(int x
, int y
, int p
)
750 // CPhipps - patch drawing updated
751 V_DrawNamePatch(x
, y
, FB
, percent
, CR_DEFAULT
, VPT_STRETCH
);
752 WI_drawNum(x
, y
, p
, -1);
756 // ====================================================================
758 // Purpose: Draws the level completion time or par time, or "Sucks"
760 // Args: x, y -- location
761 // t -- the time value to be drawn
765 // - largely rewritten to display hours and use slightly better algorithm
767 static void WI_drawTime(int x
, int y
, int t
)
778 x
= WI_drawNum(x
, y
, n
, (t
|| n
>9) ? 2 : 1) - V_NamePatchWidth(colon
);
782 // CPhipps - patch drawing updated
783 V_DrawNamePatch(x
, y
, FB
, colon
, CR_DEFAULT
, VPT_STRETCH
);
786 else // "sucks" (maybe should be "addicted", even I've never had a 100 hour game ;)
787 V_DrawNamePatch(x
- V_NamePatchWidth(sucks
),
788 y
, FB
, sucks
, CR_DEFAULT
, VPT_STRETCH
);
792 // ====================================================================
794 // Purpose: Unloads data structures (inverse of WI_Start)
803 WI_endDeathmatchStats();
805 WI_endNetgameStats();
811 // ====================================================================
813 // Purpose: Clear state, ready for end of level activity
817 void WI_initNoState(void)
825 // ====================================================================
827 // Purpose: Put the times on the screen
828 // Args: time, total time, par time, in seconds
831 // cph - pulled from WI_drawStats below
833 static void WI_drawTimeStats(int cnt_time
, int cnt_total_time
, int cnt_par
)
835 V_DrawNamePatch(SP_TIMEX
, SP_TIMEY
, FB
, time1
, CR_DEFAULT
, VPT_STRETCH
);
836 WI_drawTime(320/2 - SP_TIMEX
, SP_TIMEY
, cnt_time
);
838 V_DrawNamePatch(SP_TIMEX
, (SP_TIMEY
+200)/2, FB
, total
, CR_DEFAULT
, VPT_STRETCH
);
839 WI_drawTime(320/2 - SP_TIMEX
, (SP_TIMEY
+200)/2, cnt_total_time
);
841 // Ty 04/11/98: redid logic: should skip only if with pwad but
843 // killough 2/22/98: skip drawing par times on pwads
844 // Ty 03/17/98: unless pars changed with deh patch
846 if (!(modifiedgame
)) //&& !deh_pars))
850 V_DrawNamePatch(320/2 + SP_TIMEX
, SP_TIMEY
, FB
, par
, CR_DEFAULT
, VPT_STRETCH
);
851 WI_drawTime(320 - SP_TIMEX
, SP_TIMEY
, cnt_par
);
856 // ====================================================================
858 // Purpose: Cycle until end of level activity is done
862 void WI_updateNoState(void)
865 WI_updateAnimatedBack();
871 static boolean snl_pointeron
= false;
875 // ====================================================================
876 // WI_initShowNextLoc
877 // Purpose: Prepare to show the next level's location
881 void WI_initShowNextLoc(void)
883 if ((gamemode
!= commercial
) && (gamemap
== 8)) {
890 cnt
= SHOWNEXTLOCDELAY
* TICRATE
;
892 WI_initAnimatedBack();
895 // ====================================================================
896 // WI_updateShowNextLoc
897 // Purpose: Prepare to show the next level's location
901 void WI_updateShowNextLoc(void)
903 WI_updateAnimatedBack();
905 if (!--cnt
|| acceleratestage
)
908 snl_pointeron
= (cnt
& 31) < 20;
912 // ====================================================================
913 // WI_drawShowNextLoc
914 // Purpose: Show the next level's location on animated backgrounds
918 void WI_drawShowNextLoc(void)
925 // draw animated background
926 WI_drawAnimatedBack();
928 if ( gamemode
!= commercial
)
932 WI_drawEL(); // "Entering..." if not E1 or E2
936 last
= (wbs
->last
== 8) ? wbs
->next
- 1 : wbs
->last
;
938 // draw a splat on taken cities.
939 for (i
=0 ; i
<=last
; i
++)
940 WI_drawOnLnode(i
, &splat
);
942 // splat the secret level?
944 WI_drawOnLnode(8, &splat
);
948 WI_drawOnLnode(wbs
->next
, yah
);
951 // draws which level you are entering..
952 if ( (gamemode
!= commercial
)
953 || wbs
->next
!= 30) // check for MAP30 end game
957 // ====================================================================
959 // Purpose: Draw the pointer and next location
963 void WI_drawNoState(void)
965 snl_pointeron
= true;
966 WI_drawShowNextLoc();
970 // ====================================================================
972 // Purpose: Calculate frags for this player based on the current totals
973 // of all the other players. Subtract self-frags.
974 // Args: playernum -- the player to be calculated
975 // Returns: the total frags for this player
977 int WI_fragSum(int playernum
)
982 for (i
=0 ; i
<MAXPLAYERS
; i
++)
984 if (playeringame
[i
] // is this player playing?
985 && i
!=playernum
) // and it's not the player we're calculating
987 frags
+= plrs
[playernum
].frags
[i
];
992 // JDC hack - negative frags.
993 frags
-= plrs
[playernum
].frags
[playernum
];
1000 // CPhipps - short, dynamically allocated
1001 static short int **dm_frags
; // frags matrix
1002 static short int *dm_totals
; // totals by player
1004 // ====================================================================
1005 // WI_initDeathmatchStats
1006 // Purpose: Set up to display DM stats at end of level. Calculate
1007 // frags for all players.
1011 void WI_initDeathmatchStats(void)
1013 int i
; // looping variables
1015 // CPhipps - allocate data structures needed
1016 dm_frags
= calloc(MAXPLAYERS
, sizeof(*dm_frags
));
1017 dm_totals
= calloc(MAXPLAYERS
, sizeof(*dm_totals
));
1019 state
= StatCount
; // We're doing stats
1020 acceleratestage
= 0;
1021 dm_state
= 1; // count how many times we've done a complete stat
1023 cnt_pause
= TICRATE
;
1025 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1027 if (playeringame
[i
])
1029 // CPhipps - allocate frags line
1030 dm_frags
[i
] = calloc(MAXPLAYERS
, sizeof(**dm_frags
)); // set all counts to zero
1035 WI_initAnimatedBack();
1039 // ====================================================================
1040 // CPhipps - WI_endDeathmatchStats
1041 // Purpose: Deallocate dynamically allocated DM stats data
1046 void WI_endDeathmatchStats(void)
1049 for (i
=0; i
<MAXPLAYERS
; i
++)
1052 free(dm_frags
); free(dm_totals
);
1055 // ====================================================================
1056 // WI_updateDeathmatchStats
1057 // Purpose: Advance Deathmatch stats screen animation. Calculate
1058 // frags for all players. Lots of noise and drama around
1059 // the presentation.
1063 void WI_updateDeathmatchStats(void)
1068 boolean stillticking
;
1070 WI_updateAnimatedBack();
1072 if (acceleratestage
&& dm_state
!= 4) // still ticking
1074 acceleratestage
= 0;
1076 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1078 if (playeringame
[i
])
1080 for (j
=0 ; j
<MAXPLAYERS
; j
++)
1081 if (playeringame
[j
])
1082 dm_frags
[i
][j
] = plrs
[i
].frags
[j
];
1084 dm_totals
[i
] = WI_fragSum(i
);
1089 S_StartSound(0, sfx_barexp
); // bang
1090 dm_state
= 4; // we're done with all 4 (or all we have to do)
1097 S_StartSound(0, sfx_pistol
); // noise while counting
1099 stillticking
= false;
1101 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1103 if (playeringame
[i
])
1105 for (j
=0 ; j
<MAXPLAYERS
; j
++)
1108 && dm_frags
[i
][j
] != plrs
[i
].frags
[j
])
1110 if (plrs
[i
].frags
[j
] < 0)
1115 if (dm_frags
[i
][j
] > 999) // Ty 03/17/98 3-digit frag count
1116 dm_frags
[i
][j
] = 999;
1118 if (dm_frags
[i
][j
] < -999)
1119 dm_frags
[i
][j
] = -999;
1121 stillticking
= true;
1124 dm_totals
[i
] = WI_fragSum(i
);
1126 if (dm_totals
[i
] > 999)
1129 if (dm_totals
[i
] < -999)
1130 dm_totals
[i
] = -999; // Ty 03/17/98 end 3-digit frag count
1136 S_StartSound(0, sfx_barexp
);
1140 else if (dm_state
== 4)
1142 if (acceleratestage
)
1144 S_StartSound(0, sfx_slop
);
1146 if ( gamemode
== commercial
)
1149 WI_initShowNextLoc();
1152 else if (dm_state
& 1)
1157 cnt_pause
= TICRATE
;
1163 // ====================================================================
1164 // WI_drawDeathmatchStats
1165 // Purpose: Draw the stats on the screen in a matrix
1169 // proff/nicolas 09/20/98 -- changed for hi-res
1170 // CPhipps - patch drawing updated
1171 void WI_drawDeathmatchStats(void)
1179 int halfface
= V_NamePatchWidth(facebackp
)/2;
1181 WI_slamBackground();
1183 // draw animated background
1184 WI_drawAnimatedBack();
1187 // draw stat titles (top line)
1188 V_DrawNamePatch(DM_TOTALSX
-V_NamePatchWidth(total
)/2,
1189 DM_MATRIXY
-WI_SPACINGY
+10, FB
, total
, CR_DEFAULT
, VPT_STRETCH
);
1191 V_DrawNamePatch(DM_KILLERSX
, DM_KILLERSY
, FB
, killers
, CR_DEFAULT
, VPT_STRETCH
);
1192 V_DrawNamePatch(DM_VICTIMSX
, DM_VICTIMSY
, FB
, victims
, CR_DEFAULT
, VPT_STRETCH
);
1195 x
= DM_MATRIXX
+ DM_SPACINGX
;
1198 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1200 if (playeringame
[i
]) {
1201 //int trans = playernumtotrans[i];
1202 V_DrawNamePatch(x
-halfface
, DM_MATRIXY
- WI_SPACINGY
,
1203 FB
, facebackp
, i
? CR_LIMIT
+i
: CR_DEFAULT
,
1204 VPT_STRETCH
| (i
? VPT_TRANS
: 0));
1205 V_DrawNamePatch(DM_MATRIXX
-halfface
, y
,
1206 FB
, facebackp
, i
? CR_LIMIT
+i
: CR_DEFAULT
,
1207 VPT_STRETCH
| (i
? VPT_TRANS
: 0));
1211 V_DrawNamePatch(x
-halfface
, DM_MATRIXY
- WI_SPACINGY
,
1212 FB
, bstar
, CR_DEFAULT
, VPT_STRETCH
);
1213 V_DrawNamePatch(DM_MATRIXX
-halfface
, y
,
1214 FB
, star
, CR_DEFAULT
, VPT_STRETCH
);
1223 w
= SHORT(num
[0]->width
);
1225 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1227 x
= DM_MATRIXX
+ DM_SPACINGX
;
1229 if (playeringame
[i
])
1231 for (j
=0 ; j
<MAXPLAYERS
; j
++)
1233 if (playeringame
[j
])
1234 WI_drawNum(x
+w
, y
, dm_frags
[i
][j
], 2);
1238 WI_drawNum(DM_TOTALSX
+w
, y
, dm_totals
[i
], 2);
1246 // Note: The term "Netgame" means a coop game
1248 static short *cnt_kills
;
1249 static short *cnt_items
;
1250 static short *cnt_secret
;
1251 static short *cnt_frags
;
1253 static int ng_state
;
1255 // ====================================================================
1256 // CPhipps - WI_endNetgameStats
1257 // Purpose: Clean up coop game stats
1261 static void WI_endNetgameStats(void)
1269 // ====================================================================
1270 // WI_initNetgameStats
1271 // Purpose: Prepare for coop game stats
1275 void WI_initNetgameStats(void)
1280 acceleratestage
= 0;
1283 cnt_pause
= TICRATE
;
1285 // CPhipps - allocate these dynamically, blank with calloc
1286 cnt_kills
= calloc(MAXPLAYERS
, sizeof(*cnt_kills
));
1287 cnt_items
= calloc(MAXPLAYERS
, sizeof(*cnt_items
));
1288 cnt_secret
= calloc(MAXPLAYERS
, sizeof(*cnt_secret
));
1289 cnt_frags
= calloc(MAXPLAYERS
, sizeof(*cnt_frags
));
1291 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1292 if (playeringame
[i
])
1293 dofrags
+= WI_fragSum(i
);
1295 dofrags
= !!dofrags
; // set to true or false - did we have frags?
1297 WI_initAnimatedBack();
1301 // ====================================================================
1302 // WI_updateNetgameStats
1303 // Purpose: Calculate coop stats as we display them with noise and fury
1306 // Comment: This stuff sure is complicated for what it does
1308 void WI_updateNetgameStats(void)
1313 boolean stillticking
;
1315 WI_updateAnimatedBack();
1317 if (acceleratestage
&& ng_state
!= 10)
1319 acceleratestage
= 0;
1321 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1323 if (!playeringame
[i
])
1326 cnt_kills
[i
] = (plrs
[i
].skills
* 100) / wbs
->maxkills
;
1327 cnt_items
[i
] = (plrs
[i
].sitems
* 100) / wbs
->maxitems
;
1329 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1330 cnt_secret
[i
] = wbs
->maxsecret
?
1331 (plrs
[i
].ssecret
* 100) / wbs
->maxsecret
: 100;
1333 cnt_frags
[i
] = WI_fragSum(i
); // we had frags
1335 S_StartSound(0, sfx_barexp
); // bang
1342 S_StartSound(0, sfx_pistol
); // pop
1344 stillticking
= false;
1346 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1348 if (!playeringame
[i
])
1353 if (cnt_kills
[i
] >= (plrs
[i
].skills
* 100) / wbs
->maxkills
)
1354 cnt_kills
[i
] = (plrs
[i
].skills
* 100) / wbs
->maxkills
;
1356 stillticking
= true; // still got stuff to tally
1361 S_StartSound(0, sfx_barexp
);
1365 else if (ng_state
== 4)
1368 S_StartSound(0, sfx_pistol
);
1370 stillticking
= false;
1372 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1374 if (!playeringame
[i
])
1378 if (cnt_items
[i
] >= (plrs
[i
].sitems
* 100) / wbs
->maxitems
)
1379 cnt_items
[i
] = (plrs
[i
].sitems
* 100) / wbs
->maxitems
;
1381 stillticking
= true;
1386 S_StartSound(0, sfx_barexp
);
1390 else if (ng_state
== 6)
1393 S_StartSound(0, sfx_pistol
);
1395 stillticking
= false;
1397 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1399 if (!playeringame
[i
])
1404 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1406 if (cnt_secret
[i
] >= (wbs
->maxsecret
? (plrs
[i
].ssecret
* 100) / wbs
->maxsecret
: compatibility_level
< lxdoom_1_compatibility
? 0 : 100))
1407 cnt_secret
[i
] = wbs
->maxsecret
? (plrs
[i
].ssecret
* 100) / wbs
->maxsecret
: 100;
1409 stillticking
= true;
1414 S_StartSound(0, sfx_barexp
);
1415 ng_state
+= 1 + 2*!dofrags
;
1418 else if (ng_state
== 8)
1421 S_StartSound(0, sfx_pistol
);
1423 stillticking
= false;
1425 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1427 if (!playeringame
[i
])
1432 if (cnt_frags
[i
] >= (fsum
= WI_fragSum(i
)))
1433 cnt_frags
[i
] = fsum
;
1435 stillticking
= true;
1440 S_StartSound(0, sfx_pldeth
);
1444 else if (ng_state
== 10)
1446 if (acceleratestage
)
1448 S_StartSound(0, sfx_sgcock
);
1449 if ( gamemode
== commercial
)
1452 WI_initShowNextLoc();
1455 else if (ng_state
& 1)
1460 cnt_pause
= TICRATE
;
1466 // ====================================================================
1467 // WI_drawNetgameStats
1468 // Purpose: Put the coop stats on the screen
1472 // proff/nicolas 09/20/98 -- changed for hi-res
1473 // CPhipps - patch drawing updated
1474 void WI_drawNetgameStats(void)
1479 int pwidth
= V_NamePatchWidth(percent
);
1480 int fwidth
= V_NamePatchWidth(facebackp
);
1482 WI_slamBackground();
1484 // draw animated background
1485 WI_drawAnimatedBack();
1489 // draw stat titles (top line)
1490 V_DrawNamePatch(NG_STATSX
+NG_SPACINGX
-V_NamePatchWidth(kills
),
1491 NG_STATSY
, FB
, kills
, CR_DEFAULT
, VPT_STRETCH
);
1493 V_DrawNamePatch(NG_STATSX
+2*NG_SPACINGX
-V_NamePatchWidth(items
),
1494 NG_STATSY
, FB
, items
, CR_DEFAULT
, VPT_STRETCH
);
1496 V_DrawNamePatch(NG_STATSX
+3*NG_SPACINGX
-V_NamePatchWidth(secret
),
1497 NG_STATSY
, FB
, secret
, CR_DEFAULT
, VPT_STRETCH
);
1500 V_DrawNamePatch(NG_STATSX
+4*NG_SPACINGX
-V_NamePatchWidth(frags
),
1501 NG_STATSY
, FB
, frags
, CR_DEFAULT
, VPT_STRETCH
);
1504 y
= NG_STATSY
+ V_NamePatchHeight(kills
);
1506 for (i
=0 ; i
<MAXPLAYERS
; i
++)
1508 //int trans = playernumtotrans[i];
1509 if (!playeringame
[i
])
1513 V_DrawNamePatch(x
-fwidth
, y
, FB
, facebackp
,
1514 i
? CR_LIMIT
+i
: CR_DEFAULT
,
1515 VPT_STRETCH
| (i
? VPT_TRANS
: 0));
1518 V_DrawNamePatch(x
-fwidth
, y
, FB
, star
, CR_DEFAULT
, VPT_STRETCH
);
1521 WI_drawPercent(x
-pwidth
, y
+10, cnt_kills
[i
]); x
+= NG_SPACINGX
;
1522 WI_drawPercent(x
-pwidth
, y
+10, cnt_items
[i
]); x
+= NG_SPACINGX
;
1523 WI_drawPercent(x
-pwidth
, y
+10, cnt_secret
[i
]); x
+= NG_SPACINGX
;
1526 WI_drawNum(x
, y
+10, cnt_frags
[i
], -1);
1532 // cph - show times in coop on the entering screen
1533 WI_drawTimeStats(plrs
[me
].stime
/ TICRATE
, wbs
->totaltimes
/ TICRATE
, wbs
->partime
/ TICRATE
);
1536 static int sp_state
;
1538 // ====================================================================
1540 // Purpose: Get ready for single player stats
1543 // Comment: Seems like we could do all these stats in a more generic
1544 // set of routines that weren't duplicated for dm, coop, sp
1546 void WI_initStats(void)
1549 acceleratestage
= 0;
1552 // CPhipps - allocate (awful code, I know, but saves changing it all) and initialise
1553 *(cnt_kills
= malloc(sizeof(*cnt_kills
))) =
1554 *(cnt_items
= malloc(sizeof(*cnt_items
))) =
1555 *(cnt_secret
= malloc(sizeof(*cnt_secret
))) = -1;
1556 cnt_time
= cnt_par
= cnt_total_time
= -1;
1557 cnt_pause
= TICRATE
;
1559 WI_initAnimatedBack();
1562 // ====================================================================
1564 // Purpose: Calculate solo stats
1568 void WI_updateStats(void)
1570 WI_updateAnimatedBack();
1572 if (acceleratestage
&& sp_state
!= 10)
1574 acceleratestage
= 0;
1575 cnt_kills
[0] = (plrs
[me
].skills
* 100) / wbs
->maxkills
;
1576 cnt_items
[0] = (plrs
[me
].sitems
* 100) / wbs
->maxitems
;
1578 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1579 cnt_secret
[0] = (wbs
->maxsecret
?
1580 (plrs
[me
].ssecret
* 100) / wbs
->maxsecret
: 100);
1582 cnt_total_time
= wbs
->totaltimes
/ TICRATE
;
1583 cnt_time
= plrs
[me
].stime
/ TICRATE
;
1584 cnt_par
= wbs
->partime
/ TICRATE
;
1585 S_StartSound(0, sfx_barexp
);
1594 S_StartSound(0, sfx_pistol
);
1596 if (cnt_kills
[0] >= (plrs
[me
].skills
* 100) / wbs
->maxkills
)
1598 cnt_kills
[0] = (plrs
[me
].skills
* 100) / wbs
->maxkills
;
1599 S_StartSound(0, sfx_barexp
);
1603 else if (sp_state
== 4)
1608 S_StartSound(0, sfx_pistol
);
1610 if (cnt_items
[0] >= (plrs
[me
].sitems
* 100) / wbs
->maxitems
)
1612 cnt_items
[0] = (plrs
[me
].sitems
* 100) / wbs
->maxitems
;
1613 S_StartSound(0, sfx_barexp
);
1617 else if (sp_state
== 6)
1622 S_StartSound(0, sfx_pistol
);
1624 // killough 2/22/98: Make secrets = 100% if maxsecret = 0:
1625 if ((!wbs
->maxsecret
&& compatibility_level
< lxdoom_1_compatibility
) ||
1626 cnt_secret
[0] >= (wbs
->maxsecret
?
1627 (plrs
[me
].ssecret
* 100) / wbs
->maxsecret
: 100))
1629 cnt_secret
[0] = (wbs
->maxsecret
?
1630 (plrs
[me
].ssecret
* 100) / wbs
->maxsecret
: 100);
1631 S_StartSound(0, sfx_barexp
);
1635 else if (sp_state
== 8)
1638 S_StartSound(0, sfx_pistol
);
1642 if (cnt_time
>= plrs
[me
].stime
/ TICRATE
)
1643 cnt_time
= plrs
[me
].stime
/ TICRATE
;
1645 cnt_total_time
+= 3;
1647 if (cnt_total_time
>= wbs
->totaltimes
/ TICRATE
)
1648 cnt_total_time
= wbs
->totaltimes
/ TICRATE
;
1652 if (cnt_par
>= wbs
->partime
/ TICRATE
)
1654 cnt_par
= wbs
->partime
/ TICRATE
;
1656 if ((cnt_time
>= plrs
[me
].stime
/ TICRATE
) && (compatibility_level
< lxdoom_1_compatibility
|| cnt_total_time
>= wbs
->totaltimes
/ TICRATE
))
1658 S_StartSound(0, sfx_barexp
);
1663 else if (sp_state
== 10)
1665 if (acceleratestage
)
1667 S_StartSound(0, sfx_sgcock
);
1669 if (gamemode
== commercial
)
1672 WI_initShowNextLoc();
1675 else if (sp_state
& 1)
1680 cnt_pause
= TICRATE
;
1686 // ====================================================================
1688 // Purpose: Put the solo stats on the screen
1692 // proff/nicolas 09/20/98 -- changed for hi-res
1693 // CPhipps - patch drawing updated
1694 void WI_drawStats(void)
1699 lh
= (3*SHORT(num
[0]->height
))/2;
1701 WI_slamBackground();
1703 // draw animated background
1704 WI_drawAnimatedBack();
1708 V_DrawNamePatch(SP_STATSX
, SP_STATSY
, FB
, kills
, CR_DEFAULT
, VPT_STRETCH
);
1709 WI_drawPercent(320 - SP_STATSX
, SP_STATSY
, cnt_kills
[0]);
1711 V_DrawNamePatch(SP_STATSX
, SP_STATSY
+lh
, FB
, items
, CR_DEFAULT
, VPT_STRETCH
);
1712 WI_drawPercent(320 - SP_STATSX
, SP_STATSY
+lh
, cnt_items
[0]);
1714 V_DrawNamePatch(SP_STATSX
, SP_STATSY
+2*lh
, FB
, sp_secret
, CR_DEFAULT
, VPT_STRETCH
);
1715 WI_drawPercent(320 - SP_STATSX
, SP_STATSY
+2*lh
, cnt_secret
[0]);
1717 WI_drawTimeStats(cnt_time
, cnt_total_time
, cnt_par
);
1720 // ====================================================================
1721 // WI_checkForAccelerate
1722 // Purpose: See if the player has hit either the attack or use key
1723 // or mouse button. If so we set acceleratestage to 1 and
1724 // all those display routines above jump right to the end.
1728 void WI_checkForAccelerate(void)
1733 // check for button presses to skip delays
1734 for (i
=0, player
= players
; i
<MAXPLAYERS
; i
++, player
++)
1736 if (playeringame
[i
])
1738 if (player
->cmd
.buttons
& BT_ATTACK
)
1740 if (!player
->attackdown
)
1741 acceleratestage
= 1;
1742 player
->attackdown
= true;
1745 player
->attackdown
= false;
1747 if (player
->cmd
.buttons
& BT_USE
)
1749 if (!player
->usedown
)
1750 acceleratestage
= 1;
1751 player
->usedown
= true;
1754 player
->usedown
= false;
1759 // ====================================================================
1761 // Purpose: Do various updates every gametic, for stats, animation,
1762 // checking that intermission music is running, etc.
1766 void WI_Ticker(void)
1768 // counter for general background animation
1773 // intermission music
1774 if ( gamemode
== commercial
)
1775 S_ChangeMusic(mus_dm2int
, true);
1777 S_ChangeMusic(mus_inter
, true);
1780 WI_checkForAccelerate();
1785 if (deathmatch
) WI_updateDeathmatchStats();
1786 else if (netgame
) WI_updateNetgameStats();
1787 else WI_updateStats();
1791 WI_updateShowNextLoc();
1800 /* ====================================================================
1802 * Purpose: Initialize intermission data such as background graphics,
1803 * patches, map names, etc.
1807 * CPhipps - modified for new wad lump handling.
1808 * - no longer preload most graphics, other funcs can use
1812 void WI_loadData(void)
1816 char name
[9]; // limited to 8 characters
1819 if (gamemode
!= commercial
)
1823 for (j
=0;j
<NUMANIMS
[wbs
->epsd
];j
++)
1825 a
= &anims
[wbs
->epsd
][j
];
1826 for (i
=0;i
<a
->nanims
;i
++)
1829 if (wbs
->epsd
!= 1 || j
!= 8)
1832 snprintf(name
, sizeof(name
),"WIA%d%s%d%s%d", wbs
->epsd
, (j
/10>0?"":"0"), j
,(i
/10>0?"":"0"), i
); //ANOTHER ROCKHACK
1833 //snprintf(name, sizeof(name),"WIA%d%.2d%.2d", wbs->epsd, j, i);
1834 a
->p
[i
] = W_CacheLumpName(name
);
1839 a
->p
[i
] = anims
[1][4].p
[i
];
1849 snprintf(name
,sizeof(name
),"WINUM%d", i
);
1850 num
[i
] = W_CacheLumpName(name
);
1854 // ====================================================================
1856 // Purpose: Free up the space allocated during WI_loadData
1860 // CPhipps - reverse of WI_loadData, goes through the same lumps, but unlocking
1861 void WI_unloadData(void)
1864 char name
[9]; // limited to 8 characters
1866 // cph - unlock gamemode dependent stuff here
1867 if (gamemode
!= commercial
) {
1868 if (wbs
->epsd
< 3) {
1869 for (j
=0;j
<NUMANIMS
[wbs
->epsd
];j
++) {
1870 anim_t
* a
= &anims
[wbs
->epsd
][j
];
1871 for (i
=0; i
<a
->nanims
; i
++) {
1873 if (wbs
->epsd
!= 1 || j
!= 8) {
1875 snprintf(name
, sizeof(name
),"WIA%d%s%d%s%d", wbs
->epsd
, (j
/10>0?"":"0"), j
,(i
/10>0?"":"0"), i
); //ANOTHER ROCKHACK
1876 //snprintf(name,sizeof(name), "WIA%d%.2d%.2d", wbs->epsd, j, i);
1877 W_UnlockLumpName(name
);
1884 for (i
=0;i
<10;i
++) {
1886 snprintf(name
, sizeof(name
),"WINUM%d", i
);
1887 W_UnlockLumpName(name
);
1892 // ====================================================================
1894 // Purpose: Call the appropriate stats drawing routine depending on
1895 // what kind of game is being played (DM, coop, solo)
1899 void WI_Drawer (void)
1905 WI_drawDeathmatchStats();
1907 WI_drawNetgameStats();
1913 WI_drawShowNextLoc();
1922 // ====================================================================
1924 // Purpose: Initialize the intermission information structure
1925 // Note: wbstartstruct_t is defined in d_player.h
1926 // Args: wbstartstruct -- pointer to the structure with the data
1929 void WI_initVariables(wbstartstruct_t
* wbstartstruct
)
1932 wbs
= wbstartstruct
;
1934 #ifdef RANGECHECKING
1935 if (gamemode
!= commercial
)
1937 if ( gamemode
== retail
)
1938 RNGCHECK(wbs
->epsd
, 0, 3);
1940 RNGCHECK(wbs
->epsd
, 0, 2);
1944 RNGCHECK(wbs
->last
, 0, 8);
1945 RNGCHECK(wbs
->next
, 0, 8);
1947 RNGCHECK(wbs
->pnum
, 0, MAXPLAYERS
);
1948 RNGCHECK(wbs
->pnum
, 0, MAXPLAYERS
);
1951 acceleratestage
= 0;
1958 wbs
->maxkills
= 1; // probably only useful in MAP30
1963 if ( gamemode
!= retail
)
1968 // ====================================================================
1970 // Purpose: Call the various init routines
1971 // Note: wbstartstruct_t is defined in d_player.h
1972 // Args: wbstartstruct -- pointer to the structure with the
1973 // intermission data
1976 void WI_Start(wbstartstruct_t
* wbstartstruct
)
1978 WI_initVariables(wbstartstruct
);
1982 WI_initDeathmatchStats();
1984 WI_initNetgameStats();