📄 g_game.c
字号:
// Called after a player dies// almost everything is cleared and initialized//void G_PlayerReborn (int player){ player_t* p; int i; USHORT frags[MAXPLAYERS]; int killcount; int itemcount; int secretcount; USHORT addfrags; //from Boris int skincolor; char favoritweapon[NUMWEAPONS]; boolean originalweaponswitch; boolean autoaim; int skin; //Fab: keep same skin#ifdef CLIENTPREDICTION2 mobj_t *spirit;#endif memcpy (frags,players[player].frags,sizeof(frags)); addfrags = players[player].addfrags; killcount = players[player].killcount; itemcount = players[player].itemcount; secretcount = players[player].secretcount; //from Boris skincolor = players[player].skincolor; originalweaponswitch = players[player].originalweaponswitch; memcpy (favoritweapon,players[player].favoritweapon,NUMWEAPONS); autoaim = players[player].autoaim_toggle; skin = players[player].skin;#ifdef CLIENTPREDICTION2 spirit = players[player].spirit;#endif p = &players[player]; memset (p, 0, sizeof(*p)); memcpy (players[player].frags, frags, sizeof(players[player].frags)); players[player].addfrags=addfrags; players[player].killcount = killcount; players[player].itemcount = itemcount; players[player].secretcount = secretcount; // save player config truth reborn players[player].skincolor = skincolor; players[player].originalweaponswitch = originalweaponswitch; memcpy (players[player].favoritweapon,favoritweapon,NUMWEAPONS); players[player].autoaim_toggle = autoaim; players[player].skin = skin;#ifdef CLIENTPREDICTION2 players[player].spirit = spirit;#endif p->usedown = p->attackdown = true; // don't do anything immediately p->playerstate = PST_LIVE; p->health = initial_health; if( gamemode == heretic ) { p->weaponinfo = wpnlev1info; p->readyweapon = p->pendingweapon = wp_goldwand; p->weaponowned[wp_staff] = true; p->weaponowned[wp_goldwand] = true; p->ammo[am_goldwand] = 50; } else { p->weaponinfo = doomweaponinfo; p->readyweapon = p->pendingweapon = wp_pistol; p->weaponowned[wp_fist] = true; p->weaponowned[wp_pistol] = true; p->ammo[am_clip] = initial_bullets; } // Boris stuff if(!p->originalweaponswitch) VerifFavoritWeapon(p); //eof Boris 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//boolean G_CheckSpot ( int playernum, mapthing_t* mthing ){ fixed_t x; fixed_t y; subsector_t* ss; unsigned an; mobj_t* mo; int i; // added 25-4-98 : maybe there is no player start if(!mthing || mthing->type<0) return false; if (!players[playernum].mo) { // first spawn of level, before corpses for (i=0 ; i<playernum ; i++) // added 15-1-98 check if player is in game (mistake from id) if (playeringame[i] && 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; ss = R_PointInSubsector (x,y); // check for respawn in team-sector if(ss->sector->teamstartsec) { if(cv_teamplay.value==1) { // color if(players[playernum].skincolor!=(ss->sector->teamstartsec-1)) // -1 because wanted to know when it is set return false; } else if(cv_teamplay.value==2) { // skins if(players[playernum].skin!=(ss->sector->teamstartsec-1)) // -1 because wanted to know when it is set return false; } } 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 an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT; mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an] , ss->sector->floorheight , MT_TFOG); //added:16-01-98:consoleplayer -> displayplayer (hear snds from viewpt) // removed 9-12-98: why not ???? if (players[displayplayer].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//boolean G_DeathMatchSpawnPlayer (int playernum){ int i,j,n; if( !numdmstarts ) I_Error("No deathmatch start in this map !"); if(demoversion<123) n=20; else n=64; for (j=0 ; j<n ; j++) { i = P_Random() % numdmstarts; if (G_CheckSpot (playernum, deathmatchstarts[i]) ) { deathmatchstarts[i]->type = playernum+1; P_SpawnPlayer (deathmatchstarts[i]); return true; } } if(demoversion<113) { // no good spot, so the player will probably get stuck P_SpawnPlayer (playerstarts[playernum]); return true; } return false;}void G_CoopSpawnPlayer (int playernum){ int i; // no deathmatch use the spot 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. } if(demoversion<113) P_SpawnPlayer (playerstarts[playernum]); else { int selections; if( !numdmstarts) I_Error("No deathmatch start in this map !"); selections = P_Random() % numdmstarts; deathmatchstarts[selections]->type = playernum+1; P_SpawnPlayer (deathmatchstarts[selections]); }}//// G_DoReborn//void G_DoReborn (int playernum){ player_t* player = &players[playernum]; // boris comment : this test is like 'single player game' // all this kind of hiden variable must be removed if (!multiplayer && !cv_deathmatch.value) { // reload the level from scratch G_DoLoadLevel (true); } else { // respawn at the start // first dissasociate the corpse if(player->mo) { player->mo->player = NULL; player->mo->flags2 &= ~MF2_DONTDRAW; } // spawn at random spot if in death match if (cv_deathmatch.value) { if(G_DeathMatchSpawnPlayer (playernum)) return; } G_CoopSpawnPlayer (playernum); }}void G_AddPlayer( int playernum ){ player_t *p=&players[playernum]; p->playerstate = PST_REBORN; memset(p->inventory, 0, sizeof( p->inventory )); p->inventorySlotNum = 0; p->inv_ptr = 0; p->st_curpos = 0; p->st_inventoryTics = 0; if( gamemode == heretic ) p->weaponinfo = wpnlev1info; else p->weaponinfo = doomweaponinfo;}// DOOM Par Timesstatic const int 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 Timesstatic const int 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;void G_ExitLevel (void){ if( gamestate==GS_LEVEL ) { 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: //BP add comment : no intermistion screen if(cv_deathmatch.value) wminfo.next = 0; else { // also for heretic CL_Reset(); F_StartFinale(); return; } case 9: for (i=0 ; i<MAXPLAYERS ; i++) players[i].didsecret = true; break; } wminfo.didsecret = players[consoleplayer].didsecret; wminfo.epsd = gameepisode -1; wminfo.last = gamemap -1; // go to next level // wminfo.next is 0 biased, unlike gamemap wminfo.next = gamemap; // overwrite next level in some cases if ( gamemode == commercial) { if (secretexit) switch(gamemap) { case 15 : wminfo.next = 30; break; case 31 : wminfo.next = 31; break; default : wminfo.next = 15;break; } else switch(gamemap) { case 31: case 32: wminfo.next = 15; break; default: wminfo.next = gamemap; } } else if( gamemode == heretic ) { static int afterSecret[5] = { 7, 5, 5, 5, 4 }; if (secretexit) wminfo.next = 8; // go to secret level else if (gamemap == 9) wminfo.next = afterSecret[gameepisode-1]-1; } 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; default : wminfo.next = 0; break; } } else if (gamemap == 8) wminfo.next = 0; // wrape around in deathmatch } wminfo.maxkills = totalkills; wminfo.maxitems = totalitems; wminfo.maxsecret = totalsecret; wminfo.maxfrags = 0; if( info_partime != -1) wminfo.partime = TICRATE*info_partime; else if ( gamemode == commercial ) wminfo.partime = TICRATE*cpars[gamemap-1]; else wminfo.partime = TICRATE*pars[gameepisode][gamemap]; wminfo.pnum = consoleplayer; for (i=0 ; i<MAXPLAYERS ; i++) { wminfo.plyr[i].in = playeringame[i]; wminfo.plyr[i].skills = players[i].killcount; wminfo.plyr[i].sitems = players[i].itemcount; wminfo.plyr[i].ssecret = players[i].secretcount; wminfo.plyr[i].stime = leveltime; memcpy (wminfo.plyr[i].frags, players[i].frags , sizeof(wminfo.plyr[i].frags)); wminfo.plyr[i].addfrags = players[i].addfrags; } gamestate = GS_INTERMISSION; automapactive = false; if (statcopy) memcpy (statcopy, &wminfo, sizeof(wminfo)); WI_Start (&wminfo);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -