📄 g_game.c
字号:
//**************************************************************************//**//** g_game.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: g_game.c,v $//** $Revision: 1.68 $//** $Date: 96/01/12 13:18:07 $//** $Author: bgokey $//**//**************************************************************************#include <string.h>#include "h2def.h"#include "p_local.h"#include "soundst.h"#define AM_STARTKEY 9// External functionsextern void R_InitSky(int map);extern void P_PlayerNextArtifact(player_t *player);// Functionsboolean G_CheckDemoStatus (void);void G_ReadDemoTiccmd (ticcmd_t *cmd);void G_WriteDemoTiccmd (ticcmd_t *cmd);void G_InitNew (skill_t skill, int episode, int map);void G_DoReborn (int playernum);void G_DoLoadLevel(void);void G_DoInitNew(void);void G_DoNewGame(void);void G_DoLoadGame(void);void G_DoPlayDemo(void);void G_DoTeleportNewMap(void);void G_DoCompleted(void);void G_DoVictory(void);void G_DoWorldDone(void);void G_DoSaveGame(void);void G_DoSingleReborn(void);void H2_PageTicker(void);void H2_AdvanceDemo(void);extern boolean mn_SuicideConsole;gameaction_t gameaction;
gamestate_t gamestate;
skill_t gameskill;
//boolean respawnmonsters;
int gameepisode;
int gamemap;
int prevmap;
boolean paused;
boolean sendpause; // send a pause event next tic
boolean sendsave; // send a save event next tic
boolean usergame; // ok to save / end game
boolean timingdemo; // if true, exit with report on completion
int starttime; // for comparative timing purposes
boolean viewactive;
boolean deathmatch; // only if started as net death
boolean netgame; // only true if packets are broadcast
boolean playeringame[MAXPLAYERS];
player_t players[MAXPLAYERS];pclass_t PlayerClass[MAXPLAYERS];// Position indicator for cooperative net-play rebornint RebornPosition;int consoleplayer; // player taking events and displaying
int displayplayer; // view being displayed
int gametic;
int levelstarttic; // gametic at level start
char demoname[32];
boolean demorecording;
boolean demoplayback;
byte *demobuffer, *demo_p;
boolean singledemo; // quit after playing a demo from cmdline
boolean precache = true; // if true, load all graphics at start
short consistancy[MAXPLAYERS][BACKUPTICS];
//// controls (have defaults)//int key_right, key_left, key_up, key_down;int key_strafeleft, key_straferight, key_jump;int key_fire, key_use, key_strafe, key_speed;int key_flyup, key_flydown, key_flycenter;int key_lookup, key_lookdown, key_lookcenter;int key_invleft, key_invright, key_useartifact;int mousebfire;int mousebstrafe;
int mousebforward;
int mousebjump;int joybfire;int joybstrafe;int joybuse;int joybspeed;int joybjump;int LeaveMap;static int LeavePosition;//#define MAXPLMOVE 0x32 // Old Heretic Max move
fixed_t MaxPlayerMove[NUMCLASSES] = { 0x3C, 0x32, 0x2D, 0x31 };fixed_t forwardmove[NUMCLASSES][2] = { { 0x1D, 0x3C }, { 0x19, 0x32 }, { 0x16, 0x2E }, { 0x18, 0x31 }}; fixed_t sidemove[NUMCLASSES][2] = { { 0x1B, 0x3B }, { 0x18, 0x28 }, { 0x15, 0x25 }, { 0x17, 0x27 }};fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn
#define SLOWTURNTICS 6
#define NUMKEYS 256
boolean gamekeydown[NUMKEYS];
int turnheld; // for accelerative turning
int lookheld;
boolean mousearray[4];
boolean *mousebuttons = &mousearray[1];
// allow [-1]
int mousex, mousey; // mouse values are used once
int dclicktime, dclickstate, dclicks;
int dclicktime2, dclickstate2, dclicks2;
int joyxmove, joyymove; // joystick values are repeated
boolean joyarray[5];
boolean *joybuttons = &joyarray[1]; // allow [-1]
int savegameslot;
char savedescription[32];
int inventoryTics;#ifdef __WATCOMC__extern externdata_t *i_ExternData;#endifstatic skill_t TempSkill;static int TempEpisode;static int TempMap;//=============================================================================
/*
====================
=
= G_BuildTiccmd
=
= Builds a ticcmd from all of the available inputs or reads it from the
= demo buffer.
= If recording a demo, write it out
====================
*/
extern boolean inventory;
extern int curpos;
extern int inv_ptr;
extern int isCyberPresent; // is CyberMan present?
boolean usearti = true;void I_ReadCyberCmd (ticcmd_t *cmd);
void G_BuildTiccmd (ticcmd_t *cmd)
{
int i;
boolean strafe, bstrafe;
int speed, tspeed, lspeed;
int forward, side;
int look, arti;
int flyheight; int pClass; extern boolean artiskip;#ifdef __WATCOMC__ int angleDelta;
static int oldAngle;
extern int newViewAngleOff; static int externInvKey; extern boolean automapactive; event_t ev;#endif pClass = players[consoleplayer].class; memset (cmd,0,sizeof(*cmd));
// cmd->consistancy =
// consistancy[consoleplayer][(maketic*ticdup)%BACKUPTICS];
cmd->consistancy = consistancy[consoleplayer][maketic%BACKUPTICS];
if (isCyberPresent)
I_ReadCyberCmd (cmd);
//printf ("cons: %i\n",cmd->consistancy);
strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe]
|| joybuttons[joybstrafe];
speed = gamekeydown[key_speed] || joybuttons[joybspeed]
|| joybuttons[joybspeed];
#ifdef __WATCOMC__ if(useexterndriver) { speed |= (i_ExternData->buttons&EBT_SPEED); strafe |= (i_ExternData->buttons&EBT_STRAFE); }#endif
forward = side = look = arti = flyheight = 0;
//
// use two stage accelerative turning on the keyboard and joystick
//
if (joyxmove < 0 || joyxmove > 0
|| gamekeydown[key_right] || gamekeydown[key_left])
turnheld += ticdup;
else
turnheld = 0;
if (turnheld < SLOWTURNTICS)
tspeed = 2; // slow turn
else
tspeed = speed;
if(gamekeydown[key_lookdown] || gamekeydown[key_lookup]) { lookheld += ticdup; } else { lookheld = 0; } if(lookheld < SLOWTURNTICS) { lspeed = 1; // 3; } else { lspeed = 2; // 5; }
//
// let movement keys cancel each other out
//
if(strafe)
{
if (gamekeydown[key_right]) { side += sidemove[pClass][speed];
} if (gamekeydown[key_left])
{ side -= sidemove[pClass][speed];
} if (joyxmove > 0)
{ side += sidemove[pClass][speed];
} if (joyxmove < 0)
{ side -= sidemove[pClass][speed];
} }
else
{
if (gamekeydown[key_right])
cmd->angleturn -= angleturn[tspeed];
if (gamekeydown[key_left])
cmd->angleturn += angleturn[tspeed];
if (joyxmove > 0)
cmd->angleturn -= angleturn[tspeed];
if (joyxmove < 0)
cmd->angleturn += angleturn[tspeed];
}
if (gamekeydown[key_up]) { forward += forwardmove[pClass][speed];
} if (gamekeydown[key_down])
{ forward -= forwardmove[pClass][speed];
} if (joyymove < 0)
{ forward += forwardmove[pClass][speed];
} if (joyymove > 0)
{ forward -= forwardmove[pClass][speed];
} if (gamekeydown[key_straferight])
{ side += sidemove[pClass][speed];
} if (gamekeydown[key_strafeleft])
{ side -= sidemove[pClass][speed];
} // Look up/down/center keys if(gamekeydown[key_lookup]) { look = lspeed; } if(gamekeydown[key_lookdown]) { look = -lspeed; }#ifdef __WATCOMC__ if(gamekeydown[key_lookcenter] && !useexterndriver) { look = TOCENTER; }#else if(gamekeydown[key_lookcenter]) { look = TOCENTER; }#endif#ifdef __WATCOMC__ if(useexterndriver && look != TOCENTER && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) { if(i_ExternData->moveForward) { forward += i_ExternData->moveForward; if(speed) { forward <<= 1; } } if(i_ExternData->angleTurn) { if(strafe) { side += i_ExternData->angleTurn; } else { cmd->angleturn += i_ExternData->angleTurn; } } if(i_ExternData->moveSideways) { side += i_ExternData->moveSideways; if(speed) { side <<= 1; } } if(i_ExternData->buttons&EBT_CENTERVIEW) { look = TOCENTER; oldAngle = 0; } else if(i_ExternData->pitch) { angleDelta = i_ExternData->pitch-oldAngle; if(abs(angleDelta) < 35) { look = angleDelta/5; } else { look = 7*(angleDelta > 0 ? 1 : -1); } if(look == TOCENTER) { look++; } oldAngle += look*5; } if(i_ExternData->flyDirection) { if(i_ExternData->flyDirection > 0) { flyheight = 5; } else { flyheight = -5; } } if(abs(newViewAngleOff-i_ExternData->angleHead) < 3000) { newViewAngleOff = i_ExternData->angleHead; } if(i_ExternData->buttons&EBT_FIRE) { cmd->buttons |= BT_ATTACK; } if(i_ExternData->buttons&EBT_OPENDOOR) { cmd->buttons |= BT_USE; } if(i_ExternData->buttons&EBT_PAUSE) { cmd->buttons = BT_SPECIAL|BTS_PAUSE; i_ExternData->buttons &= ~EBT_PAUSE; } if(externInvKey&EBT_USEARTIFACT) { ev.type = ev_keyup; ev.data1 = key_useartifact; H2_PostEvent(&ev); externInvKey &= ~EBT_USEARTIFACT; } else if(i_ExternData->buttons&EBT_USEARTIFACT) { externInvKey |= EBT_USEARTIFACT; ev.type = ev_keydown; ev.data1 = key_useartifact; H2_PostEvent(&ev); } if(externInvKey&EBT_INVENTORYRIGHT) { ev.type = ev_keyup; ev.data1 = key_invright; H2_PostEvent(&ev); externInvKey &= ~EBT_INVENTORYRIGHT; } else if(i_ExternData->buttons&EBT_INVENTORYRIGHT) { externInvKey |= EBT_INVENTORYRIGHT; ev.type = ev_keydown; ev.data1 = key_invright; H2_PostEvent(&ev); } if(externInvKey&EBT_INVENTORYLEFT) { ev.type = ev_keyup; ev.data1 = key_invleft; H2_PostEvent(&ev); externInvKey &= ~EBT_INVENTORYLEFT; } else if(i_ExternData->buttons&EBT_INVENTORYLEFT) { externInvKey |= EBT_INVENTORYLEFT; ev.type = ev_keydown; ev.data1 = key_invleft; H2_PostEvent(&ev); } if(i_ExternData->buttons&EBT_FLYDROP) { flyheight = TOCENTER; } if(gamestate == GS_LEVEL) { if(externInvKey&EBT_MAP) { // automap ev.type = ev_keyup; ev.data1 = AM_STARTKEY; H2_PostEvent(&ev); externInvKey &= ~EBT_MAP; } else if(i_ExternData->buttons&EBT_MAP) { externInvKey |= EBT_MAP; ev.type = ev_keydown; ev.data1 = AM_STARTKEY; H2_PostEvent(&ev); } } if(i_ExternData->buttons&EBT_WEAPONCYCLE) { int curWeapon; player_t *pl; pl = &players[consoleplayer]; curWeapon = pl->readyweapon; for(curWeapon = (curWeapon+1)&3; curWeapon != pl->readyweapon; curWeapon = (curWeapon+1)&3) { if(pl->weaponowned[curWeapon]) { cmd->buttons |= BT_CHANGE; cmd->buttons |= curWeapon<<BT_WEAPONSHIFT; break; } } } if(i_ExternData->buttons&EBT_JUMP) { cmd->arti |= AFLAG_JUMP; } }#endif // Fly up/down/drop keys if(gamekeydown[key_flyup]) { flyheight = 5; // note that the actual flyheight will be twice this } if(gamekeydown[key_flydown]) { flyheight = -5; } if(gamekeydown[key_flycenter]) { flyheight = TOCENTER;#ifdef __WATCOMC__ if(!useexterndriver) { look = TOCENTER; }#else look = TOCENTER;#endif } // Use artifact key if(gamekeydown[key_useartifact]) { if(gamekeydown[key_speed] && artiskip) { if(players[consoleplayer].inventory[inv_ptr].type != arti_none) { // Skip an artifact gamekeydown[key_useartifact] = false; P_PlayerNextArtifact(&players[consoleplayer]); } } else { if(inventory) { players[consoleplayer].readyArtifact = players[consoleplayer].inventory[inv_ptr].type; inventory = false; cmd->arti = 0; usearti = false; } else if(usearti) { cmd->arti |= players[consoleplayer].inventory[inv_ptr].type&AFLAG_MASK; usearti = false; } } } if(gamekeydown[key_jump] || mousebuttons[mousebjump] || joybuttons[joybjump]) { cmd->arti |= AFLAG_JUMP; } if(mn_SuicideConsole) { cmd->arti |= AFLAG_SUICIDE; mn_SuicideConsole = false; } // Artifact hot keys if(gamekeydown[KEY_BACKSPACE] && !cmd->arti) { gamekeydown[KEY_BACKSPACE] = false; // Use one of each artifact cmd->arti = NUMARTIFACTS; } else if(gamekeydown[KEY_BACKSLASH] && !cmd->arti && (players[consoleplayer].mo->health < MAXHEALTH)) { gamekeydown[KEY_BACKSLASH] = false; cmd->arti = arti_health; } else if(gamekeydown[KEY_ZERO] && !cmd->arti) { gamekeydown[KEY_ZERO] = false; cmd->arti = arti_poisonbag; } else if(gamekeydown[KEY_NINE] && !cmd->arti) { gamekeydown[KEY_NINE] = false; cmd->arti = arti_blastradius; } else if(gamekeydown[KEY_EIGHT] && !cmd->arti) { gamekeydown[KEY_EIGHT] = false; cmd->arti = arti_teleport; } else if(gamekeydown[KEY_SEVEN] && !cmd->arti) { gamekeydown[KEY_SEVEN] = false; cmd->arti = arti_teleportother; } else if(gamekeydown[KEY_SIX] && !cmd->arti) { gamekeydown[KEY_SIX] = false; cmd->arti = arti_egg; } else if(gamekeydown[KEY_FIVE] && !cmd->arti && !players[consoleplayer].powers[pw_invulnerability]) { gamekeydown[KEY_FIVE] = false; cmd->arti = arti_invulnerability; }//
// buttons
//
cmd->chatchar = CT_dequeueChatChar();
if (gamekeydown[key_fire] || mousebuttons[mousebfire]
|| joybuttons[joybfire])
cmd->buttons |= BT_ATTACK;
if (gamekeydown[key_use] || joybuttons[joybuse] )
{
cmd->buttons |= BT_USE;
dclicks = 0; // clear double clicks if hit use button
}
for(i = 0; i < NUMWEAPONS; i++) { if(gamekeydown['1'+i]) { cmd->buttons |= BT_CHANGE; cmd->buttons |= i<<BT_WEAPONSHIFT; break; } }//
// mouse
//
if (mousebuttons[mousebforward]) { forward += forwardmove[pClass][speed];
}
//
// forward double click
//
if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 )
{
dclickstate = mousebuttons[mousebforward];
if (dclickstate)
dclicks++;
if (dclicks == 2)
{
cmd->buttons |= BT_USE;
dclicks = 0;
}
else
dclicktime = 0;
}
else
{
dclicktime += ticdup;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -