|
|
1.1 root 1: /* G_game.c */
2:
3: #include "doomdef.h"
4: #include "p_local.h"
5:
6: void G_PlayerReborn (int player);
7:
8: void G_DoReborn (int playernum);
9:
10: void G_DoLoadLevel (void);
11:
12:
13: gameaction_t gameaction;
14: skill_t gameskill;
15: int gamemap;
16: int nextmap; /* the map to go to after the stats */
17:
18: gametype_t netgame;
19:
20: boolean playeringame[MAXPLAYERS];
21: player_t players[MAXPLAYERS];
22:
23: int consoleplayer; /* player taking events and displaying */
24: int displayplayer; /* view being displayed */
25: int gametic;
26: int totalkills, totalitems, totalsecret; /* for intermission */
27:
28: char demoname[32];
29: boolean demorecording;
30: boolean demoplayback;
31:
32:
33: /*
34: ==============
35: =
36: = G_DoLoadLevel
37: =
38: ==============
39: */
40:
41: extern int skytexture;
42: extern texture_t *skytexturep;
43: extern texture_t textures[];
44:
45: void G_DoLoadLevel (void)
46: {
47: int i;
48:
49: for (i=0 ; i<MAXPLAYERS ; i++)
50: {
51: if (playeringame[i] && players[i].playerstate == PST_DEAD)
52: players[i].playerstate = PST_REBORN;
53: players[i].frags = 0;
54: }
55:
56: /* */
57: /* set the sky map for the episode */
58: /* */
59: if (gamemap < 9)
60: skytexture = R_TextureNumForName ("SKY1");
61: else if (gamemap < 18)
62: skytexture = R_TextureNumForName ("SKY2");
63: else
64: skytexture = R_TextureNumForName ("SKY3");
65:
66: skytexturep = &textures[skytexture];
67:
68: P_SetupLevel (gamemap, gameskill);
69: displayplayer = consoleplayer; /* view the guy you are playing */
70: gameaction = ga_nothing;
71:
72: /* S_StartSong(1, 0); */ /* Added CEF */
73:
74: Z_CheckHeap (mainzone); /* DEBUG */
75: }
76:
77:
78:
79: /*
80: ==============================================================================
81:
82: PLAYER STRUCTURE FUNCTIONS
83:
84: also see P_SpawnPlayer in P_Mobj
85: ==============================================================================
86: */
87:
88: /*
89: ====================
90: =
91: = G_PlayerFinishLevel
92: =
93: = Can when a player completes a level
94: ====================
95: */
96:
97: void G_PlayerFinishLevel (int player)
98: {
99: player_t *p;
100:
101: p = &players[player];
102:
103: D_memset (p->powers, 0, sizeof (p->powers));
104: D_memset (p->cards, 0, sizeof (p->cards));
105: p->mo->flags &= ~MF_SHADOW; /* cancel invisibility */
106: p->extralight = 0; /* cancel gun flashes */
107: p->fixedcolormap = 0; /* cancel ir gogles */
108: p->damagecount = 0; /* no palette changes */
109: p->bonuscount = 0;
110: }
111:
112: /*
113: ====================
114: =
115: = G_PlayerReborn
116: =
117: = Called after a player dies
118: = almost everything is cleared and initialized
119: ====================
120: */
121:
122: void G_PlayerReborn (int player)
123: {
124: player_t *p;
125: int i;
126: int frags;
127:
128:
129: p = &players[player];
130: frags = p->frags;
131: D_memset (p, 0, sizeof(*p));
132: p->frags = frags;
133: p->usedown = p->attackdown = true; /* don't do anything immediately */
134: p->playerstate = PST_LIVE;
135: p->health = MAXHEALTH;
136: p->readyweapon = p->pendingweapon = wp_pistol;
137: p->weaponowned[wp_fist] = true;
138: p->weaponowned[wp_pistol] = true;
139: p->ammo[am_clip] = 50;
140:
141: for (i=0 ; i<NUMAMMO ; i++)
142: p->maxammo[i] = maxammo[i];
143: }
144:
145:
146: /*
147: ====================
148: =
149: = G_CheckSpot
150: =
151: = Returns false if the player cannot be respawned at the given mapthing_t spot
152: = because something is occupying it
153: ====================
154: */
155:
156: void P_SpawnPlayer (mapthing_t *mthing);
157:
158: boolean G_CheckSpot (int playernum, mapthing_t *mthing)
159: {
160: fixed_t x,y;
161: subsector_t *ss;
162: int an;
163: mobj_t *mo;
164:
165: x = mthing->x << FRACBITS;
166: y = mthing->y << FRACBITS;
167:
168: if (!P_CheckPosition (players[playernum].mo, x, y) )
169: return false;
170:
171: ss = R_PointInSubsector (x,y);
172: an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT;
173:
174: /* spawn a teleport fog */
175: mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an], ss->sector->floorheight
176: , MT_TFOG);
177: S_StartSound (mo, sfx_telept);
178:
179: return true;
180: }
181:
182: /*
183: ====================
184: =
185: = G_DeathMatchSpawnPlayer
186: =
187: = Spawns a player at one of the random death match spots
188: = called at level load and each death
189: ====================
190: */
191:
192: void G_DeathMatchSpawnPlayer (int playernum)
193: {
194: int i,j;
195: int selections;
196:
197: selections = deathmatch_p - deathmatchstarts;
198: if (selections < 4)
199: I_Error ("Only %i deathmatch spots, 4 required", selections);
200:
201: for (j=0 ; j<20 ; j++)
202: {
203: i = P_Random()%selections;
204: if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
205: {
206: deathmatchstarts[i].type = playernum+1;
207: P_SpawnPlayer (&deathmatchstarts[i]);
208: return;
209: }
210: }
211:
212: /* no good spot, so the player will probably get stuck */
213: P_SpawnPlayer (&playerstarts[playernum]);
214: }
215:
216: /*
217: ====================
218: =
219: = G_DoReborn
220: =
221: ====================
222: */
223:
224: void G_DoReborn (int playernum)
225: {
226: int i;
227:
228: if (!netgame)
229: {
230: gameaction = ga_died; /* reload the level from scratch */
231: return;
232: }
233:
234: /* */
235: /* respawn this player while the other players keep going */
236: /* */
237: players[playernum].mo->player = NULL; /* dissasociate the corpse */
238:
239: /* spawn at random spot if in death match */
240: if (netgame == gt_deathmatch)
241: {
242: G_DeathMatchSpawnPlayer (playernum);
243: return;
244: }
245:
246: if (G_CheckSpot (playernum, &playerstarts[playernum]) )
247: {
248: P_SpawnPlayer (&playerstarts[playernum]);
249: return;
250: }
251: /* try to spawn at one of the other players spots */
252: for (i=0 ; i<MAXPLAYERS ; i++)
253: if (G_CheckSpot (playernum, &playerstarts[i]) )
254: {
255: playerstarts[i].type = playernum+1; /* fake as other player */
256: P_SpawnPlayer (&playerstarts[i]);
257: playerstarts[i].type = i+1; /* restore */
258: return;
259: }
260: /* he's going to be inside something. Too bad. */
261: P_SpawnPlayer (&playerstarts[playernum]);
262: }
263:
264:
265: /*
266: ====================
267: =
268: = G_ExitLevel
269: =
270: ====================
271: */
272:
273: void G_ExitLevel (void)
274: {
275: gameaction = ga_completed;
276: }
277:
278: void G_SecretExitLevel (void)
279: {
280: gameaction = ga_secretexit;
281: }
282:
283: /*============================================================================ */
284:
285: /*
286: ====================
287: =
288: = G_InitNew
289: =
290: ====================
291: */
292:
293: extern mobj_t emptymobj;
294:
295: void G_InitNew (skill_t skill, int map, gametype_t gametype)
296: {
297: int i;
298:
299: D_printf ("G_InitNew\n");
300:
301: M_ClearRandom ();
302:
303: /* these may be reset by I_NetSetup */
304: gamemap = map;
305: gameskill = skill;
306: netgame = gametype;
307: I_DrawSbar (); /* draw frag boxes if multiplayer */
308:
309: /* force players to be initialized upon first level load */
310: for (i=0 ; i<MAXPLAYERS ; i++)
311: players[i].playerstate = PST_REBORN;
312:
313: players[0].mo = players[1].mo = &emptymobj; /* for net consistancy checks */
314:
315: playeringame[0] = true;
316: if (netgame != gt_single)
317: playeringame[1] = true;
318: else
319: playeringame[1] = false;
320:
321: demorecording = false;
322: demoplayback = false;
323:
324:
325: gametic = 0;
326:
327: if ( skill == sk_nightmare )
328: {
329: states[S_SARG_ATK1].tics = 2;
330: states[S_SARG_ATK2].tics = 2;
331: states[S_SARG_ATK3].tics = 2;
332: mobjinfo[MT_SERGEANT].speed = 15;
333: mobjinfo[MT_SHADOWS].speed = 15;
334:
335: mobjinfo[MT_BRUISERSHOT].speed = 40*FRACUNIT;
336: mobjinfo[MT_HEADSHOT].speed = 40*FRACUNIT;
337: mobjinfo[MT_TROOPSHOT].speed = 40*FRACUNIT;
338: }
339: else
340: {
341: states[S_SARG_ATK1].tics = 4;
342: states[S_SARG_ATK2].tics = 4;
343: states[S_SARG_ATK3].tics = 4;
344: mobjinfo[MT_SERGEANT].speed = 10;
345: mobjinfo[MT_SHADOWS].speed = 10;
346:
347: mobjinfo[MT_BRUISERSHOT].speed = 30*FRACUNIT;
348: mobjinfo[MT_HEADSHOT].speed = 20*FRACUNIT;
349: mobjinfo[MT_TROOPSHOT].speed = 20*FRACUNIT;
350: }
351: }
352:
353: /*============================================================================ */
354:
355: /*
356: =================
357: =
358: = G_RunGame
359: =
360: = The game should allready have been initialized or laoded
361: =================
362: */
363:
364: void G_RunGame (void)
365: {
366: int i;
367:
368: while (1)
369: {
370: /* load a level */
371: G_DoLoadLevel ();
372:
373: /* run a level until death or completion */
374: MiniLoop (P_Start, P_Stop, P_Ticker, P_Drawer);
375:
376: /* take away cards and stuff */
377:
378: for (i=0 ; i<MAXPLAYERS ; i++)
379: if (playeringame[i])
380: G_PlayerFinishLevel (i);
381:
382: if (gameaction == ga_died)
383: continue; /* died, so restart the level */
384:
385: if (gameaction == ga_warped)
386: continue; /* skip intermission */
387:
388: /* decide which level to go to next */
389: #ifdef MARS
390: if (gameaction == ga_secretexit)
391: nextmap = 24;
392: else
393: {
394: switch (gamemap)
395: {
396: case 15: nextmap = 23; break;
397: case 24: nextmap = 4; break;
398: default: nextmap = gamemap+1; break;
399: }
400: }
401: #else
402: if (gameaction == ga_secretexit)
403: {
404: nextmap = 24;
405: }
406: else
407: {
408: switch (gamemap)
409: {
410: case 24: nextmap = 4; break;
411: case 23: nextmap = 23; break; /* don't add secret level to eeprom */
412: default: nextmap = gamemap+1; break;
413: }
414: #ifdef JAGUAR
415: if (nextmap > maxlevel)
416: { /* allow higher menu selection now */
417: void WriteEEProm (void);
418: maxlevel = nextmap;
419: WriteEEProm ();
420: }
421: #endif
422:
423: }
424: #endif
425:
426: /* run a stats intermission */
427: MiniLoop (IN_Start, IN_Stop, IN_Ticker, IN_Drawer);
428:
429: /* run the finale if needed */
430: if (gamemap == 23)
431: MiniLoop (F_Start, F_Stop, F_Ticker, F_Drawer);
432:
433: gamemap = nextmap;
434: }
435: }
436:
437:
438: int G_PlayDemoPtr (int *demo)
439: {
440: int exit;
441: int skill, map;
442:
443: demobuffer = demo;
444:
445: skill = *demo++;
446: map = *demo++;
447:
448: demo_p = demo;
449:
450: G_InitNew (skill, map, gt_single);
451: G_DoLoadLevel ();
452: demoplayback = true;
453: exit = MiniLoop (P_Start, P_Stop, P_Ticker, P_Drawer);
454: demoplayback = false;
455:
456: return exit;
457: }
458:
459: /*
460: =================
461: =
462: = G_RecordDemo
463: =
464: =================
465: */
466:
467: void G_RecordDemo (void)
468: {
469: demo_p = demobuffer = Z_Malloc (0x8000, PU_STATIC, NULL);
470:
471: *demo_p++ = startskill;
472: *demo_p++ = startmap;
473:
474: G_InitNew (startskill, startmap, gt_single);
475: G_DoLoadLevel ();
476: demorecording = true;
477: MiniLoop (P_Start, P_Stop, P_Ticker, P_Drawer);
478: demorecording = false;
479:
480: D_printf ("w %x,%x",demobuffer,demo_p);
481:
482: while (1)
483: {
484: G_PlayDemoPtr (demobuffer);
485: D_printf ("w %x,%x",demobuffer,demo_p);
486: }
487:
488: }
489:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.