📄 g_game.c
字号:
if (dclicktime > 20)
{
dclicks = 0;
dclickstate = 0;
}
}
//
// strafe double click
//
bstrafe = mousebuttons[mousebstrafe]
|| joybuttons[joybstrafe];
if (bstrafe != dclickstate2 && dclicktime2 > 1 )
{
dclickstate2 = bstrafe;
if (dclickstate2)
dclicks2++;
if (dclicks2 == 2)
{
cmd->buttons |= BT_USE;
dclicks2 = 0;
}
else
dclicktime2 = 0;
}
else
{
dclicktime2 += ticdup;
if (dclicktime2 > 20)
{
dclicks2 = 0;
dclickstate2 = 0;
}
}
if (strafe) { side += mousex*2; } else { cmd->angleturn -= mousex*0x8;
}
forward += mousey; mousex = mousey = 0;
if (forward > MaxPlayerMove[pClass]) { forward = MaxPlayerMove[pClass];
} else if (forward < -MaxPlayerMove[pClass])
{ forward = -MaxPlayerMove[pClass];
} if (side > MaxPlayerMove[pClass])
{ side = MaxPlayerMove[pClass]; } else if (side < -MaxPlayerMove[pClass])
{ side = -MaxPlayerMove[pClass];
}
if(players[consoleplayer].powers[pw_speed] && !players[consoleplayer].morphTics) { // Adjust for a player with a speed artifact forward = (3*forward)>>1; side = (3*side)>>1; } cmd->forwardmove += forward;
cmd->sidemove += side;
if(players[consoleplayer].playerstate == PST_LIVE) { if(look < 0) { look += 16; } cmd->lookfly = look; } if(flyheight < 0) { flyheight += 16; } cmd->lookfly |= flyheight<<4;//
// special buttons
//
if (sendpause)
{
sendpause = false;
cmd->buttons = BT_SPECIAL | BTS_PAUSE;
}
if (sendsave)
{
sendsave = false;
cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT);
}
}
/*
==============
=
= G_DoLoadLevel
=
==============
*/
void G_DoLoadLevel (void)
{
int i;
levelstarttic = gametic; // for time calculation
gamestate = GS_LEVEL;
for (i=0 ; i<MAXPLAYERS ; i++)
{
if (playeringame[i] && players[i].playerstate == PST_DEAD)
players[i].playerstate = PST_REBORN;
memset (players[i].frags,0,sizeof(players[i].frags));
}
SN_StopAllSequences();
P_SetupLevel (gameepisode, gamemap, 0, gameskill);
displayplayer = consoleplayer; // view the guy you are playing
starttime = I_GetTime ();
gameaction = ga_nothing;
Z_CheckHeap ();
//
// clear cmd building stuff
//
memset (gamekeydown, 0, sizeof(gamekeydown));
joyxmove = joyymove = 0;
mousex = mousey = 0;
sendpause = sendsave = paused = false;
memset (mousebuttons, 0, sizeof(mousebuttons));
memset (joybuttons, 0, sizeof(joybuttons));
}
/*
===============================================================================
=
= G_Responder
=
= get info needed to make ticcmd_ts for the players
=
===============================================================================
*/
boolean G_Responder(event_t *ev){ player_t *plr; extern boolean MenuActive; plr = &players[consoleplayer]; if(ev->type == ev_keyup && ev->data1 == key_useartifact) { // flag to denote that it's okay to use an artifact if(!inventory) { plr->readyArtifact = plr->inventory[inv_ptr].type; } usearti = true; } // Check for spy mode player cycle if(gamestate == GS_LEVEL && ev->type == ev_keydown && ev->data1 == KEY_F12 && !deathmatch) { // Cycle the display player do { displayplayer++; if(displayplayer == MAXPLAYERS) { displayplayer = 0; } } while(!playeringame[displayplayer] && displayplayer != consoleplayer); return(true); } if(CT_Responder(ev)) { // Chat ate the event return(true); } if(gamestate == GS_LEVEL) { if(SB_Responder(ev)) { // Status bar ate the event return(true); } if(AM_Responder(ev)) { // Automap ate the event return(true); } } switch(ev->type) { case ev_keydown: if(ev->data1 == key_invleft) { inventoryTics = 5*35; if(!inventory) { inventory = true; break; } inv_ptr--; if(inv_ptr < 0) { inv_ptr = 0; } else { curpos--; if(curpos < 0) { curpos = 0; } } return(true); } if(ev->data1 == key_invright) { inventoryTics = 5*35; if(!inventory) { inventory = true; break; } inv_ptr++; if(inv_ptr >= plr->inventorySlotNum) { inv_ptr--; if(inv_ptr < 0) inv_ptr = 0; } else { curpos++; if(curpos > 6) { curpos = 6; } } return(true); } if(ev->data1 == KEY_PAUSE && !MenuActive) { sendpause = true; return(true); } if(ev->data1 < NUMKEYS) { 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: joybuttons[0] = ev->data1&1; joybuttons[1] = ev->data1&2; joybuttons[2] = ev->data1&4; joybuttons[3] = ev->data1&8; joyxmove = ev->data2; joyymove = ev->data3; return(true); // eat events default: break; } return(false);}//==========================================================================//// G_Ticker////==========================================================================void G_Ticker(void){ int i, buf; ticcmd_t *cmd=NULL;//
// 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_initnew: G_DoInitNew(); break; case ga_newgame: G_DoNewGame(); break; case ga_loadgame: Draw_LoadIcon(); G_DoLoadGame(); break; case ga_savegame: Draw_SaveIcon(); G_DoSaveGame(); break; case ga_singlereborn: G_DoSingleReborn(); break; case ga_playdemo: G_DoPlayDemo(); break; case ga_screenshot: M_ScreenShot(); gameaction = ga_nothing; break; case ga_leavemap: Draw_TeleportIcon(); G_DoTeleportNewMap(); break; case ga_completed:
G_DoCompleted();
break; case ga_worlddone: G_DoWorldDone(); break; case ga_victory: F_StartFinale(); break; default: break; } }
//
// get commands, check consistancy, and build new consistancy check
//
//buf = gametic%BACKUPTICS;
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);
if (netgame && !(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])
{ if(netgame) { strcpy (savedescription, "NET GAME"); } else { strcpy(savedescription, "SAVE GAME"); } }
savegameslot =
(players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT;
gameaction = ga_savegame;
break;
}
}
}
// turn inventory off after a certain amount of time if(inventory && !(--inventoryTics)) { players[consoleplayer].readyArtifact = players[consoleplayer].inventory[inv_ptr].type; inventory = false; cmd->arti = 0; }//
// do main actions
//
//
// do main actions
//
switch (gamestate)
{
case GS_LEVEL:
P_Ticker ();
SB_Ticker ();
AM_Ticker ();
CT_Ticker(); break;
case GS_INTERMISSION:
IN_Ticker ();
break;
case GS_FINALE:
F_Ticker();
break;
case GS_DEMOSCREEN:
H2_PageTicker ();
break;
}
}
/*
==============================================================================
PLAYER STRUCTURE FUNCTIONS
also see P_SpawnPlayer in P_Things
==============================================================================
*///==========================================================================//// G_PlayerExitMap//// Called when the player leaves a map.////==========================================================================void G_PlayerExitMap(int playerNumber){ int i; player_t *player; int flightPower; player = &players[playerNumber];// if(deathmatch)// {// // Strip all but one of each type of artifact// for(i = 0; i < player->inventorySlotNum; i++)// {// player->inventory[i].count = 1;// }// player->artifactCount = player->inventorySlotNum;// }// else // Strip all current powers (retain flight) flightPower = player->powers[pw_flight]; memset(player->powers, 0, sizeof(player->powers)); player->powers[pw_flight] = flightPower; if(deathmatch) { player->powers[pw_flight] = 0; } else { if(P_GetMapCluster(gamemap) != P_GetMapCluster(LeaveMap)) { // Entering new cluster // Strip all keys player->keys = 0; // Strip flight artifact for(i = 0; i < 25; i++) { player->powers[pw_flight] = 0; P_PlayerUseArtifact(player, arti_fly); } player->powers[pw_flight] = 0; } } if(player->morphTics) { player->readyweapon = player->mo->special1; // Restore weapon player->morphTics = 0; } player->messageTics = 0; player->lookdir = 0; player->mo->flags &= ~MF_SHADOW; // Remove invisibility player->extralight = 0; // Remove weapon flashes player->fixedcolormap = 0; // Remove torch player->damagecount = 0; // No palette changes player->bonuscount = 0; player->poisoncount = 0; if(player == &players[consoleplayer]) { SB_state = -1; // refresh the status bar viewangleoffset = 0; }}//==========================================================================//// G_PlayerReborn//// Called after a player dies. Almost everything is cleared and// initialized.////==========================================================================void G_PlayerReborn(int player){ player_t *p; int frags[MAXPLAYERS]; int killcount, itemcount, secretcount; uint worldTimer; memcpy(frags, players[player].frags, sizeof(frags)); killcount = players[player].killcount; itemcount = players[player].itemcount; secretcount = players[player].secretcount; worldTimer = players[player].worldTimer; 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; players[player].worldTimer = worldTimer; players[player].class = PlayerClass[player]; p->usedown = p->attackdown = true; // don't do anything immediately p->playerstate = PST_LIVE; p->health = MAXHEALTH; p->readyweapon = p->pendingweapon = WP_FIRST; p->weaponowned[WP_FIRST] = true; p->messageTics = 0; p->lookdir = 0; localQuakeHappening[player] = false; if(p == &players[consoleplayer]) { SB_state = -1; // refresh the status bar inv_ptr = 0; // reset the inventory pointer curpos = 0; viewangleoffset = 0; }}/*
====================
=
= 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);
boolean G_CheckSpot (int playernum, mapthing_t *mthing)
{
fixed_t x,y;
subsector_t *ss;
unsigned an;
mobj_t *mo;
x = mthing->x << FRACBITS;
y = mthing->y << FRACBITS;
players[playernum].mo->flags2 &= ~MF2_PASSMOBJ;
if (!P_CheckPosition (players[playernum].mo, x, y) )
{ players[playernum].mo->flags2 |= MF2_PASSMOBJ; return false;
} players[playernum].mo->flags2 |= MF2_PASSMOBJ;// 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+TELEFOGHEIGHT, MT_TFOG);
if (players[consoleplayer].viewz != 1)
S_StartSound (mo, SFX_TELEPORT); // 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;
// This check has been moved to p_setup.c:P_LoadThings() //if (selections < 8)
// I_Error ("Only %i deathmatch spots, 8 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]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -