📄 g_game.c
字号:
gamekeydown[ev->data1] = true; return true; // eat key down events case ev_keyup: if (ev->data1 <NUMKEYS) gamekeydown[ev->data1] = false; return false; // always let key up events filter down case ev_mouse: mousebuttons[0] = ev->data1 & 1; mousebuttons[1] = ev->data1 & 2; mousebuttons[2] = ev->data1 & 4; mousex = ev->data2*(mouseSensitivity+5)/10; mousey = ev->data3*(mouseSensitivity+5)/10; return true; // eat events case ev_joystick: /* Hard coding this for the Stinger. Someone please fix this! */ joybuttons[0] = ev->data1 & (1 << 6); joybuttons[1] = ev->data1 & (1 << 7); joybuttons[2] = ev->data1 & (1 << 0); joybuttons[3] = ev->data1 & (1 << 3); if (abs(ev->data2) > 0x5000) joyxmove = 1; else joyxmove = 0; if (ev->data2 < 0) joyxmove = -joyxmove; if(abs(ev->data3) > 0x5000) joyymove = 1; else joyymove = 0; if (ev->data3 < 0) joyymove = -joyymove; printf("Recording buttons: %d - %d - %d - %d\n", joybuttons[0], joybuttons[1], joybuttons[2], joybuttons[3]); printf("Recording movement: %d, %d\n", joyxmove, joyymove); return true; // eat events default: break; } return false; } //// G_Ticker// Make ticcmd_ts for the players.//void G_Ticker (void) { int i; int buf; ticcmd_t* cmd; // do player reborns if needed for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i] && players[i].playerstate == PST_REBORN) G_DoReborn (i); // do things to change the game state while (gameaction != ga_nothing) { switch (gameaction) { case ga_loadlevel: G_DoLoadLevel (); break; case ga_newgame: G_DoNewGame (); break; case ga_loadgame: G_DoLoadGame (); break; case ga_savegame: G_DoSaveGame (); break; case ga_playdemo: G_DoPlayDemo (); break; case ga_completed: G_DoCompleted (); break; case ga_victory: F_StartFinale (); break; case ga_worlddone: G_DoWorldDone (); break; case ga_screenshot: M_ScreenShot (); gameaction = ga_nothing; break; case ga_nothing: break; } } // get commands, check consistancy, // and build new consistancy check buf = (gametic/ticdup)%BACKUPTICS; for (i=0 ; i<MAXPLAYERS ; i++) { if (playeringame[i]) { cmd = &players[i].cmd; memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t)); if (demoplayback) G_ReadDemoTiccmd (cmd); if (demorecording) G_WriteDemoTiccmd (cmd); // check for turbo cheats if (cmd->forwardmove > TURBOTHRESHOLD && !(gametic&31) && ((gametic>>5)&3) == i ) { static char turbomessage[80]; extern char *player_names[4]; sprintf (turbomessage, "%s is turbo!",player_names[i]); players[consoleplayer].message = turbomessage; } if (netgame && !netdemo && !(gametic%ticdup) ) { if (gametic > BACKUPTICS && consistancy[i][buf] != cmd->consistancy) { I_Error ("consistency failure (%i should be %i)", cmd->consistancy, consistancy[i][buf]); } if (players[i].mo) consistancy[i][buf] = players[i].mo->x; else consistancy[i][buf] = rndindex; } } } // check for special buttons for (i=0 ; i<MAXPLAYERS ; i++) { if (playeringame[i]) { if (players[i].cmd.buttons & BT_SPECIAL) { switch (players[i].cmd.buttons & BT_SPECIALMASK) { case BTS_PAUSE: paused ^= 1; if (paused) S_PauseSound (); else S_ResumeSound (); break; case BTS_SAVEGAME: if (!savedescription[0]) strcpy (savedescription, "NET GAME"); savegameslot = (players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT; gameaction = ga_savegame; break; } } } } // do main actions switch (gamestate) { case GS_LEVEL: P_Ticker (); ST_Ticker (); AM_Ticker (); HU_Ticker (); break; case GS_INTERMISSION: WI_Ticker (); break; case GS_FINALE: F_Ticker (); break; case GS_DEMOSCREEN: D_PageTicker (); break; } } //// PLAYER STRUCTURE FUNCTIONS// also see P_SpawnPlayer in P_Things////// G_InitPlayer // Called at the start.// Called by the game initialization functions.//void G_InitPlayer (int player) { player_t* p; // set up the saved info p = &players[player]; // clear everything else to defaults G_PlayerReborn (player); } //// G_PlayerFinishLevel// Can when a player completes a level.//void G_PlayerFinishLevel (int player) { player_t* p; p = &players[player]; memset (p->powers, 0, sizeof (p->powers)); memset (p->cards, 0, sizeof (p->cards)); p->mo->flags &= ~MF_SHADOW; // cancel invisibility p->extralight = 0; // cancel gun flashes p->fixedcolormap = 0; // cancel ir gogles p->damagecount = 0; // no palette changes p->bonuscount = 0; } //// G_PlayerReborn// Called after a player dies // almost everything is cleared and initialized //void G_PlayerReborn (int player) { player_t* p; int i; int frags[MAXPLAYERS]; int killcount; int itemcount; int secretcount; memcpy (frags,players[player].frags,sizeof(frags)); killcount = players[player].killcount; itemcount = players[player].itemcount; secretcount = players[player].secretcount; p = &players[player]; memset (p, 0, sizeof(*p)); memcpy (players[player].frags, frags, sizeof(players[player].frags)); players[player].killcount = killcount; players[player].itemcount = itemcount; players[player].secretcount = secretcount; p->usedown = p->attackdown = true; // don't do anything immediately p->playerstate = PST_LIVE; p->health = MAXHEALTH; p->readyweapon = p->pendingweapon = wp_pistol; p->weaponowned[wp_fist] = true; p->weaponowned[wp_pistol] = true; p->ammo[am_clip] = 50; for (i=0 ; i<NUMAMMO ; i++) p->maxammo[i] = maxammo[i]; }//// G_CheckSpot // Returns false if the player cannot be respawned// at the given mapthing_t spot // because something is occupying it //void P_SpawnPlayer (mapthing_t* mthing); booleanG_CheckSpot( int playernum, mapthing_t* mthing ) { fixed_t x; fixed_t y; subsector_t* ss; unsigned an; mobj_t* mo; int i; if (!players[playernum].mo) { // first spawn of level, before corpses for (i=0 ; i<playernum ; i++) if (players[i].mo->x == mthing->x << FRACBITS && players[i].mo->y == mthing->y << FRACBITS) return false; return true; } x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; if (!P_CheckPosition (players[playernum].mo, x, y) ) return false; // flush an old corpse if needed if (bodyqueslot >= BODYQUESIZE) P_RemoveMobj (bodyque[bodyqueslot%BODYQUESIZE]); bodyque[bodyqueslot%BODYQUESIZE] = players[playernum].mo; bodyqueslot++; // spawn a teleport fog ss = R_PointInSubsector (x,y); an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT; mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an] , ss->sector->floorheight , MT_TFOG); if (players[consoleplayer].viewz != 1) S_StartSound (mo, sfx_telept); // don't start sound on first frame return true; } //// G_DeathMatchSpawnPlayer // Spawns a player at one of the random death match spots // called at level load and each death //void G_DeathMatchSpawnPlayer (int playernum) { int i,j; int selections; selections = deathmatch_p - deathmatchstarts; if (selections < 4) I_Error ("Only %i deathmatch spots, 4 required", selections); for (j=0 ; j<20 ; j++) { i = P_Random() % selections; if (G_CheckSpot (playernum, &deathmatchstarts[i]) ) { deathmatchstarts[i].type = playernum+1; P_SpawnPlayer (&deathmatchstarts[i]); return; } } // no good spot, so the player will probably get stuck P_SpawnPlayer (&playerstarts[playernum]); } //// G_DoReborn // void G_DoReborn (int playernum) { int i; if (!netgame) { // reload the level from scratch gameaction = ga_loadlevel; } else { // respawn at the start // first dissasociate the corpse players[playernum].mo->player = NULL; // spawn at random spot if in death match if (deathmatch) { G_DeathMatchSpawnPlayer (playernum); return; } if (G_CheckSpot (playernum, &playerstarts[playernum]) ) { P_SpawnPlayer (&playerstarts[playernum]); return; } // try to spawn at one of the other players spots for (i=0 ; i<MAXPLAYERS ; i++) { if (G_CheckSpot (playernum, &playerstarts[i]) ) { playerstarts[i].type = playernum+1; // fake as other player P_SpawnPlayer (&playerstarts[i]); playerstarts[i].type = i+1; // restore return; } // he's going to be inside something. Too bad. } P_SpawnPlayer (&playerstarts[playernum]); } } void G_ScreenShot (void) { gameaction = ga_screenshot; } // DOOM Par Timesint pars[4][10] = { {0}, {0,30,75,120,90,165,180,180,30,165}, {0,90,90,90,120,90,360,240,30,170}, {0,90,45,90,150,90,90,165,30,135} }; // DOOM II Par Timesint cpars[32] ={ 30,90,120,120,90,150,120,120,270,90, // 1-10 210,150,150,150,210,150,420,150,210,150, // 11-20 240,150,180,150,150,300,330,420,300,180, // 21-30 120,30 // 31-32}; //// G_DoCompleted //boolean secretexit; extern char* pagename; void G_ExitLevel (void) { secretexit = false; gameaction = ga_completed; } // Here's for the german edition.void G_SecretExitLevel (void) { // IF NO WOLF3D LEVELS, NO SECRET EXIT! if ( (gamemode == commercial) && (W_CheckNumForName("map31")<0)) secretexit = false; else secretexit = true; gameaction = ga_completed; } void G_DoCompleted (void) { int i; gameaction = ga_nothing; for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i]) G_PlayerFinishLevel (i); // take away cards and stuff if (automapactive) AM_Stop (); if ( gamemode != commercial) switch(gamemap) { case 8: gameaction = ga_victory; return; case 9: for (i=0 ; i<MAXPLAYERS ; i++) players[i].didsecret = true; break; } //#if 0 Hmmm - why? if ( (gamemap == 8) && (gamemode != commercial) ) { // victory gameaction = ga_victory; return; } if ( (gamemap == 9) && (gamemode != commercial) ) { // exit secret level for (i=0 ; i<MAXPLAYERS ; i++) players[i].didsecret = true; } //#endif wminfo.didsecret = players[consoleplayer].didsecret; wminfo.epsd = gameepisode -1; wminfo.last = gamemap -1; // wminfo.next is 0 biased, unlike gamemap if ( gamemode == commercial) { if (secretexit) switch(gamemap) { case 15: wminfo.next = 30; break; case 31: wminfo.next = 31; break; } else switch(gamemap) { case 31: case 32: wminfo.next = 15; break; default: wminfo.next = gamemap; } } else { if (secretexit) wminfo.next = 8; // go to secret level else if (gamemap == 9) { // returning from secret level switch (gameepisode) { case 1: wminfo.next = 3; break; case 2: wminfo.next = 5; break; case 3: wminfo.next = 6; break; case 4: wminfo.next = 2; break; } } else wminfo.next = gamemap; // go to next level } wminfo.maxkills = totalkills; wminfo.maxitems = totalitems; wminfo.maxsecret = totalsecret; wminfo.maxfrags = 0; if ( gamemode == commercial ) wminfo.partime = 35*cpars[gamemap-1]; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -