Iskhodnyy_kod_Doom
.pdf// 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 |
|
// |
|
extern gamestate_t |
wipegamestate; |
void G_DoLoadLevel (void) |
|
{ |
|
int |
i; |
//Set the sky map.
//First thing, we have a dummy sky texture name,
//a flat. The data is in the WAD only because
//we look for an actual index, instead of simply
//setting one.
skyflatnum = R_FlatNumForName ( SKYFLATNAME );
//DOOM determines the sky texture to be used
//depending on the current episode, and the game version. if ( (gamemode == commercial)
||( gamemode == pack_tnt )
||( gamemode == pack_plut ) )
{
skytexture = R_TextureNumForName ("SKY3"); if (gamemap < 12)
skytexture = R_TextureNumForName ("SKY1");
else
if (gamemap < 21)
skytexture = R_TextureNumForName ("SKY2");
} |
|
|
|
levelstarttic = gametic; |
// for |
time calculation |
|
if (wipegamestate |
== GS_LEVEL) |
|
|
wipegamestate |
= -1; |
// |
force a wipe |
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));
}
P_SetupLevel (gameepisode, gamemap, 0, gameskill);
displayplayer = consoleplayer; |
// view the guy you are playing |
starttime = I_GetTime (); |
|
gameaction = ga_nothing; |
|
Z_CheckHeap (); |
|
131
// 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)
{
//allow spy mode changes even during the demo
if (gamestate == GS_LEVEL && ev->type == ev_keydown
&& ev->data1 == KEY_F12 && (singledemo || !deathmatch) )
{
// spy mode do
{
displayplayer++;
if (displayplayer == MAXPLAYERS) displayplayer = 0;
} while (!playeringame[displayplayer] && displayplayer != consoleplayer); return true;
}
// any other key pops up menu if in demos
if (gameaction == ga_nothing && !singledemo && (demoplayback || gamestate == GS_DEMOSCREEN)
)
{
if (ev->type == ev_keydown ||
(ev->type == ev_mouse && ev->data1) || (ev->type == ev_joystick && ev->data1) )
{
M_StartControlPanel (); return true;
}
return false;
}
if (gamestate == GS_LEVEL)
{
#if 0
if (devparm && ev->type == ev_keydown && ev->data1 == ’;’)
{
G_DeathMatchSpawnPlayer (0); return true;
} |
|
#endif |
|
if (HU_Responder (ev)) |
|
return true; |
// chat ate the event |
if (ST_Responder (ev)) |
|
return true; |
// status window ate it |
if (AM_Responder (ev)) |
|
return true; |
// automap ate it |
} |
|
if (gamestate == GS_FINALE)
{
if (F_Responder (ev))
132
return true; |
// finale ate the event |
} |
|
switch (ev->type)
{
case ev_keydown:
if (ev->data1 == KEY_PAUSE)
{
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
//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)
133
{
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)
134
{
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;
}
}
135
//
//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];
136
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);
boolean |
|
G_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;
137
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;
138
}
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 Times 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 Times
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; |
|
extern char* |
pagename; |
|
void G_ExitLevel (void)
{
secretexit = false; gameaction = ga_completed;
}
// Here’s for the german edition. void G_SecretExitLevel (void)
139
{
// 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;
140