|
|
1.1.1.2 root 1: 1.1.1.3 ! root 2: //************************************************************************** ! 3: //** ! 4: //** g_game.c : Heretic 2 : Raven Software, Corp. ! 5: //** ! 6: //** $RCSfile: g_game.c,v $ ! 7: //** $Revision: 1.68 $ ! 8: //** $Date: 96/01/12 13:18:07 $ ! 9: //** $Author: bgokey $ ! 10: //** ! 11: //************************************************************************** 1.1.1.2 root 12: 13: #include <string.h> 1.1.1.3 ! root 14: #include "h2def.h" ! 15: #include "p_local.h" 1.1.1.2 root 16: #include "soundst.h" 17: 1.1.1.3 ! root 18: #define AM_STARTKEY 9 1.1.1.2 root 19: 1.1.1.3 ! root 20: // External functions ! 21: ! 22: extern void R_InitSky(int map); ! 23: extern void P_PlayerNextArtifact(player_t *player); 1.1.1.2 root 24: 25: // Functions 26: 27: boolean G_CheckDemoStatus (void); 28: void G_ReadDemoTiccmd (ticcmd_t *cmd); 29: void G_WriteDemoTiccmd (ticcmd_t *cmd); 30: void G_InitNew (skill_t skill, int episode, int map); 31: 32: void G_DoReborn (int playernum); 33: 1.1.1.3 ! root 34: void G_DoLoadLevel(void); ! 35: void G_DoInitNew(void); ! 36: void G_DoNewGame(void); ! 37: void G_DoLoadGame(void); ! 38: void G_DoPlayDemo(void); ! 39: void G_DoTeleportNewMap(void); ! 40: void G_DoCompleted(void); ! 41: void G_DoVictory(void); ! 42: void G_DoWorldDone(void); ! 43: void G_DoSaveGame(void); ! 44: void G_DoSingleReborn(void); 1.1.1.2 root 45: 1.1.1.3 ! root 46: void H2_PageTicker(void); ! 47: void H2_AdvanceDemo(void); ! 48: ! 49: extern boolean mn_SuicideConsole; 1.1.1.2 root 50: 51: gameaction_t gameaction; 52: gamestate_t gamestate; 53: skill_t gameskill; 1.1.1.3 ! root 54: //boolean respawnmonsters; 1.1.1.2 root 55: int gameepisode; 56: int gamemap; 1.1.1.3 ! root 57: int prevmap; 1.1.1.2 root 58: 59: boolean paused; 60: boolean sendpause; // send a pause event next tic 61: boolean sendsave; // send a save event next tic 62: boolean usergame; // ok to save / end game 63: 64: boolean timingdemo; // if true, exit with report on completion 1.1.1.3 ! root 65: int starttime; // for comparative timing purposes 1.1.1.2 root 66: 67: boolean viewactive; 68: 69: boolean deathmatch; // only if started as net death 70: boolean netgame; // only true if packets are broadcast 71: boolean playeringame[MAXPLAYERS]; 72: player_t players[MAXPLAYERS]; 1.1.1.3 ! root 73: pclass_t PlayerClass[MAXPLAYERS]; ! 74: ! 75: // Position indicator for cooperative net-play reborn ! 76: int RebornPosition; 1.1.1.2 root 77: 78: int consoleplayer; // player taking events and displaying 79: int displayplayer; // view being displayed 80: int gametic; 81: int levelstarttic; // gametic at level start 82: 83: char demoname[32]; 84: boolean demorecording; 85: boolean demoplayback; 86: byte *demobuffer, *demo_p; 87: boolean singledemo; // quit after playing a demo from cmdline 88: 89: boolean precache = true; // if true, load all graphics at start 90: 91: short consistancy[MAXPLAYERS][BACKUPTICS]; 92: 93: // 94: // controls (have defaults) 95: // 1.1.1.3 ! root 96: int key_right, key_left, key_up, key_down; ! 97: int key_strafeleft, key_straferight, key_jump; ! 98: int key_fire, key_use, key_strafe, key_speed; ! 99: int key_flyup, key_flydown, key_flycenter; ! 100: int key_lookup, key_lookdown, key_lookcenter; ! 101: int key_invleft, key_invright, key_useartifact; ! 102: ! 103: int mousebfire; ! 104: int mousebstrafe; ! 105: int mousebforward; ! 106: int mousebjump; ! 107: ! 108: int joybfire; ! 109: int joybstrafe; ! 110: int joybuse; ! 111: int joybspeed; ! 112: int joybjump; ! 113: ! 114: int LeaveMap; ! 115: static int LeavePosition; ! 116: ! 117: //#define MAXPLMOVE 0x32 // Old Heretic Max move ! 118: ! 119: fixed_t MaxPlayerMove[NUMCLASSES] = { 0x3C, 0x32, 0x2D, 0x31 }; ! 120: fixed_t forwardmove[NUMCLASSES][2] = ! 121: { ! 122: { 0x1D, 0x3C }, ! 123: { 0x19, 0x32 }, ! 124: { 0x16, 0x2E }, ! 125: { 0x18, 0x31 } ! 126: }; ! 127: ! 128: fixed_t sidemove[NUMCLASSES][2] = ! 129: { ! 130: { 0x1B, 0x3B }, ! 131: { 0x18, 0x28 }, ! 132: { 0x15, 0x25 }, ! 133: { 0x17, 0x27 } ! 134: }; 1.1.1.2 root 135: 1.1.1.3 ! root 136: fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn 1.1.1.2 root 137: #define SLOWTURNTICS 6 138: 139: #define NUMKEYS 256 140: boolean gamekeydown[NUMKEYS]; 141: int turnheld; // for accelerative turning 1.1.1.3 ! root 142: int lookheld; 1.1.1.2 root 143: 144: 145: boolean mousearray[4]; 146: boolean *mousebuttons = &mousearray[1]; 147: // allow [-1] 148: int mousex, mousey; // mouse values are used once 149: int dclicktime, dclickstate, dclicks; 150: int dclicktime2, dclickstate2, dclicks2; 151: 152: int joyxmove, joyymove; // joystick values are repeated 153: boolean joyarray[5]; 154: boolean *joybuttons = &joyarray[1]; // allow [-1] 155: 156: int savegameslot; 157: char savedescription[32]; 158: 159: int inventoryTics; 160: 161: #ifdef __WATCOMC__ 162: extern externdata_t *i_ExternData; 163: #endif 164: 1.1.1.3 ! root 165: static skill_t TempSkill; ! 166: static int TempEpisode; ! 167: static int TempMap; 1.1.1.2 root 168: 1.1.1.3 ! root 169: //============================================================================= 1.1.1.2 root 170: /* 171: ==================== 172: = 173: = G_BuildTiccmd 174: = 175: = Builds a ticcmd from all of the available inputs or reads it from the 176: = demo buffer. 177: = If recording a demo, write it out 178: ==================== 179: */ 1.1 root 180: 1.1.1.2 root 181: extern boolean inventory; 182: extern int curpos; 183: extern int inv_ptr; 184: 185: extern int isCyberPresent; // is CyberMan present? 186: boolean usearti = true; 187: void I_ReadCyberCmd (ticcmd_t *cmd); 188: 189: void G_BuildTiccmd (ticcmd_t *cmd) 1.1 root 190: { 1.1.1.2 root 191: int i; 192: boolean strafe, bstrafe; 193: int speed, tspeed, lspeed; 194: int forward, side; 195: int look, arti; 196: int flyheight; 1.1.1.3 ! root 197: int pClass; 1.1.1.2 root 198: 1.1.1.3 ! root 199: extern boolean artiskip; 1.1.1.2 root 200: 201: #ifdef __WATCOMC__ 202: int angleDelta; 203: static int oldAngle; 204: extern int newViewAngleOff; 205: static int externInvKey; 206: extern boolean automapactive; 207: event_t ev; 208: #endif 209: 1.1.1.3 ! root 210: pClass = players[consoleplayer].class; 1.1.1.2 root 211: memset (cmd,0,sizeof(*cmd)); 1.1.1.3 ! root 212: ! 213: // cmd->consistancy = ! 214: // consistancy[consoleplayer][(maketic*ticdup)%BACKUPTICS]; ! 215: 1.1.1.2 root 216: cmd->consistancy = 217: consistancy[consoleplayer][maketic%BACKUPTICS]; 218: if (isCyberPresent) 219: I_ReadCyberCmd (cmd); 220: 221: //printf ("cons: %i\n",cmd->consistancy); 1.1.1.3 ! root 222: 1.1.1.2 root 223: strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe] 224: || joybuttons[joybstrafe]; 225: speed = gamekeydown[key_speed] || joybuttons[joybspeed] 226: || joybuttons[joybspeed]; 227: #ifdef __WATCOMC__ 228: if(useexterndriver) 229: { 230: speed |= (i_ExternData->buttons&EBT_SPEED); 231: strafe |= (i_ExternData->buttons&EBT_STRAFE); 232: } 233: #endif 234: 235: forward = side = look = arti = flyheight = 0; 1.1.1.3 ! root 236: 1.1.1.2 root 237: // 238: // use two stage accelerative turning on the keyboard and joystick 239: // 1.1.1.3 ! root 240: if (joyxmove < 0 || joyxmove > 0 1.1.1.2 root 241: || gamekeydown[key_right] || gamekeydown[key_left]) 242: turnheld += ticdup; 1.1 root 243: else 1.1.1.2 root 244: turnheld = 0; 245: if (turnheld < SLOWTURNTICS) 246: tspeed = 2; // slow turn 247: else 248: tspeed = speed; 1.1 root 249: 1.1.1.2 root 250: if(gamekeydown[key_lookdown] || gamekeydown[key_lookup]) 251: { 252: lookheld += ticdup; 253: } 254: else 255: { 256: lookheld = 0; 257: } 258: if(lookheld < SLOWTURNTICS) 259: { 1.1.1.3 ! root 260: lspeed = 1; // 3; 1.1.1.2 root 261: } 262: else 263: { 1.1.1.3 ! root 264: lspeed = 2; // 5; 1.1.1.2 root 265: } 266: 267: // 268: // let movement keys cancel each other out 269: // 270: if(strafe) 271: { 272: if (gamekeydown[key_right]) 1.1.1.3 ! root 273: { ! 274: side += sidemove[pClass][speed]; ! 275: } 1.1.1.2 root 276: if (gamekeydown[key_left]) 1.1.1.3 ! root 277: { ! 278: side -= sidemove[pClass][speed]; ! 279: } 1.1.1.2 root 280: if (joyxmove > 0) 1.1.1.3 ! root 281: { ! 282: side += sidemove[pClass][speed]; ! 283: } 1.1.1.2 root 284: if (joyxmove < 0) 1.1.1.3 ! root 285: { ! 286: side -= sidemove[pClass][speed]; ! 287: } 1.1.1.2 root 288: } 289: else 290: { 291: if (gamekeydown[key_right]) 292: cmd->angleturn -= angleturn[tspeed]; 293: if (gamekeydown[key_left]) 294: cmd->angleturn += angleturn[tspeed]; 295: if (joyxmove > 0) 296: cmd->angleturn -= angleturn[tspeed]; 297: if (joyxmove < 0) 298: cmd->angleturn += angleturn[tspeed]; 299: } 1.1 root 300: 1.1.1.2 root 301: if (gamekeydown[key_up]) 1.1.1.3 ! root 302: { ! 303: forward += forwardmove[pClass][speed]; ! 304: } 1.1.1.2 root 305: if (gamekeydown[key_down]) 1.1.1.3 ! root 306: { ! 307: forward -= forwardmove[pClass][speed]; ! 308: } 1.1.1.2 root 309: if (joyymove < 0) 1.1.1.3 ! root 310: { ! 311: forward += forwardmove[pClass][speed]; ! 312: } 1.1.1.2 root 313: if (joyymove > 0) 1.1.1.3 ! root 314: { ! 315: forward -= forwardmove[pClass][speed]; ! 316: } 1.1.1.2 root 317: if (gamekeydown[key_straferight]) 1.1.1.3 ! root 318: { ! 319: side += sidemove[pClass][speed]; ! 320: } 1.1.1.2 root 321: if (gamekeydown[key_strafeleft]) 1.1.1.3 ! root 322: { ! 323: side -= sidemove[pClass][speed]; ! 324: } 1.1 root 325: 1.1.1.2 root 326: // Look up/down/center keys 327: if(gamekeydown[key_lookup]) 328: { 329: look = lspeed; 330: } 331: if(gamekeydown[key_lookdown]) 332: { 333: look = -lspeed; 334: } 335: #ifdef __WATCOMC__ 336: if(gamekeydown[key_lookcenter] && !useexterndriver) 337: { 338: look = TOCENTER; 339: } 340: #else 341: if(gamekeydown[key_lookcenter]) 342: { 343: look = TOCENTER; 344: } 345: #endif 346: 347: #ifdef __WATCOMC__ 348: if(useexterndriver && look != TOCENTER && (gamestate == GS_LEVEL || 349: gamestate == GS_INTERMISSION)) 350: { 351: if(i_ExternData->moveForward) 1.1 root 352: { 1.1.1.2 root 353: forward += i_ExternData->moveForward; 354: if(speed) 1.1 root 355: { 1.1.1.2 root 356: forward <<= 1; 1.1 root 357: } 358: } 1.1.1.2 root 359: if(i_ExternData->angleTurn) 360: { 361: if(strafe) 362: { 363: side += i_ExternData->angleTurn; 364: } 365: else 366: { 367: cmd->angleturn += i_ExternData->angleTurn; 368: } 369: } 370: if(i_ExternData->moveSideways) 371: { 372: side += i_ExternData->moveSideways; 373: if(speed) 374: { 375: side <<= 1; 376: } 377: } 378: if(i_ExternData->buttons&EBT_CENTERVIEW) 1.1 root 379: { 1.1.1.2 root 380: look = TOCENTER; 381: oldAngle = 0; 1.1 root 382: } 1.1.1.2 root 383: else if(i_ExternData->pitch) 384: { 385: angleDelta = i_ExternData->pitch-oldAngle; 386: if(abs(angleDelta) < 35) 387: { 388: look = angleDelta/5; 389: } 390: else 391: { 392: look = 7*(angleDelta > 0 ? 1 : -1); 393: } 394: if(look == TOCENTER) 395: { 396: look++; 397: } 398: oldAngle += look*5; 399: } 400: if(i_ExternData->flyDirection) 401: { 402: if(i_ExternData->flyDirection > 0) 403: { 404: flyheight = 5; 405: } 406: else 407: { 408: flyheight = -5; 409: } 410: } 411: if(abs(newViewAngleOff-i_ExternData->angleHead) < 3000) 412: { 413: newViewAngleOff = i_ExternData->angleHead; 414: } 415: if(i_ExternData->buttons&EBT_FIRE) 1.1 root 416: { 1.1.1.2 root 417: cmd->buttons |= BT_ATTACK; 418: } 419: if(i_ExternData->buttons&EBT_OPENDOOR) 420: { 421: cmd->buttons |= BT_USE; 422: } 423: if(i_ExternData->buttons&EBT_PAUSE) 424: { 1.1.1.3 ! root 425: cmd->buttons = BT_SPECIAL|BTS_PAUSE; 1.1.1.2 root 426: i_ExternData->buttons &= ~EBT_PAUSE; 427: } 428: if(externInvKey&EBT_USEARTIFACT) 429: { 430: ev.type = ev_keyup; 431: ev.data1 = key_useartifact; 1.1.1.3 ! root 432: H2_PostEvent(&ev); 1.1.1.2 root 433: externInvKey &= ~EBT_USEARTIFACT; 434: } 435: else if(i_ExternData->buttons&EBT_USEARTIFACT) 436: { 437: externInvKey |= EBT_USEARTIFACT; 438: ev.type = ev_keydown; 439: ev.data1 = key_useartifact; 1.1.1.3 ! root 440: H2_PostEvent(&ev); 1.1.1.2 root 441: } 442: if(externInvKey&EBT_INVENTORYRIGHT) 443: { 444: ev.type = ev_keyup; 445: ev.data1 = key_invright; 1.1.1.3 ! root 446: H2_PostEvent(&ev); 1.1.1.2 root 447: externInvKey &= ~EBT_INVENTORYRIGHT; 448: } 449: else if(i_ExternData->buttons&EBT_INVENTORYRIGHT) 450: { 451: externInvKey |= EBT_INVENTORYRIGHT; 452: ev.type = ev_keydown; 453: ev.data1 = key_invright; 1.1.1.3 ! root 454: H2_PostEvent(&ev); 1.1.1.2 root 455: } 456: if(externInvKey&EBT_INVENTORYLEFT) 457: { 458: ev.type = ev_keyup; 459: ev.data1 = key_invleft; 1.1.1.3 ! root 460: H2_PostEvent(&ev); 1.1.1.2 root 461: externInvKey &= ~EBT_INVENTORYLEFT; 462: } 463: else if(i_ExternData->buttons&EBT_INVENTORYLEFT) 464: { 465: externInvKey |= EBT_INVENTORYLEFT; 466: ev.type = ev_keydown; 467: ev.data1 = key_invleft; 1.1.1.3 ! root 468: H2_PostEvent(&ev); 1.1.1.2 root 469: } 470: if(i_ExternData->buttons&EBT_FLYDROP) 471: { 472: flyheight = TOCENTER; 473: } 474: if(gamestate == GS_LEVEL) 475: { 476: if(externInvKey&EBT_MAP) 1.1.1.3 ! root 477: { // automap 1.1.1.2 root 478: ev.type = ev_keyup; 479: ev.data1 = AM_STARTKEY; 1.1.1.3 ! root 480: H2_PostEvent(&ev); 1.1.1.2 root 481: externInvKey &= ~EBT_MAP; 482: } 483: else if(i_ExternData->buttons&EBT_MAP) 484: { 485: externInvKey |= EBT_MAP; 486: ev.type = ev_keydown; 487: ev.data1 = AM_STARTKEY; 1.1.1.3 ! root 488: H2_PostEvent(&ev); 1.1.1.2 root 489: } 490: } 491: if(i_ExternData->buttons&EBT_WEAPONCYCLE) 492: { 493: int curWeapon; 494: player_t *pl; 1.1.1.3 ! root 495: 1.1.1.2 root 496: pl = &players[consoleplayer]; 497: curWeapon = pl->readyweapon; 1.1.1.3 ! root 498: for(curWeapon = (curWeapon+1)&3; curWeapon != pl->readyweapon; ! 499: curWeapon = (curWeapon+1)&3) 1.1 root 500: { 1.1.1.2 root 501: if(pl->weaponowned[curWeapon]) 502: { 1.1.1.3 ! root 503: cmd->buttons |= BT_CHANGE; ! 504: cmd->buttons |= curWeapon<<BT_WEAPONSHIFT; 1.1.1.2 root 505: break; 506: } 1.1 root 507: } 1.1.1.3 ! root 508: } ! 509: if(i_ExternData->buttons&EBT_JUMP) ! 510: { ! 511: cmd->arti |= AFLAG_JUMP; 1.1.1.2 root 512: } 513: } 1.1 root 514: #endif 515: 1.1.1.2 root 516: // Fly up/down/drop keys 517: if(gamekeydown[key_flyup]) 518: { 519: flyheight = 5; // note that the actual flyheight will be twice this 520: } 521: if(gamekeydown[key_flydown]) 522: { 523: flyheight = -5; 524: } 525: if(gamekeydown[key_flycenter]) 526: { 527: flyheight = TOCENTER; 528: #ifdef __WATCOMC__ 529: if(!useexterndriver) 530: { 531: look = TOCENTER; 1.1 root 532: } 1.1.1.2 root 533: #else 534: look = TOCENTER; 1.1 root 535: #endif 1.1.1.2 root 536: } 537: // Use artifact key 538: if(gamekeydown[key_useartifact]) 539: { 1.1.1.3 ! root 540: if(gamekeydown[key_speed] && artiskip) 1.1.1.2 root 541: { 542: if(players[consoleplayer].inventory[inv_ptr].type != arti_none) 1.1.1.3 ! root 543: { // Skip an artifact 1.1.1.2 root 544: gamekeydown[key_useartifact] = false; 1.1.1.3 ! root 545: P_PlayerNextArtifact(&players[consoleplayer]); 1.1.1.2 root 546: } 547: } 548: else 549: { 550: if(inventory) 551: { 552: players[consoleplayer].readyArtifact = 553: players[consoleplayer].inventory[inv_ptr].type; 554: inventory = false; 555: cmd->arti = 0; 556: usearti = false; 557: } 558: else if(usearti) 559: { 1.1.1.3 ! root 560: cmd->arti |= ! 561: players[consoleplayer].inventory[inv_ptr].type&AFLAG_MASK; 1.1.1.2 root 562: usearti = false; 563: } 564: } 565: } 1.1.1.3 ! root 566: if(gamekeydown[key_jump] || mousebuttons[mousebjump] ! 567: || joybuttons[joybjump]) 1.1.1.2 root 568: { 1.1.1.3 ! root 569: cmd->arti |= AFLAG_JUMP; ! 570: } ! 571: if(mn_SuicideConsole) ! 572: { ! 573: cmd->arti |= AFLAG_SUICIDE; ! 574: mn_SuicideConsole = false; ! 575: } ! 576: ! 577: // Artifact hot keys ! 578: if(gamekeydown[KEY_BACKSPACE] && !cmd->arti) ! 579: { ! 580: gamekeydown[KEY_BACKSPACE] = false; // Use one of each artifact ! 581: cmd->arti = NUMARTIFACTS; ! 582: } ! 583: else if(gamekeydown[KEY_BACKSLASH] && !cmd->arti ! 584: && (players[consoleplayer].mo->health < MAXHEALTH)) ! 585: { ! 586: gamekeydown[KEY_BACKSLASH] = false; ! 587: cmd->arti = arti_health; ! 588: } ! 589: else if(gamekeydown[KEY_ZERO] && !cmd->arti) ! 590: { ! 591: gamekeydown[KEY_ZERO] = false; ! 592: cmd->arti = arti_poisonbag; ! 593: } ! 594: else if(gamekeydown[KEY_NINE] && !cmd->arti) ! 595: { ! 596: gamekeydown[KEY_NINE] = false; ! 597: cmd->arti = arti_blastradius; ! 598: } ! 599: else if(gamekeydown[KEY_EIGHT] && !cmd->arti) ! 600: { ! 601: gamekeydown[KEY_EIGHT] = false; ! 602: cmd->arti = arti_teleport; ! 603: } ! 604: else if(gamekeydown[KEY_SEVEN] && !cmd->arti) ! 605: { ! 606: gamekeydown[KEY_SEVEN] = false; ! 607: cmd->arti = arti_teleportother; ! 608: } ! 609: else if(gamekeydown[KEY_SIX] && !cmd->arti) ! 610: { ! 611: gamekeydown[KEY_SIX] = false; ! 612: cmd->arti = arti_egg; ! 613: } ! 614: else if(gamekeydown[KEY_FIVE] && !cmd->arti ! 615: && !players[consoleplayer].powers[pw_invulnerability]) ! 616: { ! 617: gamekeydown[KEY_FIVE] = false; ! 618: cmd->arti = arti_invulnerability; 1.1.1.2 root 619: } 620: 621: // 622: // buttons 623: // 624: cmd->chatchar = CT_dequeueChatChar(); 625: 626: if (gamekeydown[key_fire] || mousebuttons[mousebfire] 627: || joybuttons[joybfire]) 628: cmd->buttons |= BT_ATTACK; 629: 630: if (gamekeydown[key_use] || joybuttons[joybuse] ) 631: { 632: cmd->buttons |= BT_USE; 633: dclicks = 0; // clear double clicks if hit use button 634: } 1.1.1.3 ! root 635: ! 636: for(i = 0; i < NUMWEAPONS; i++) 1.1.1.2 root 637: { 638: if(gamekeydown['1'+i]) 639: { 640: cmd->buttons |= BT_CHANGE; 641: cmd->buttons |= i<<BT_WEAPONSHIFT; 642: break; 643: } 644: } 645: 646: // 647: // mouse 648: // 649: if (mousebuttons[mousebforward]) 650: { 1.1.1.3 ! root 651: forward += forwardmove[pClass][speed]; 1.1.1.2 root 652: } 1.1.1.3 ! root 653: 1.1.1.2 root 654: // 655: // forward double click 656: // 657: if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 ) 658: { 659: dclickstate = mousebuttons[mousebforward]; 660: if (dclickstate) 661: dclicks++; 662: if (dclicks == 2) 663: { 664: cmd->buttons |= BT_USE; 665: dclicks = 0; 666: } 667: else 668: dclicktime = 0; 669: } 670: else 671: { 672: dclicktime += ticdup; 673: if (dclicktime > 20) 674: { 675: dclicks = 0; 676: dclickstate = 0; 677: } 678: } 1.1.1.3 ! root 679: 1.1.1.2 root 680: // 681: // strafe double click 682: // 683: bstrafe = mousebuttons[mousebstrafe] 684: || joybuttons[joybstrafe]; 685: if (bstrafe != dclickstate2 && dclicktime2 > 1 ) 686: { 687: dclickstate2 = bstrafe; 688: if (dclickstate2) 689: dclicks2++; 690: if (dclicks2 == 2) 691: { 692: cmd->buttons |= BT_USE; 693: dclicks2 = 0; 694: } 695: else 696: dclicktime2 = 0; 697: } 698: else 699: { 700: dclicktime2 += ticdup; 701: if (dclicktime2 > 20) 702: { 703: dclicks2 = 0; 704: dclickstate2 = 0; 705: } 706: } 707: 708: if (strafe) 709: { 710: side += mousex*2; 711: } 712: else 713: { 714: cmd->angleturn -= mousex*0x8; 1.1.1.3 ! root 715: } 1.1.1.2 root 716: forward += mousey; 717: mousex = mousey = 0; 1.1.1.3 ! root 718: ! 719: if (forward > MaxPlayerMove[pClass]) ! 720: { ! 721: forward = MaxPlayerMove[pClass]; ! 722: } ! 723: else if (forward < -MaxPlayerMove[pClass]) ! 724: { ! 725: forward = -MaxPlayerMove[pClass]; ! 726: } ! 727: if (side > MaxPlayerMove[pClass]) ! 728: { ! 729: side = MaxPlayerMove[pClass]; ! 730: } ! 731: else if (side < -MaxPlayerMove[pClass]) ! 732: { ! 733: side = -MaxPlayerMove[pClass]; ! 734: } 1.1.1.2 root 735: 1.1.1.3 ! root 736: if(players[consoleplayer].powers[pw_speed] ! 737: && !players[consoleplayer].morphTics) ! 738: { // Adjust for a player with a speed artifact ! 739: forward = (3*forward)>>1; ! 740: side = (3*side)>>1; ! 741: } 1.1.1.2 root 742: cmd->forwardmove += forward; 743: cmd->sidemove += side; 744: if(players[consoleplayer].playerstate == PST_LIVE) 745: { 746: if(look < 0) 747: { 748: look += 16; 749: } 750: cmd->lookfly = look; 751: } 752: if(flyheight < 0) 753: { 754: flyheight += 16; 755: } 756: cmd->lookfly |= flyheight<<4; 757: 758: // 759: // special buttons 760: // 761: if (sendpause) 762: { 763: sendpause = false; 764: cmd->buttons = BT_SPECIAL | BTS_PAUSE; 765: } 1.1 root 766: 1.1.1.2 root 767: if (sendsave) 768: { 769: sendsave = false; 770: cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT); 1.1 root 771: } 772: } 773: 774: 1.1.1.2 root 775: /* 776: ============== 777: = 778: = G_DoLoadLevel 779: = 780: ============== 781: */ 782: 783: void G_DoLoadLevel (void) 784: { 785: int i; 1.1.1.3 ! root 786: ! 787: levelstarttic = gametic; // for time calculation 1.1.1.2 root 788: gamestate = GS_LEVEL; 789: for (i=0 ; i<MAXPLAYERS ; i++) 790: { 791: if (playeringame[i] && players[i].playerstate == PST_DEAD) 792: players[i].playerstate = PST_REBORN; 793: memset (players[i].frags,0,sizeof(players[i].frags)); 794: } 795: 1.1.1.3 ! root 796: SN_StopAllSequences(); ! 797: P_SetupLevel (gameepisode, gamemap, 0, gameskill); ! 798: displayplayer = consoleplayer; // view the guy you are playing 1.1.1.2 root 799: starttime = I_GetTime (); 800: gameaction = ga_nothing; 801: Z_CheckHeap (); 802: 803: // 804: // clear cmd building stuff 1.1.1.3 ! root 805: // 1.1.1.2 root 806: 807: memset (gamekeydown, 0, sizeof(gamekeydown)); 808: joyxmove = joyymove = 0; 809: mousex = mousey = 0; 810: sendpause = sendsave = paused = false; 811: memset (mousebuttons, 0, sizeof(mousebuttons)); 812: memset (joybuttons, 0, sizeof(joybuttons)); 1.1 root 813: } 814: 1.1.1.2 root 815: 1.1 root 816: /* 1.1.1.2 root 817: =============================================================================== 1.1 root 818: = 1.1.1.3 ! root 819: = G_Responder 1.1.1.2 root 820: = 821: = get info needed to make ticcmd_ts for the players 1.1 root 822: = 1.1.1.2 root 823: =============================================================================== 1.1 root 824: */ 825: 1.1.1.2 root 826: boolean G_Responder(event_t *ev) 1.1 root 827: { 1.1.1.2 root 828: player_t *plr; 829: extern boolean MenuActive; 830: 831: plr = &players[consoleplayer]; 832: if(ev->type == ev_keyup && ev->data1 == key_useartifact) 833: { // flag to denote that it's okay to use an artifact 834: if(!inventory) 835: { 836: plr->readyArtifact = plr->inventory[inv_ptr].type; 837: } 838: usearti = true; 839: } 840: 841: // Check for spy mode player cycle 842: if(gamestate == GS_LEVEL && ev->type == ev_keydown 843: && ev->data1 == KEY_F12 && !deathmatch) 844: { // Cycle the display player 845: do 846: { 847: displayplayer++; 848: if(displayplayer == MAXPLAYERS) 849: { 850: displayplayer = 0; 851: } 852: } while(!playeringame[displayplayer] 853: && displayplayer != consoleplayer); 854: return(true); 855: } 856: 1.1.1.3 ! root 857: if(CT_Responder(ev)) ! 858: { // Chat ate the event ! 859: return(true); ! 860: } 1.1.1.2 root 861: if(gamestate == GS_LEVEL) 862: { 863: if(SB_Responder(ev)) 864: { // Status bar ate the event 865: return(true); 866: } 867: if(AM_Responder(ev)) 868: { // Automap ate the event 869: return(true); 870: } 871: } 872: 873: switch(ev->type) 1.1 root 874: { 1.1.1.2 root 875: case ev_keydown: 876: if(ev->data1 == key_invleft) 877: { 878: inventoryTics = 5*35; 879: if(!inventory) 880: { 881: inventory = true; 882: break; 883: } 884: inv_ptr--; 885: if(inv_ptr < 0) 886: { 887: inv_ptr = 0; 888: } 889: else 890: { 891: curpos--; 892: if(curpos < 0) 893: { 894: curpos = 0; 895: } 896: } 897: return(true); 898: } 899: if(ev->data1 == key_invright) 900: { 901: inventoryTics = 5*35; 902: if(!inventory) 903: { 904: inventory = true; 905: break; 906: } 907: inv_ptr++; 908: if(inv_ptr >= plr->inventorySlotNum) 909: { 910: inv_ptr--; 911: if(inv_ptr < 0) 912: inv_ptr = 0; 913: } 914: else 915: { 916: curpos++; 917: if(curpos > 6) 918: { 919: curpos = 6; 920: } 921: } 922: return(true); 923: } 924: if(ev->data1 == KEY_PAUSE && !MenuActive) 925: { 926: sendpause = true; 927: return(true); 928: } 929: if(ev->data1 < NUMKEYS) 930: { 931: gamekeydown[ev->data1] = true; 932: } 933: return(true); // eat key down events 934: 935: case ev_keyup: 936: if(ev->data1 < NUMKEYS) 937: { 938: gamekeydown[ev->data1] = false; 939: } 940: return(false); // always let key up events filter down 941: 942: case ev_mouse: 943: mousebuttons[0] = ev->data1&1; 944: mousebuttons[1] = ev->data1&2; 945: mousebuttons[2] = ev->data1&4; 946: mousex = ev->data2*(mouseSensitivity+5)/10; 947: mousey = ev->data3*(mouseSensitivity+5)/10; 948: return(true); // eat events 949: 950: case ev_joystick: 951: joybuttons[0] = ev->data1&1; 952: joybuttons[1] = ev->data1&2; 953: joybuttons[2] = ev->data1&4; 954: joybuttons[3] = ev->data1&8; 955: joyxmove = ev->data2; 956: joyymove = ev->data3; 957: return(true); // eat events 958: 959: default: 960: break; 1.1 root 961: } 1.1.1.2 root 962: return(false); 1.1 root 963: } 964: 1.1.1.2 root 965: 1.1.1.3 ! root 966: //========================================================================== ! 967: // ! 968: // G_Ticker ! 969: // ! 970: //========================================================================== ! 971: ! 972: void G_Ticker(void) 1.1.1.2 root 973: { 1.1.1.3 ! root 974: int i, buf; ! 975: ticcmd_t *cmd=NULL; 1.1.1.2 root 976: 977: // 978: // do player reborns if needed 979: // 980: for (i=0 ; i<MAXPLAYERS ; i++) 981: if (playeringame[i] && players[i].playerstate == PST_REBORN) 982: G_DoReborn (i); 983: 984: // 985: // do things to change the game state 986: // 987: while (gameaction != ga_nothing) 988: { 989: switch (gameaction) 990: { 1.1.1.3 ! root 991: case ga_loadlevel: ! 992: G_DoLoadLevel(); ! 993: break; ! 994: case ga_initnew: ! 995: G_DoInitNew(); ! 996: break; ! 997: case ga_newgame: ! 998: G_DoNewGame(); ! 999: break; ! 1000: case ga_loadgame: ! 1001: Draw_LoadIcon(); ! 1002: G_DoLoadGame(); ! 1003: break; ! 1004: case ga_savegame: ! 1005: Draw_SaveIcon(); ! 1006: G_DoSaveGame(); ! 1007: break; ! 1008: case ga_singlereborn: ! 1009: G_DoSingleReborn(); ! 1010: break; ! 1011: case ga_playdemo: ! 1012: G_DoPlayDemo(); ! 1013: break; ! 1014: case ga_screenshot: ! 1015: M_ScreenShot(); ! 1016: gameaction = ga_nothing; ! 1017: break; ! 1018: case ga_leavemap: ! 1019: Draw_TeleportIcon(); ! 1020: G_DoTeleportNewMap(); ! 1021: break; ! 1022: case ga_completed: ! 1023: G_DoCompleted(); ! 1024: break; ! 1025: case ga_worlddone: ! 1026: G_DoWorldDone(); ! 1027: break; ! 1028: case ga_victory: ! 1029: F_StartFinale(); ! 1030: break; ! 1031: default: ! 1032: break; 1.1.1.2 root 1033: } 1034: } 1.1.1.3 ! root 1035: ! 1036: 1.1.1.2 root 1037: // 1038: // get commands, check consistancy, and build new consistancy check 1039: // 1040: //buf = gametic%BACKUPTICS; 1.1.1.3 ! root 1041: ! 1042: 1.1.1.2 root 1043: buf = (gametic/ticdup)%BACKUPTICS; 1044: 1045: for (i=0 ; i<MAXPLAYERS ; i++) 1046: if (playeringame[i]) 1047: { 1048: cmd = &players[i].cmd; 1049: 1050: memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t)); 1051: 1052: if (demoplayback) 1053: G_ReadDemoTiccmd (cmd); 1054: if (demorecording) 1055: G_WriteDemoTiccmd (cmd); 1056: 1057: if (netgame && !(gametic%ticdup) ) 1058: { 1059: if (gametic > BACKUPTICS 1060: && consistancy[i][buf] != cmd->consistancy) 1061: { 1062: I_Error ("consistency failure (%i should be %i)",cmd->consistancy, consistancy[i][buf]); 1063: } 1064: if (players[i].mo) 1065: consistancy[i][buf] = players[i].mo->x; 1066: else 1067: consistancy[i][buf] = rndindex; 1068: } 1069: } 1070: 1071: // 1072: // check for special buttons 1073: // 1074: for (i=0 ; i<MAXPLAYERS ; i++) 1075: if (playeringame[i]) 1076: { 1077: if (players[i].cmd.buttons & BT_SPECIAL) 1078: { 1079: switch (players[i].cmd.buttons & BT_SPECIALMASK) 1080: { 1081: case BTS_PAUSE: 1082: paused ^= 1; 1083: if(paused) 1084: { 1085: S_PauseSound(); 1086: } 1087: else 1088: { 1089: S_ResumeSound(); 1090: } 1091: break; 1.1.1.3 ! root 1092: 1.1.1.2 root 1093: case BTS_SAVEGAME: 1094: if (!savedescription[0]) 1095: { 1096: if(netgame) 1097: { 1098: strcpy (savedescription, "NET GAME"); 1099: } 1100: else 1101: { 1102: strcpy(savedescription, "SAVE GAME"); 1103: } 1104: } 1.1.1.3 ! root 1105: savegameslot = 1.1.1.2 root 1106: (players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT; 1107: gameaction = ga_savegame; 1108: break; 1109: } 1110: } 1111: } 1.1.1.3 ! root 1112: ! 1113: // turn inventory off after a certain amount of time 1.1.1.2 root 1114: if(inventory && !(--inventoryTics)) 1115: { 1116: players[consoleplayer].readyArtifact = 1117: players[consoleplayer].inventory[inv_ptr].type; 1118: inventory = false; 1119: cmd->arti = 0; 1120: } 1121: // 1122: // do main actions 1123: // 1124: // 1125: // do main actions 1126: // 1127: switch (gamestate) 1128: { 1129: case GS_LEVEL: 1130: P_Ticker (); 1131: SB_Ticker (); 1132: AM_Ticker (); 1133: CT_Ticker(); 1134: break; 1135: case GS_INTERMISSION: 1136: IN_Ticker (); 1137: break; 1138: case GS_FINALE: 1139: F_Ticker(); 1140: break; 1141: case GS_DEMOSCREEN: 1.1.1.3 ! root 1142: H2_PageTicker (); 1.1.1.2 root 1143: break; 1.1.1.3 ! root 1144: } 1.1.1.2 root 1145: } 1146: 1147: 1148: /* 1149: ============================================================================== 1150: 1151: PLAYER STRUCTURE FUNCTIONS 1152: 1153: also see P_SpawnPlayer in P_Things 1154: ============================================================================== 1155: */ 1156: 1.1.1.3 ! root 1157: //========================================================================== ! 1158: // ! 1159: // G_PlayerExitMap ! 1160: // ! 1161: // Called when the player leaves a map. ! 1162: // ! 1163: //========================================================================== 1.1.1.2 root 1164: 1.1.1.3 ! root 1165: void G_PlayerExitMap(int playerNumber) 1.1.1.2 root 1166: { 1.1.1.3 ! root 1167: int i; ! 1168: player_t *player; ! 1169: int flightPower; 1.1.1.2 root 1170: 1.1.1.3 ! root 1171: player = &players[playerNumber]; 1.1.1.2 root 1172: 1.1.1.3 ! root 1173: // if(deathmatch) ! 1174: // { ! 1175: // // Strip all but one of each type of artifact ! 1176: // for(i = 0; i < player->inventorySlotNum; i++) ! 1177: // { ! 1178: // player->inventory[i].count = 1; ! 1179: // } ! 1180: // player->artifactCount = player->inventorySlotNum; ! 1181: // } ! 1182: // else ! 1183: ! 1184: // Strip all current powers (retain flight) ! 1185: flightPower = player->powers[pw_flight]; ! 1186: memset(player->powers, 0, sizeof(player->powers)); ! 1187: player->powers[pw_flight] = flightPower; 1.1.1.2 root 1188: 1.1.1.3 ! root 1189: if(deathmatch) 1.1.1.2 root 1190: { 1.1.1.3 ! root 1191: player->powers[pw_flight] = 0; 1.1.1.2 root 1192: } 1.1.1.3 ! root 1193: else 1.1.1.2 root 1194: { 1.1.1.3 ! root 1195: if(P_GetMapCluster(gamemap) != P_GetMapCluster(LeaveMap)) ! 1196: { // Entering new cluster ! 1197: // Strip all keys ! 1198: player->keys = 0; ! 1199: ! 1200: // Strip flight artifact ! 1201: for(i = 0; i < 25; i++) ! 1202: { ! 1203: player->powers[pw_flight] = 0; ! 1204: P_PlayerUseArtifact(player, arti_fly); ! 1205: } ! 1206: player->powers[pw_flight] = 0; 1.1.1.2 root 1207: } 1208: } 1.1.1.3 ! root 1209: ! 1210: if(player->morphTics) 1.1.1.2 root 1211: { 1.1.1.3 ! root 1212: player->readyweapon = player->mo->special1; // Restore weapon ! 1213: player->morphTics = 0; 1.1.1.2 root 1214: } 1.1.1.3 ! root 1215: player->messageTics = 0; ! 1216: player->lookdir = 0; ! 1217: player->mo->flags &= ~MF_SHADOW; // Remove invisibility ! 1218: player->extralight = 0; // Remove weapon flashes ! 1219: player->fixedcolormap = 0; // Remove torch ! 1220: player->damagecount = 0; // No palette changes ! 1221: player->bonuscount = 0; ! 1222: player->poisoncount = 0; ! 1223: if(player == &players[consoleplayer]) 1.1.1.2 root 1224: { 1225: SB_state = -1; // refresh the status bar 1.1.1.3 ! root 1226: viewangleoffset = 0; 1.1.1.2 root 1227: } 1228: } 1229: 1.1.1.3 ! root 1230: //========================================================================== ! 1231: // ! 1232: // G_PlayerReborn ! 1233: // ! 1234: // Called after a player dies. Almost everything is cleared and ! 1235: // initialized. ! 1236: // ! 1237: //========================================================================== 1.1.1.2 root 1238: 1239: void G_PlayerReborn(int player) 1240: { 1241: player_t *p; 1242: int frags[MAXPLAYERS]; 1243: int killcount, itemcount, secretcount; 1.1.1.3 ! root 1244: uint worldTimer; 1.1.1.2 root 1245: 1246: memcpy(frags, players[player].frags, sizeof(frags)); 1247: killcount = players[player].killcount; 1248: itemcount = players[player].itemcount; 1249: secretcount = players[player].secretcount; 1.1.1.3 ! root 1250: worldTimer = players[player].worldTimer; 1.1.1.2 root 1251: 1252: p = &players[player]; 1253: memset(p, 0, sizeof(*p)); 1254: 1255: memcpy(players[player].frags, frags, sizeof(players[player].frags)); 1256: players[player].killcount = killcount; 1257: players[player].itemcount = itemcount; 1258: players[player].secretcount = secretcount; 1.1.1.3 ! root 1259: players[player].worldTimer = worldTimer; ! 1260: players[player].class = PlayerClass[player]; 1.1.1.2 root 1261: 1262: p->usedown = p->attackdown = true; // don't do anything immediately 1263: p->playerstate = PST_LIVE; 1264: p->health = MAXHEALTH; 1.1.1.3 ! root 1265: p->readyweapon = p->pendingweapon = WP_FIRST; ! 1266: p->weaponowned[WP_FIRST] = true; 1.1.1.2 root 1267: p->messageTics = 0; 1268: p->lookdir = 0; 1.1.1.3 ! root 1269: localQuakeHappening[player] = false; 1.1.1.2 root 1270: if(p == &players[consoleplayer]) 1271: { 1272: SB_state = -1; // refresh the status bar 1273: inv_ptr = 0; // reset the inventory pointer 1274: curpos = 0; 1.1.1.3 ! root 1275: viewangleoffset = 0; 1.1.1.2 root 1276: } 1277: } 1278: 1279: /* 1280: ==================== 1281: = 1.1.1.3 ! root 1282: = G_CheckSpot 1.1.1.2 root 1283: = 1.1.1.3 ! root 1284: = Returns false if the player cannot be respawned at the given mapthing_t spot 1.1.1.2 root 1285: = because something is occupying it 1286: ==================== 1287: */ 1288: 1289: void P_SpawnPlayer (mapthing_t *mthing); 1290: 1291: boolean G_CheckSpot (int playernum, mapthing_t *mthing) 1292: { 1293: fixed_t x,y; 1294: subsector_t *ss; 1295: unsigned an; 1296: mobj_t *mo; 1.1.1.3 ! root 1297: 1.1.1.2 root 1298: x = mthing->x << FRACBITS; 1299: y = mthing->y << FRACBITS; 1300: 1301: players[playernum].mo->flags2 &= ~MF2_PASSMOBJ; 1302: if (!P_CheckPosition (players[playernum].mo, x, y) ) 1303: { 1304: players[playernum].mo->flags2 |= MF2_PASSMOBJ; 1305: return false; 1306: } 1307: players[playernum].mo->flags2 |= MF2_PASSMOBJ; 1308: 1309: // spawn a teleport fog 1310: ss = R_PointInSubsector (x,y); 1311: an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT; 1312: 1.1.1.3 ! root 1313: mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an], ! 1314: ss->sector->floorheight+TELEFOGHEIGHT, MT_TFOG); 1.1.1.2 root 1315: 1316: if (players[consoleplayer].viewz != 1) 1.1.1.3 ! root 1317: S_StartSound (mo, SFX_TELEPORT); // don't start sound on first frame 1.1.1.2 root 1318: 1319: return true; 1320: } 1321: 1322: /* 1323: ==================== 1324: = 1325: = G_DeathMatchSpawnPlayer 1326: = 1327: = Spawns a player at one of the random death match spots 1328: = called at level load and each death 1329: ==================== 1330: */ 1331: 1332: void G_DeathMatchSpawnPlayer (int playernum) 1333: { 1334: int i,j; 1335: int selections; 1.1.1.3 ! root 1336: 1.1.1.2 root 1337: selections = deathmatch_p - deathmatchstarts; 1.1.1.3 ! root 1338: ! 1339: // This check has been moved to p_setup.c:P_LoadThings() ! 1340: //if (selections < 8) ! 1341: // I_Error ("Only %i deathmatch spots, 8 required", selections); 1.1.1.2 root 1342: 1343: for (j=0 ; j<20 ; j++) 1344: { 1345: i = P_Random() % selections; 1346: if (G_CheckSpot (playernum, &deathmatchstarts[i]) ) 1347: { 1348: deathmatchstarts[i].type = playernum+1; 1349: P_SpawnPlayer (&deathmatchstarts[i]); 1350: return; 1351: } 1352: } 1353: 1354: // no good spot, so the player will probably get stuck 1.1.1.3 ! root 1355: P_SpawnPlayer (&playerstarts[0][playernum]); 1.1.1.2 root 1356: } 1357: 1.1.1.3 ! root 1358: //========================================================================== ! 1359: // ! 1360: // G_DoReborn ! 1361: // ! 1362: //========================================================================== 1.1.1.2 root 1363: 1.1.1.3 ! root 1364: void G_DoReborn(int playernum) 1.1.1.2 root 1365: { 1.1.1.3 ! root 1366: int i; ! 1367: boolean oldWeaponowned[NUMWEAPONS]; ! 1368: int oldKeys; ! 1369: int oldPieces; ! 1370: boolean foundSpot; ! 1371: int bestWeapon; 1.1.1.2 root 1372: 1.1.1.3 ! root 1373: if(G_CheckDemoStatus()) ! 1374: { 1.1.1.2 root 1375: return; 1.1.1.3 ! root 1376: } ! 1377: if(!netgame) ! 1378: { ! 1379: if(SV_RebornSlotAvailable()) ! 1380: { // Use the reborn code if the slot is available ! 1381: gameaction = ga_singlereborn; ! 1382: } ! 1383: else ! 1384: { // Start a new game if there's no reborn info ! 1385: gameaction = ga_newgame; ! 1386: } ! 1387: } 1.1.1.2 root 1388: else 1.1.1.3 ! root 1389: { // Net-game ! 1390: players[playernum].mo->player = NULL; // Dissassociate the corpse 1.1.1.2 root 1391: 1.1.1.3 ! root 1392: if(deathmatch) ! 1393: { // Spawn at random spot if in death match ! 1394: G_DeathMatchSpawnPlayer(playernum); 1.1.1.2 root 1395: return; 1396: } 1397: 1.1.1.3 ! root 1398: // Cooperative net-play, retain keys and weapons ! 1399: oldKeys = players[playernum].keys; ! 1400: oldPieces = players[playernum].pieces; ! 1401: for(i = 0; i < NUMWEAPONS; i++) ! 1402: { ! 1403: oldWeaponowned[i] = players[playernum].weaponowned[i]; ! 1404: } ! 1405: ! 1406: foundSpot = false; ! 1407: if(G_CheckSpot(playernum, ! 1408: &playerstarts[RebornPosition][playernum])) ! 1409: { // Appropriate player start spot is open ! 1410: P_SpawnPlayer(&playerstarts[RebornPosition][playernum]); ! 1411: foundSpot = true; ! 1412: } ! 1413: else 1.1.1.2 root 1414: { 1.1.1.3 ! root 1415: // Try to spawn at one of the other player start spots ! 1416: for(i = 0; i < MAXPLAYERS; i++) ! 1417: { ! 1418: if(G_CheckSpot(playernum, &playerstarts[RebornPosition][i])) ! 1419: { // Found an open start spot ! 1420: ! 1421: // Fake as other player ! 1422: playerstarts[RebornPosition][i].type = playernum+1; ! 1423: P_SpawnPlayer(&playerstarts[RebornPosition][i]); ! 1424: ! 1425: // Restore proper player type ! 1426: playerstarts[RebornPosition][i].type = i+1; ! 1427: ! 1428: foundSpot = true; ! 1429: break; ! 1430: } ! 1431: } 1.1.1.2 root 1432: } 1.1.1.3 ! root 1433: ! 1434: if(foundSpot == false) ! 1435: { // Player's going to be inside something ! 1436: P_SpawnPlayer(&playerstarts[RebornPosition][playernum]); ! 1437: } ! 1438: ! 1439: // Restore keys and weapons ! 1440: players[playernum].keys = oldKeys; ! 1441: players[playernum].pieces = oldPieces; ! 1442: for(bestWeapon = 0, i = 0; i < NUMWEAPONS; i++) ! 1443: { ! 1444: if(oldWeaponowned[i]) ! 1445: { ! 1446: bestWeapon = i; ! 1447: players[playernum].weaponowned[i] = true; 1.1.1.2 root 1448: } 1.1.1.3 ! root 1449: } ! 1450: players[playernum].mana[MANA_1] = 25; ! 1451: players[playernum].mana[MANA_2] = 25; ! 1452: if(bestWeapon) ! 1453: { // Bring up the best weapon ! 1454: players[playernum].pendingweapon = bestWeapon; ! 1455: } 1.1.1.2 root 1456: } 1457: } 1458: 1459: void G_ScreenShot (void) 1460: { 1461: gameaction = ga_screenshot; 1462: } 1463: 1.1.1.3 ! root 1464: //========================================================================== ! 1465: // ! 1466: // G_StartNewInit ! 1467: // ! 1468: //========================================================================== 1.1.1.2 root 1469: 1.1.1.3 ! root 1470: void G_StartNewInit(void) ! 1471: { ! 1472: SV_InitBaseSlot(); ! 1473: SV_ClearRebornSlot(); ! 1474: P_ACSInitNewGame(); ! 1475: // Default the player start spot group to 0 ! 1476: RebornPosition = 0; ! 1477: } ! 1478: ! 1479: //========================================================================== ! 1480: // ! 1481: // G_StartNewGame ! 1482: // ! 1483: //========================================================================== ! 1484: ! 1485: void G_StartNewGame(skill_t skill) ! 1486: { ! 1487: int realMap; ! 1488: ! 1489: G_StartNewInit(); ! 1490: realMap = P_TranslateMap(1); ! 1491: if(realMap == -1) ! 1492: { ! 1493: realMap = 1; ! 1494: } ! 1495: G_InitNew(TempSkill, 1, realMap); ! 1496: } 1.1.1.2 root 1497: 1.1.1.3 ! root 1498: //========================================================================== ! 1499: // ! 1500: // G_TeleportNewMap ! 1501: // ! 1502: // Only called by the warp cheat code. Works just like normal map to map ! 1503: // teleporting, but doesn't do any interlude stuff. ! 1504: // ! 1505: //========================================================================== ! 1506: ! 1507: void G_TeleportNewMap(int map, int position) ! 1508: { ! 1509: gameaction = ga_leavemap; ! 1510: LeaveMap = map; ! 1511: LeavePosition = position; ! 1512: } ! 1513: ! 1514: //========================================================================== ! 1515: // ! 1516: // G_DoTeleportNewMap ! 1517: // ! 1518: //========================================================================== ! 1519: ! 1520: void G_DoTeleportNewMap(void) ! 1521: { ! 1522: SV_MapTeleport(LeaveMap, LeavePosition); ! 1523: gamestate = GS_LEVEL; ! 1524: gameaction = ga_nothing; ! 1525: RebornPosition = LeavePosition; ! 1526: } 1.1.1.2 root 1527: 1.1.1.3 ! root 1528: /* ! 1529: boolean secretexit; 1.1.1.2 root 1530: void G_ExitLevel (void) 1531: { 1532: secretexit = false; 1533: gameaction = ga_completed; 1534: } 1535: void G_SecretExitLevel (void) 1536: { 1537: secretexit = true; 1538: gameaction = ga_completed; 1539: } 1.1.1.3 ! root 1540: */ ! 1541: ! 1542: //========================================================================== ! 1543: // ! 1544: // G_Completed ! 1545: // ! 1546: // Starts intermission routine, which is used only during hub exits, ! 1547: // and DeathMatch games. ! 1548: //========================================================================== ! 1549: ! 1550: void G_Completed(int map, int position) ! 1551: { ! 1552: gameaction = ga_completed; ! 1553: LeaveMap = map; ! 1554: LeavePosition = position; ! 1555: } 1.1.1.2 root 1556: 1557: void G_DoCompleted(void) 1558: { 1559: int i; 1.1.1.3 ! root 1560: ! 1561: gameaction = ga_nothing; ! 1562: if(G_CheckDemoStatus()) ! 1563: { ! 1564: return; ! 1565: } ! 1566: for(i = 0; i < MAXPLAYERS; i++) ! 1567: { ! 1568: if(playeringame[i]) ! 1569: { ! 1570: G_PlayerExitMap(i); ! 1571: } ! 1572: } ! 1573: if(LeaveMap == -1 && LeavePosition == -1) ! 1574: { ! 1575: gameaction = ga_victory; ! 1576: return; ! 1577: } ! 1578: else ! 1579: { ! 1580: gamestate = GS_INTERMISSION; ! 1581: IN_Start(); ! 1582: } ! 1583: ! 1584: /* ! 1585: int i; ! 1586: static int afterSecret[3] = { 7, 5, 5 }; 1.1.1.2 root 1587: 1588: gameaction = ga_nothing; 1589: if(G_CheckDemoStatus()) 1590: { 1591: return; 1592: } 1593: for(i = 0; i < MAXPLAYERS; i++) 1594: { 1595: if(playeringame[i]) 1596: { 1597: G_PlayerFinishLevel(i); 1598: } 1599: } 1600: prevmap = gamemap; 1601: if(secretexit == true) 1602: { 1603: gamemap = 9; 1604: } 1605: else if(gamemap == 9) 1606: { // Finished secret level 1607: gamemap = afterSecret[gameepisode-1]; 1608: } 1609: else if(gamemap == 8) 1610: { 1611: gameaction = ga_victory; 1612: return; 1613: } 1614: else 1615: { 1616: gamemap++; 1617: } 1618: gamestate = GS_INTERMISSION; 1619: IN_Start(); 1.1.1.3 ! root 1620: */ 1.1.1.2 root 1621: } 1622: 1623: //============================================================================ 1624: // 1625: // G_WorldDone 1626: // 1627: //============================================================================ 1628: 1629: void G_WorldDone(void) 1630: { 1631: gameaction = ga_worlddone; 1632: } 1633: 1634: //============================================================================ 1635: // 1636: // G_DoWorldDone 1637: // 1638: //============================================================================ 1639: 1640: void G_DoWorldDone(void) 1641: { 1642: gamestate = GS_LEVEL; 1643: G_DoLoadLevel(); 1644: gameaction = ga_nothing; 1645: viewactive = true; 1646: } 1647: 1.1.1.3 ! root 1648: //========================================================================== ! 1649: // ! 1650: // G_DoSingleReborn ! 1651: // ! 1652: // Called by G_Ticker based on gameaction. Loads a game from the reborn ! 1653: // save slot. ! 1654: // ! 1655: //========================================================================== ! 1656: ! 1657: void G_DoSingleReborn(void) ! 1658: { ! 1659: gameaction = ga_nothing; ! 1660: SV_LoadGame(SV_GetRebornSlot()); ! 1661: SB_SetClassData(); ! 1662: } ! 1663: ! 1664: //========================================================================== 1.1.1.2 root 1665: // 1.1.1.3 ! root 1666: // G_LoadGame 1.1.1.2 root 1667: // 1668: // Can be called by the startup code or the menu task. 1669: // 1.1.1.3 ! root 1670: //========================================================================== 1.1.1.2 root 1671: 1.1.1.3 ! root 1672: static int GameLoadSlot; 1.1.1.2 root 1673: 1.1.1.3 ! root 1674: void G_LoadGame(int slot) 1.1.1.2 root 1675: { 1.1.1.3 ! root 1676: GameLoadSlot = slot; 1.1.1.2 root 1677: gameaction = ga_loadgame; 1678: } 1679: 1.1.1.3 ! root 1680: //========================================================================== 1.1.1.2 root 1681: // 1.1.1.3 ! root 1682: // G_DoLoadGame 1.1.1.2 root 1683: // 1684: // Called by G_Ticker based on gameaction. 1685: // 1.1.1.3 ! root 1686: //========================================================================== 1.1.1.2 root 1687: 1688: void G_DoLoadGame(void) 1689: { 1.1.1.3 ! root 1690: gameaction = ga_nothing; ! 1691: SV_LoadGame(GameLoadSlot); ! 1692: if(!netgame) ! 1693: { // Copy the base slot to the reborn slot ! 1694: SV_UpdateRebornSlot(); ! 1695: } ! 1696: SB_SetClassData(); ! 1697: } ! 1698: ! 1699: //========================================================================== ! 1700: // ! 1701: // G_SaveGame ! 1702: // ! 1703: // Called by the menu task. <description> is a 24 byte text string. ! 1704: // ! 1705: //========================================================================== ! 1706: ! 1707: void G_SaveGame(int slot, char *description) ! 1708: { ! 1709: savegameslot = slot; ! 1710: strcpy(savedescription, description); ! 1711: sendsave = true; ! 1712: } ! 1713: ! 1714: //========================================================================== ! 1715: // ! 1716: // G_DoSaveGame ! 1717: // ! 1718: // Called by G_Ticker based on gameaction. ! 1719: // ! 1720: //========================================================================== 1.1.1.2 root 1721: 1.1.1.3 ! root 1722: void G_DoSaveGame(void) ! 1723: { ! 1724: SV_SaveGame(savegameslot, savedescription); 1.1.1.2 root 1725: gameaction = ga_nothing; 1.1.1.3 ! root 1726: savedescription[0] = 0; ! 1727: P_SetMessage(&players[consoleplayer], TXT_GAMESAVED, true); ! 1728: } 1.1.1.2 root 1729: 1.1.1.3 ! root 1730: //========================================================================== ! 1731: // ! 1732: // G_DeferredNewGame ! 1733: // ! 1734: //========================================================================== 1.1.1.2 root 1735: 1.1.1.3 ! root 1736: void G_DeferredNewGame(skill_t skill) ! 1737: { ! 1738: TempSkill = skill; ! 1739: gameaction = ga_newgame; 1.1.1.2 root 1740: } 1741: 1.1.1.3 ! root 1742: //========================================================================== ! 1743: // ! 1744: // G_DoNewGame ! 1745: // ! 1746: //========================================================================== ! 1747: ! 1748: void G_DoNewGame(void) ! 1749: { ! 1750: G_StartNewGame(TempSkill); ! 1751: gameaction = ga_nothing; ! 1752: } 1.1.1.2 root 1753: 1754: /* 1755: ==================== 1756: = 1757: = G_InitNew 1758: = 1759: = Can be called by the startup code or the menu task 1760: = consoleplayer, displayplayer, playeringame[] should be set 1761: ==================== 1762: */ 1763: 1.1.1.3 ! root 1764: void G_DeferedInitNew(skill_t skill, int episode, int map) ! 1765: { ! 1766: TempSkill = skill; ! 1767: TempEpisode = episode; ! 1768: TempMap = map; ! 1769: gameaction = ga_initnew; 1.1.1.2 root 1770: } 1771: 1.1.1.3 ! root 1772: void G_DoInitNew(void) 1.1.1.2 root 1773: { 1.1.1.3 ! root 1774: SV_InitBaseSlot(); ! 1775: G_InitNew(TempSkill, TempEpisode, TempMap); 1.1.1.2 root 1776: gameaction = ga_nothing; 1777: } 1778: 1779: void G_InitNew(skill_t skill, int episode, int map) 1780: { 1781: int i; 1782: 1783: if(paused) 1784: { 1785: paused = false; 1786: S_ResumeSound(); 1787: } 1788: if(skill < sk_baby) 1.1.1.3 ! root 1789: { 1.1.1.2 root 1790: skill = sk_baby; 1.1.1.3 ! root 1791: } 1.1.1.2 root 1792: if(skill > sk_nightmare) 1793: { 1.1.1.3 ! root 1794: skill = sk_nightmare; 1.1.1.2 root 1795: } 1.1.1.3 ! root 1796: if(map < 1) 1.1.1.2 root 1797: { 1.1.1.3 ! root 1798: map = 1; 1.1.1.2 root 1799: } 1.1.1.3 ! root 1800: if(map > 99) 1.1.1.2 root 1801: { 1.1.1.3 ! root 1802: map = 99; 1.1.1.2 root 1803: } 1.1.1.3 ! root 1804: M_ClearRandom(); 1.1.1.2 root 1805: // Force players to be initialized upon first level load 1806: for(i = 0; i < MAXPLAYERS; i++) 1807: { 1808: players[i].playerstate = PST_REBORN; 1.1.1.3 ! root 1809: players[i].worldTimer = 0; 1.1.1.2 root 1810: } 1.1.1.3 ! root 1811: 1.1.1.2 root 1812: // Set up a bunch of globals 1813: usergame = true; // will be set false if a demo 1814: paused = false; 1815: demorecording = false; 1816: demoplayback = false; 1817: viewactive = true; 1818: gameepisode = episode; 1819: gamemap = map; 1820: gameskill = skill; 1821: BorderNeedRefresh = true; 1822: 1.1.1.3 ! root 1823: // Initialize the sky ! 1824: R_InitSky(map); ! 1825: ! 1826: // Give one null ticcmd_t ! 1827: //gametic = 0; ! 1828: //maketic = 1; ! 1829: //for (i=0 ; i<MAXPLAYERS ; i++) ! 1830: // nettics[i] = 1; // one null event for this gametic ! 1831: //memset (localcmds,0,sizeof(localcmds)); ! 1832: //memset (netcmds,0,sizeof(netcmds)); 1.1.1.2 root 1833: 1834: G_DoLoadLevel(); 1835: } 1836: 1837: /* 1838: =============================================================================== 1839: 1840: DEMO RECORDING 1841: 1842: =============================================================================== 1843: */ 1844: 1845: #define DEMOMARKER 0x80 1846: 1847: void G_ReadDemoTiccmd (ticcmd_t *cmd) 1848: { 1849: if (*demo_p == DEMOMARKER) 1850: { // end of demo data stream 1851: G_CheckDemoStatus (); 1852: return; 1853: } 1854: cmd->forwardmove = ((signed char)*demo_p++); 1855: cmd->sidemove = ((signed char)*demo_p++); 1856: cmd->angleturn = ((unsigned char)*demo_p++)<<8; 1857: cmd->buttons = (unsigned char)*demo_p++; 1858: cmd->lookfly = (unsigned char)*demo_p++; 1859: cmd->arti = (unsigned char)*demo_p++; 1860: } 1861: 1862: void G_WriteDemoTiccmd (ticcmd_t *cmd) 1863: { 1864: if (gamekeydown['q']) // press q to end demo recording 1865: G_CheckDemoStatus (); 1866: *demo_p++ = cmd->forwardmove; 1867: *demo_p++ = cmd->sidemove; 1868: *demo_p++ = cmd->angleturn>>8; 1869: *demo_p++ = cmd->buttons; 1870: *demo_p++ = cmd->lookfly; 1871: *demo_p++ = cmd->arti; 1872: demo_p -= 6; 1873: G_ReadDemoTiccmd (cmd); // make SURE it is exactly the same 1874: } 1875: 1876: 1877: 1878: /* 1879: =================== 1880: = 1881: = G_RecordDemo 1882: = 1883: =================== 1884: */ 1885: 1886: void G_RecordDemo (skill_t skill, int numplayers, int episode, int map, char *name) 1887: { 1888: int i; 1.1.1.3 ! root 1889: 1.1.1.2 root 1890: G_InitNew (skill, episode, map); 1891: usergame = false; 1892: strcpy (demoname, name); 1893: strcat (demoname, ".lmp"); 1894: demobuffer = demo_p = Z_Malloc (0x20000,PU_STATIC,NULL); 1895: *demo_p++ = skill; 1896: *demo_p++ = episode; 1897: *demo_p++ = map; 1.1.1.3 ! root 1898: 1.1.1.2 root 1899: for (i=0 ; i<MAXPLAYERS ; i++) 1.1.1.3 ! root 1900: { 1.1.1.2 root 1901: *demo_p++ = playeringame[i]; 1.1.1.3 ! root 1902: *demo_p++ = PlayerClass[i]; ! 1903: } 1.1.1.2 root 1904: demorecording = true; 1905: } 1906: 1907: 1908: /* 1909: =================== 1910: = 1911: = G_PlayDemo 1912: = 1913: =================== 1914: */ 1915: 1916: char *defdemoname; 1917: 1918: void G_DeferedPlayDemo (char *name) 1919: { 1920: defdemoname = name; 1921: gameaction = ga_playdemo; 1922: } 1923: 1924: void G_DoPlayDemo (void) 1925: { 1926: skill_t skill; 1927: int i, episode, map; 1.1.1.3 ! root 1928: 1.1.1.2 root 1929: gameaction = ga_nothing; 1930: demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC); 1931: skill = *demo_p++; 1932: episode = *demo_p++; 1933: map = *demo_p++; 1934: 1935: for (i=0 ; i<MAXPLAYERS ; i++) 1.1.1.3 ! root 1936: { 1.1.1.2 root 1937: playeringame[i] = *demo_p++; 1.1.1.3 ! root 1938: PlayerClass[i] = *demo_p++; ! 1939: } ! 1940: ! 1941: // Initialize world info, etc. ! 1942: G_StartNewInit(); 1.1.1.2 root 1943: 1944: precache = false; // don't spend a lot of time in loadlevel 1945: G_InitNew (skill, episode, map); 1946: precache = true; 1947: usergame = false; 1948: demoplayback = true; 1949: } 1950: 1951: 1952: /* 1953: =================== 1954: = 1955: = G_TimeDemo 1956: = 1957: =================== 1958: */ 1959: 1960: void G_TimeDemo (char *name) 1961: { 1962: skill_t skill; 1963: int episode, map; 1.1.1.3 ! root 1964: 1.1.1.2 root 1965: demobuffer = demo_p = W_CacheLumpName (name, PU_STATIC); 1966: skill = *demo_p++; 1967: episode = *demo_p++; 1968: map = *demo_p++; 1969: G_InitNew (skill, episode, map); 1970: usergame = false; 1971: demoplayback = true; 1972: timingdemo = true; 1973: singletics = true; 1974: } 1975: 1976: 1977: /* 1978: =================== 1979: = 1980: = G_CheckDemoStatus 1981: = 1982: = Called after a death or level completion to allow demos to be cleaned up 1983: = Returns true if a new demo loop action will take place 1984: =================== 1985: */ 1986: 1987: boolean G_CheckDemoStatus (void) 1988: { 1989: int endtime; 1.1.1.3 ! root 1990: 1.1.1.2 root 1991: if (timingdemo) 1992: { 1993: endtime = I_GetTime (); 1994: I_Error ("timed %i gametics in %i realtics",gametic 1995: , endtime-starttime); 1996: } 1.1.1.3 ! root 1997: 1.1.1.2 root 1998: if (demoplayback) 1999: { 2000: if (singledemo) 2001: I_Quit (); 1.1.1.3 ! root 2002: 1.1.1.2 root 2003: Z_ChangeTag (demobuffer, PU_CACHE); 2004: demoplayback = false; 1.1.1.3 ! root 2005: H2_AdvanceDemo(); 1.1.1.2 root 2006: return true; 2007: } 2008: 2009: if (demorecording) 2010: { 2011: *demo_p++ = DEMOMARKER; 2012: M_WriteFile (demoname, demobuffer, demo_p - demobuffer); 2013: Z_Free (demobuffer); 2014: demorecording = false; 2015: I_Error ("Demo %s recorded",demoname); 2016: } 2017: 2018: return false; 2019: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.