12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015 |
- //**************************************************************************
- //**
- //** 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 functions
- extern void R_InitSky(int map);
- extern void P_PlayerNextArtifact(player_t *player);
- // Functions
- boolean 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 reborn
- int 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;
- #endif
- static 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;
- 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]);
- return;
- }
- }
- // no good spot, so the player will probably get stuck
- P_SpawnPlayer (&playerstarts[0][playernum]);
- }
- //==========================================================================
- //
- // G_DoReborn
- //
- //==========================================================================
- void G_DoReborn(int playernum)
- {
- int i;
- boolean oldWeaponowned[NUMWEAPONS];
- int oldKeys;
- int oldPieces;
- boolean foundSpot;
- int bestWeapon;
- if(G_CheckDemoStatus())
- {
- return;
- }
- if(!netgame)
- {
- if(SV_RebornSlotAvailable())
- { // Use the reborn code if the slot is available
- gameaction = ga_singlereborn;
- }
- else
- { // Start a new game if there's no reborn info
- gameaction = ga_newgame;
- }
- }
- else
- { // Net-game
- players[playernum].mo->player = NULL; // Dissassociate the corpse
- if(deathmatch)
- { // Spawn at random spot if in death match
- G_DeathMatchSpawnPlayer(playernum);
- return;
- }
- // Cooperative net-play, retain keys and weapons
- oldKeys = players[playernum].keys;
- oldPieces = players[playernum].pieces;
- for(i = 0; i < NUMWEAPONS; i++)
- {
- oldWeaponowned[i] = players[playernum].weaponowned[i];
- }
- foundSpot = false;
- if(G_CheckSpot(playernum,
- &playerstarts[RebornPosition][playernum]))
- { // Appropriate player start spot is open
- P_SpawnPlayer(&playerstarts[RebornPosition][playernum]);
- foundSpot = true;
- }
- else
- {
- // Try to spawn at one of the other player start spots
- for(i = 0; i < MAXPLAYERS; i++)
- {
- if(G_CheckSpot(playernum, &playerstarts[RebornPosition][i]))
- { // Found an open start spot
- // Fake as other player
- playerstarts[RebornPosition][i].type = playernum+1;
- P_SpawnPlayer(&playerstarts[RebornPosition][i]);
- // Restore proper player type
- playerstarts[RebornPosition][i].type = i+1;
-
- foundSpot = true;
- break;
- }
- }
- }
- if(foundSpot == false)
- { // Player's going to be inside something
- P_SpawnPlayer(&playerstarts[RebornPosition][playernum]);
- }
- // Restore keys and weapons
- players[playernum].keys = oldKeys;
- players[playernum].pieces = oldPieces;
- for(bestWeapon = 0, i = 0; i < NUMWEAPONS; i++)
- {
- if(oldWeaponowned[i])
- {
- bestWeapon = i;
- players[playernum].weaponowned[i] = true;
- }
- }
- players[playernum].mana[MANA_1] = 25;
- players[playernum].mana[MANA_2] = 25;
- if(bestWeapon)
- { // Bring up the best weapon
- players[playernum].pendingweapon = bestWeapon;
- }
- }
- }
- void G_ScreenShot (void)
- {
- gameaction = ga_screenshot;
- }
- //==========================================================================
- //
- // G_StartNewInit
- //
- //==========================================================================
- void G_StartNewInit(void)
- {
- SV_InitBaseSlot();
- SV_ClearRebornSlot();
- P_ACSInitNewGame();
- // Default the player start spot group to 0
- RebornPosition = 0;
- }
- //==========================================================================
- //
- // G_StartNewGame
- //
- //==========================================================================
- void G_StartNewGame(skill_t skill)
- {
- int realMap;
- G_StartNewInit();
- realMap = P_TranslateMap(1);
- if(realMap == -1)
- {
- realMap = 1;
- }
- G_InitNew(TempSkill, 1, realMap);
- }
- //==========================================================================
- //
- // G_TeleportNewMap
- //
- // Only called by the warp cheat code. Works just like normal map to map
- // teleporting, but doesn't do any interlude stuff.
- //
- //==========================================================================
- void G_TeleportNewMap(int map, int position)
- {
- gameaction = ga_leavemap;
- LeaveMap = map;
- LeavePosition = position;
- }
- //==========================================================================
- //
- // G_DoTeleportNewMap
- //
- //==========================================================================
- void G_DoTeleportNewMap(void)
- {
- SV_MapTeleport(LeaveMap, LeavePosition);
- gamestate = GS_LEVEL;
- gameaction = ga_nothing;
- RebornPosition = LeavePosition;
- }
- /*
- boolean secretexit;
- void G_ExitLevel (void)
- {
- secretexit = false;
- gameaction = ga_completed;
- }
- void G_SecretExitLevel (void)
- {
- secretexit = true;
- gameaction = ga_completed;
- }
- */
- //==========================================================================
- //
- // G_Completed
- //
- // Starts intermission routine, which is used only during hub exits,
- // and DeathMatch games.
- //==========================================================================
- void G_Completed(int map, int position)
- {
- gameaction = ga_completed;
- LeaveMap = map;
- LeavePosition = position;
- }
- void G_DoCompleted(void)
- {
- int i;
- gameaction = ga_nothing;
- if(G_CheckDemoStatus())
- {
- return;
- }
- for(i = 0; i < MAXPLAYERS; i++)
- {
- if(playeringame[i])
- {
- G_PlayerExitMap(i);
- }
- }
- if(LeaveMap == -1 && LeavePosition == -1)
- {
- gameaction = ga_victory;
- return;
- }
- else
- {
- gamestate = GS_INTERMISSION;
- IN_Start();
- }
- /*
- int i;
- static int afterSecret[3] = { 7, 5, 5 };
- gameaction = ga_nothing;
- if(G_CheckDemoStatus())
- {
- return;
- }
- for(i = 0; i < MAXPLAYERS; i++)
- {
- if(playeringame[i])
- {
- G_PlayerFinishLevel(i);
- }
- }
- prevmap = gamemap;
- if(secretexit == true)
- {
- gamemap = 9;
- }
- else if(gamemap == 9)
- { // Finished secret level
- gamemap = afterSecret[gameepisode-1];
- }
- else if(gamemap == 8)
- {
- gameaction = ga_victory;
- return;
- }
- else
- {
- gamemap++;
- }
- gamestate = GS_INTERMISSION;
- IN_Start();
- */
- }
- //============================================================================
- //
- // G_WorldDone
- //
- //============================================================================
- void G_WorldDone(void)
- {
- gameaction = ga_worlddone;
- }
- //============================================================================
- //
- // G_DoWorldDone
- //
- //============================================================================
- void G_DoWorldDone(void)
- {
- gamestate = GS_LEVEL;
- G_DoLoadLevel();
- gameaction = ga_nothing;
- viewactive = true;
- }
- //==========================================================================
- //
- // G_DoSingleReborn
- //
- // Called by G_Ticker based on gameaction. Loads a game from the reborn
- // save slot.
- //
- //==========================================================================
- void G_DoSingleReborn(void)
- {
- gameaction = ga_nothing;
- SV_LoadGame(SV_GetRebornSlot());
- SB_SetClassData();
- }
- //==========================================================================
- //
- // G_LoadGame
- //
- // Can be called by the startup code or the menu task.
- //
- //==========================================================================
- static int GameLoadSlot;
- void G_LoadGame(int slot)
- {
- GameLoadSlot = slot;
- gameaction = ga_loadgame;
- }
- //==========================================================================
- //
- // G_DoLoadGame
- //
- // Called by G_Ticker based on gameaction.
- //
- //==========================================================================
- void G_DoLoadGame(void)
- {
- gameaction = ga_nothing;
- SV_LoadGame(GameLoadSlot);
- if(!netgame)
- { // Copy the base slot to the reborn slot
- SV_UpdateRebornSlot();
- }
- SB_SetClassData();
- }
- //==========================================================================
- //
- // G_SaveGame
- //
- // Called by the menu task. <description> is a 24 byte text string.
- //
- //==========================================================================
- void G_SaveGame(int slot, char *description)
- {
- savegameslot = slot;
- strcpy(savedescription, description);
- sendsave = true;
- }
- //==========================================================================
- //
- // G_DoSaveGame
- //
- // Called by G_Ticker based on gameaction.
- //
- //==========================================================================
- void G_DoSaveGame(void)
- {
- SV_SaveGame(savegameslot, savedescription);
- gameaction = ga_nothing;
- savedescription[0] = 0;
- P_SetMessage(&players[consoleplayer], TXT_GAMESAVED, true);
- }
- //==========================================================================
- //
- // G_DeferredNewGame
- //
- //==========================================================================
- void G_DeferredNewGame(skill_t skill)
- {
- TempSkill = skill;
- gameaction = ga_newgame;
- }
- //==========================================================================
- //
- // G_DoNewGame
- //
- //==========================================================================
- void G_DoNewGame(void)
- {
- G_StartNewGame(TempSkill);
- gameaction = ga_nothing;
- }
- /*
- ====================
- =
- = G_InitNew
- =
- = Can be called by the startup code or the menu task
- = consoleplayer, displayplayer, playeringame[] should be set
- ====================
- */
- void G_DeferedInitNew(skill_t skill, int episode, int map)
- {
- TempSkill = skill;
- TempEpisode = episode;
- TempMap = map;
- gameaction = ga_initnew;
- }
- void G_DoInitNew(void)
- {
- SV_InitBaseSlot();
- G_InitNew(TempSkill, TempEpisode, TempMap);
- gameaction = ga_nothing;
- }
- void G_InitNew(skill_t skill, int episode, int map)
- {
- int i;
- if(paused)
- {
- paused = false;
- S_ResumeSound();
- }
- if(skill < sk_baby)
- {
- skill = sk_baby;
- }
- if(skill > sk_nightmare)
- {
- skill = sk_nightmare;
- }
- if(map < 1)
- {
- map = 1;
- }
- if(map > 99)
- {
- map = 99;
- }
- M_ClearRandom();
- // Force players to be initialized upon first level load
- for(i = 0; i < MAXPLAYERS; i++)
- {
- players[i].playerstate = PST_REBORN;
- players[i].worldTimer = 0;
- }
- // Set up a bunch of globals
- usergame = true; // will be set false if a demo
- paused = false;
- demorecording = false;
- demoplayback = false;
- viewactive = true;
- gameepisode = episode;
- gamemap = map;
- gameskill = skill;
- BorderNeedRefresh = true;
- // Initialize the sky
- R_InitSky(map);
- // Give one null ticcmd_t
- //gametic = 0;
- //maketic = 1;
- //for (i=0 ; i<MAXPLAYERS ; i++)
- // nettics[i] = 1; // one null event for this gametic
- //memset (localcmds,0,sizeof(localcmds));
- //memset (netcmds,0,sizeof(netcmds));
- G_DoLoadLevel();
- }
- /*
- ===============================================================================
- DEMO RECORDING
- ===============================================================================
- */
- #define DEMOMARKER 0x80
- void G_ReadDemoTiccmd (ticcmd_t *cmd)
- {
- if (*demo_p == DEMOMARKER)
- { // end of demo data stream
- G_CheckDemoStatus ();
- return;
- }
- cmd->forwardmove = ((signed char)*demo_p++);
- cmd->sidemove = ((signed char)*demo_p++);
- cmd->angleturn = ((unsigned char)*demo_p++)<<8;
- cmd->buttons = (unsigned char)*demo_p++;
- cmd->lookfly = (unsigned char)*demo_p++;
- cmd->arti = (unsigned char)*demo_p++;
- }
- void G_WriteDemoTiccmd (ticcmd_t *cmd)
- {
- if (gamekeydown['q']) // press q to end demo recording
- G_CheckDemoStatus ();
- *demo_p++ = cmd->forwardmove;
- *demo_p++ = cmd->sidemove;
- *demo_p++ = cmd->angleturn>>8;
- *demo_p++ = cmd->buttons;
- *demo_p++ = cmd->lookfly;
- *demo_p++ = cmd->arti;
- demo_p -= 6;
- G_ReadDemoTiccmd (cmd); // make SURE it is exactly the same
- }
- /*
- ===================
- =
- = G_RecordDemo
- =
- ===================
- */
- void G_RecordDemo (skill_t skill, int numplayers, int episode, int map, char *name)
- {
- int i;
-
- G_InitNew (skill, episode, map);
- usergame = false;
- strcpy (demoname, name);
- strcat (demoname, ".lmp");
- demobuffer = demo_p = Z_Malloc (0x20000,PU_STATIC,NULL);
- *demo_p++ = skill;
- *demo_p++ = episode;
- *demo_p++ = map;
-
- for (i=0 ; i<MAXPLAYERS ; i++)
- {
- *demo_p++ = playeringame[i];
- *demo_p++ = PlayerClass[i];
- }
- demorecording = true;
- }
- /*
- ===================
- =
- = G_PlayDemo
- =
- ===================
- */
- char *defdemoname;
- void G_DeferedPlayDemo (char *name)
- {
- defdemoname = name;
- gameaction = ga_playdemo;
- }
- void G_DoPlayDemo (void)
- {
- skill_t skill;
- int i, episode, map;
-
- gameaction = ga_nothing;
- demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC);
- skill = *demo_p++;
- episode = *demo_p++;
- map = *demo_p++;
- for (i=0 ; i<MAXPLAYERS ; i++)
- {
- playeringame[i] = *demo_p++;
- PlayerClass[i] = *demo_p++;
- }
- // Initialize world info, etc.
- G_StartNewInit();
- precache = false; // don't spend a lot of time in loadlevel
- G_InitNew (skill, episode, map);
- precache = true;
- usergame = false;
- demoplayback = true;
- }
- /*
- ===================
- =
- = G_TimeDemo
- =
- ===================
- */
- void G_TimeDemo (char *name)
- {
- skill_t skill;
- int episode, map;
-
- demobuffer = demo_p = W_CacheLumpName (name, PU_STATIC);
- skill = *demo_p++;
- episode = *demo_p++;
- map = *demo_p++;
- G_InitNew (skill, episode, map);
- usergame = false;
- demoplayback = true;
- timingdemo = true;
- singletics = true;
- }
- /*
- ===================
- =
- = G_CheckDemoStatus
- =
- = Called after a death or level completion to allow demos to be cleaned up
- = Returns true if a new demo loop action will take place
- ===================
- */
- boolean G_CheckDemoStatus (void)
- {
- int endtime;
-
- if (timingdemo)
- {
- endtime = I_GetTime ();
- I_Error ("timed %i gametics in %i realtics",gametic
- , endtime-starttime);
- }
-
- if (demoplayback)
- {
- if (singledemo)
- I_Quit ();
-
- Z_ChangeTag (demobuffer, PU_CACHE);
- demoplayback = false;
- H2_AdvanceDemo();
- return true;
- }
- if (demorecording)
- {
- *demo_p++ = DEMOMARKER;
- M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
- Z_Free (demobuffer);
- demorecording = false;
- I_Error ("Demo %s recorded",demoname);
- }
- return false;
- }
|