11 #define INVALID_PATCH 0
12 #define W_CacheLumpName(a,b) W_GetNumForName(a)
13 #define WR_CacheLumpNum(a,b) a
14 #define V_DrawPatch(x,y,p) OGL_DrawPatch(x,y,p)
15 #define V_DrawFuzzPatch(x,y,p) OGL_DrawFuzzPatch(x,y,p)
16 #define V_DrawAltFuzzPatch(x,y,p) OGL_DrawAltFuzzPatch(x,y,p)
18 #define PATCH_REF patch_t*
19 #define INVALID_PATCH 0
20 #define WR_CacheLumpNum(a,b) W_CacheLumpNum(a,b)
25 #define CHEAT_ENCRYPT(a) \
37 typedef struct Cheat_s
39 void (*func)(player_t *player, struct Cheat_s *cheat);
48 static void DrawSoundInfo(void);
49 static void ShadeLine(int x, int y, int height, int shade);
50 static void ShadeChain(void);
51 static void DrINumber(signed int val, int x, int y);
52 static void DrBNumber(signed int val, int x, int y);
53 static void DrawCommonBar(void);
54 static void DrawMainBar(void);
55 static void DrawInventoryBar(void);
56 static void DrawFullScreenStuff(void);
57 static boolean HandleCheats(byte key);
58 static boolean CheatAddKey(Cheat_t *cheat, byte key, boolean *eat);
59 static void CheatGodFunc(player_t *player, Cheat_t *cheat);
60 static void CheatNoClipFunc(player_t *player, Cheat_t *cheat);
61 static void CheatWeaponsFunc(player_t *player, Cheat_t *cheat);
62 static void CheatPowerFunc(player_t *player, Cheat_t *cheat);
63 static void CheatHealthFunc(player_t *player, Cheat_t *cheat);
64 static void CheatKeysFunc(player_t *player, Cheat_t *cheat);
65 static void CheatSoundFunc(player_t *player, Cheat_t *cheat);
66 static void CheatTickerFunc(player_t *player, Cheat_t *cheat);
67 static void CheatArtifact1Func(player_t *player, Cheat_t *cheat);
68 static void CheatArtifact2Func(player_t *player, Cheat_t *cheat);
69 static void CheatArtifact3Func(player_t *player, Cheat_t *cheat);
70 static void CheatWarpFunc(player_t *player, Cheat_t *cheat);
71 static void CheatChickenFunc(player_t *player, Cheat_t *cheat);
72 static void CheatMassacreFunc(player_t *player, Cheat_t *cheat);
73 static void CheatIDKFAFunc(player_t *player, Cheat_t *cheat);
74 static void CheatIDDQDFunc(player_t *player, Cheat_t *cheat);
78 boolean DebugSound; // debug flag for displaying sound info
87 static int HealthMarker;
88 static int ChainWiggle;
89 static player_t *CPlayer;
92 PATCH_REF PatchLTFACE;
93 PATCH_REF PatchRTFACE;
94 PATCH_REF PatchBARBACK;
96 PATCH_REF PatchSTATBAR;
97 PATCH_REF PatchLIFEGEM;
98 //PATCH_REF PatchEMPWEAP;
99 //PATCH_REF PatchLIL4BOX;
100 PATCH_REF PatchLTFCTOP;
101 PATCH_REF PatchRTFCTOP;
102 //PATCH_REF PatchARMORBOX;
103 //PATCH_REF PatchARTIBOX;
104 PATCH_REF PatchSELECTBOX;
105 //PATCH_REF PatchKILLSPIC;
106 //PATCH_REF PatchMANAPIC;
107 //PATCH_REF PatchPOWERICN;
108 PATCH_REF PatchINVLFGEM1;
109 PATCH_REF PatchINVLFGEM2;
110 PATCH_REF PatchINVRTGEM1;
111 PATCH_REF PatchINVRTGEM2;
112 PATCH_REF PatchINumbers[10];
113 PATCH_REF PatchNEGATIVE;
114 PATCH_REF PatchSmNumbers[10];
115 PATCH_REF PatchBLACKSQ;
116 PATCH_REF PatchINVBAR;
117 PATCH_REF PatchARMCLEAR;
118 PATCH_REF PatchCHAINBACK;
125 static byte CheatLookup[256];
128 static byte CheatGodSeq[] =
140 // Toggle no clipping mode
141 static byte CheatNoClipSeq[] =
151 // Get all weapons and ammo
152 static byte CheatWeaponsSeq[] =
162 // Toggle tome of power
163 static byte CheatPowerSeq[] =
175 static byte CheatHealthSeq[] =
186 static byte CheatKeysSeq[] =
195 // Toggle sound debug info
196 static byte CheatSoundSeq[] =
207 static byte CheatTickerSeq[] =
218 // Get an artifact 1st stage (ask for type)
219 static byte CheatArtifact1Seq[] =
229 // Get an artifact 2nd stage (ask for count)
230 static byte CheatArtifact2Seq[] =
240 // Get an artifact final stage
241 static byte CheatArtifact3Seq[] =
252 static byte CheatWarpSeq[] =
264 static byte CheatChickenSeq[] =
284 static byte CheatMassacreSeq[] =
297 static byte CheatIDKFASeq[] =
307 static byte CheatIDDQDSeq[] =
317 static Cheat_t Cheats[] =
319 { CheatGodFunc, CheatGodSeq, NULL, {0, 0}, 0 },
320 { CheatNoClipFunc, CheatNoClipSeq, NULL, {0, 0}, 0 },
321 { CheatWeaponsFunc, CheatWeaponsSeq, NULL, {0, 0}, 0 },
322 { CheatPowerFunc, CheatPowerSeq, NULL, {0, 0}, 0 },
323 { CheatHealthFunc, CheatHealthSeq, NULL, {0, 0}, 0 },
324 { CheatKeysFunc, CheatKeysSeq, NULL, {0, 0}, 0 },
325 { CheatSoundFunc, CheatSoundSeq, NULL, {0, 0}, 0 },
326 { CheatTickerFunc, CheatTickerSeq, NULL, {0, 0}, 0 },
327 { CheatArtifact1Func, CheatArtifact1Seq, NULL, {0, 0}, 0 },
328 { CheatArtifact2Func, CheatArtifact2Seq, NULL, {0, 0}, 0 },
329 { CheatArtifact3Func, CheatArtifact3Seq, NULL, {0, 0}, 0 },
330 { CheatWarpFunc, CheatWarpSeq, NULL, {0, 0}, 0 },
331 { CheatChickenFunc, CheatChickenSeq, NULL, {0, 0}, 0 },
332 { CheatMassacreFunc, CheatMassacreSeq, NULL, {0, 0}, 0 },
333 { CheatIDKFAFunc, CheatIDKFASeq, NULL, {0, 0}, 0 },
334 { CheatIDDQDFunc, CheatIDDQDSeq, NULL, {0, 0}, 0 },
335 { NULL, NULL, NULL, {0, 0}, 0 } // Terminator
338 //---------------------------------------------------------------------------
342 //---------------------------------------------------------------------------
349 PatchLTFACE = W_CacheLumpName("LTFACE", PU_STATIC);
350 PatchRTFACE = W_CacheLumpName("RTFACE", PU_STATIC);
351 PatchBARBACK = W_CacheLumpName("BARBACK", PU_STATIC);
352 PatchINVBAR = W_CacheLumpName("INVBAR", PU_STATIC);
353 PatchCHAIN = W_CacheLumpName("CHAIN", PU_STATIC);
356 PatchSTATBAR = W_CacheLumpName("STATBAR", PU_STATIC);
360 PatchSTATBAR = W_CacheLumpName("LIFEBAR", PU_STATIC);
363 { // single player game uses red life gem
364 PatchLIFEGEM = W_CacheLumpName("LIFEGEM2", PU_STATIC);
368 PatchLIFEGEM = WR_CacheLumpNum(W_GetNumForName("LIFEGEM0")
369 + consoleplayer, PU_STATIC);
371 PatchLTFCTOP = W_CacheLumpName("LTFCTOP", PU_STATIC);
372 PatchRTFCTOP = W_CacheLumpName("RTFCTOP", PU_STATIC);
373 PatchSELECTBOX = W_CacheLumpName("SELECTBOX", PU_STATIC);
374 PatchINVLFGEM1 = W_CacheLumpName("INVGEML1", PU_STATIC);
375 PatchINVLFGEM2 = W_CacheLumpName("INVGEML2", PU_STATIC);
376 PatchINVRTGEM1 = W_CacheLumpName("INVGEMR1", PU_STATIC);
377 PatchINVRTGEM2 = W_CacheLumpName("INVGEMR2", PU_STATIC);
378 PatchBLACKSQ = W_CacheLumpName("BLACKSQ", PU_STATIC);
379 PatchARMCLEAR = W_CacheLumpName("ARMCLEAR", PU_STATIC);
380 PatchCHAINBACK = W_CacheLumpName("CHAINBACK", PU_STATIC);
381 startLump = W_GetNumForName("IN0");
382 for(i = 0; i < 10; i++)
384 PatchINumbers[i] = WR_CacheLumpNum(startLump+i, PU_STATIC);
386 PatchNEGATIVE = W_CacheLumpName("NEGNUM", PU_STATIC);
387 FontBNumBase = W_GetNumForName("FONTB16");
388 startLump = W_GetNumForName("SMALLIN0");
389 for(i = 0; i < 10; i++)
391 PatchSmNumbers[i] = WR_CacheLumpNum(startLump+i, PU_STATIC);
393 playpalette = W_GetNumForName("PLAYPAL");
394 spinbooklump = W_GetNumForName("SPINBK0");
395 spinflylump = W_GetNumForName("SPFLY0");
396 for(i = 0; i < 256; i++)
398 CheatLookup[i] = CHEAT_ENCRYPT(i);
402 //---------------------------------------------------------------------------
406 //---------------------------------------------------------------------------
415 ChainWiggle = P_Random()&1;
417 curHealth = players[consoleplayer].mo->health;
422 if(curHealth < HealthMarker)
424 delta = (HealthMarker-curHealth)>>2;
433 HealthMarker -= delta;
435 else if(curHealth > HealthMarker)
437 delta = (curHealth-HealthMarker)>>2;
446 HealthMarker += delta;
450 //---------------------------------------------------------------------------
454 // Draws a three digit number.
456 //---------------------------------------------------------------------------
458 static void DrINumber(signed int val, int x, int y)
468 V_DrawPatch(x+1, y+1, W_CacheLumpName("LAME", PU_CACHE));
473 V_DrawPatch(x+18, y, PatchINumbers[val]);
474 V_DrawPatch(x+9, y, PatchNEGATIVE);
480 patch = PatchINumbers[val/100];
481 V_DrawPatch(x, y, patch);
484 if(val > 9 || oldval > 99)
486 patch = PatchINumbers[val/10];
487 V_DrawPatch(x+9, y, patch);
490 patch = PatchINumbers[val];
491 V_DrawPatch(x+18, y, patch);
494 //---------------------------------------------------------------------------
498 // Draws a three digit number using FontB
500 //---------------------------------------------------------------------------
502 static void DrBNumber(signed int val, int x, int y)
516 patch = W_CacheLumpNum(FontBNumBase+val/100, PU_CACHE);
518 OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/100);
520 V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
525 if(val > 9 || oldval > 99)
527 patch = W_CacheLumpNum(FontBNumBase+val/10, PU_CACHE);
529 OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/10);
531 V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
536 patch = W_CacheLumpNum(FontBNumBase+val, PU_CACHE);
538 OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/1);
540 V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
544 //---------------------------------------------------------------------------
546 // PROC DrSmallNumber
548 // Draws a small two digit number.
550 //---------------------------------------------------------------------------
552 static void DrSmallNumber(int val, int x, int y)
562 patch = PatchSmNumbers[val/10];
563 V_DrawPatch(x, y, patch);
566 patch = PatchSmNumbers[val];
567 V_DrawPatch(x+4, y, patch);
570 //---------------------------------------------------------------------------
574 //---------------------------------------------------------------------------
576 static void ShadeLine(int x, int y, int height, int shade)
581 shades = colormaps+9*256+shade*2*256;
582 dest = screen+y*SCREENWIDTH+x;
585 *(dest) = *(shades+*dest);
590 //---------------------------------------------------------------------------
594 //---------------------------------------------------------------------------
596 static void ShadeChain(void)
600 for(i = 0; i < 16; i++)
602 ShadeLine(277+i, 190, 10, i/2);
603 ShadeLine(19+i, 190, 10, 7-(i/2));
607 //---------------------------------------------------------------------------
609 // PROC DrawSoundInfo
611 // Displays sound debugging information.
613 //---------------------------------------------------------------------------
615 static void DrawSoundInfo(void)
623 int xPos[7] = {1, 75, 112, 156, 200, 230, 260};
627 MN_DrTextA("*** SOUND DEBUG INFO ***", xPos[0], 20);
629 S_GetChannelInfo(&s);
630 if(s.channelCount == 0)
635 MN_DrTextA("NAME", xPos[x++], 30);
636 MN_DrTextA("MO.T", xPos[x++], 30);
637 MN_DrTextA("MO.X", xPos[x++], 30);
638 MN_DrTextA("MO.Y", xPos[x++], 30);
639 MN_DrTextA("ID", xPos[x++], 30);
640 MN_DrTextA("PRI", xPos[x++], 30);
641 MN_DrTextA("DIST", xPos[x++], 30);
642 for(i = 0; i < s.channelCount; i++)
648 { // Channel is unused
649 MN_DrTextA("------", xPos[0], y);
652 sprintf(text, "%s", c->name);
653 M_ForceUppercase(text);
654 MN_DrTextA(text, xPos[x++], y);
655 sprintf(text, "%d", c->mo->type);
656 MN_DrTextA(text, xPos[x++], y);
657 sprintf(text, "%d", c->mo->x>>FRACBITS);
658 MN_DrTextA(text, xPos[x++], y);
659 sprintf(text, "%d", c->mo->y>>FRACBITS);
660 MN_DrTextA(text, xPos[x++], y);
661 sprintf(text, "%ld", c->id);
662 MN_DrTextA(text, xPos[x++], y);
663 sprintf(text, "%d", c->priority);
664 MN_DrTextA(text, xPos[x++], y);
665 sprintf(text, "%d", c->distance);
666 MN_DrTextA(text, xPos[x++], y);
668 UpdateState |= I_FULLSCRN;
669 BorderNeedRefresh = true;
672 //---------------------------------------------------------------------------
676 //---------------------------------------------------------------------------
678 char patcharti[][10] =
681 {"ARTIINVU"}, // invulnerability
682 {"ARTIINVS"}, // invisibility
683 {"ARTIPTN2"}, // health
684 {"ARTISPHL"}, // superhealth
685 {"ARTIPWBK"}, // tomeofpower
686 {"ARTITRCH"}, // torch
687 {"ARTIFBMB"}, // firebomb
690 {"ARTIATLP"} // teleport
704 static int oldfrags = -9999;
705 static int oldammo = -1;
706 static int oldarmor = -1;
707 static int oldweapon = -1;
708 static int oldhealth = -1;
709 static int oldlife = -1;
710 static int oldarti = 0;
711 static int oldartiCount = 0;
712 static int oldkeys = -1;
716 extern boolean automapactive;
721 static boolean hitCenterFrame;
723 // Sound info debug stuff
724 if(DebugSound == true)
728 CPlayer = &players[consoleplayer];
729 if(viewheight == SCREENHEIGHT && !automapactive)
731 DrawFullScreenStuff();
740 V_DrawPatch(0, 158, PatchBARBACK);
741 if(players[consoleplayer].cheats&CF_GODMODE)
743 V_DrawPatch(16, 167, W_CacheLumpName("GOD1", PU_CACHE));
744 V_DrawPatch(287, 167, W_CacheLumpName("GOD2", PU_CACHE));
758 V_DrawPatch(34, 160, PatchSTATBAR);
763 oldfrags = -9999; //can't use -1, 'cuz of negative frags
776 V_DrawPatch(34, 160, PatchINVBAR);
785 if(CPlayer->powers[pw_flight])
787 if(CPlayer->powers[pw_flight] > BLINKTHRESHOLD
788 || !(CPlayer->powers[pw_flight]&16))
790 frame = (leveltime/3)&15;
791 if(CPlayer->mo->flags2&MF2_FLY)
793 if(hitCenterFrame && (frame != 15 && frame != 0))
795 V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+15, PU_CACHE));
799 V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+frame, PU_CACHE));
800 hitCenterFrame = false;
805 if(!hitCenterFrame && (frame != 15 && frame != 0))
807 V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+frame, PU_CACHE));
808 hitCenterFrame = false;
812 V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+15, PU_CACHE));
813 hitCenterFrame = true;
816 BorderTopRefresh = true;
817 UpdateState |= I_MESSAGES;
821 BorderTopRefresh = true;
822 UpdateState |= I_MESSAGES;
826 if(CPlayer->powers[pw_weaponlevel2] && !CPlayer->chickenTics)
828 if(CPlayer->powers[pw_weaponlevel2] > BLINKTHRESHOLD
829 || !(CPlayer->powers[pw_weaponlevel2]&16))
831 frame = (leveltime/3)&15;
832 V_DrawPatch(300, 17, WR_CacheLumpNum(spinbooklump+frame, PU_CACHE));
833 BorderTopRefresh = true;
834 UpdateState |= I_MESSAGES;
838 BorderTopRefresh = true;
839 UpdateState |= I_MESSAGES;
843 if(CPlayer->powers[pw_weaponlevel2] > BLINKTHRESHOLD
844 || (CPlayer->powers[pw_weaponlevel2]&8))
846 V_DrawPatch(291, 0, W_CacheLumpName("ARTIPWBK", PU_CACHE));
850 BorderTopRefresh = true;
856 // sets the new palette based upon current values of player->damagecount
857 // and player->bonuscount
858 void SB_PaletteFlash(void)
860 static int sb_palette = 0;
866 CPlayer = &players[consoleplayer];
868 if(CPlayer->damagecount)
870 palette = (CPlayer->damagecount+7)>>3;
871 if(palette >= NUMREDPALS)
873 palette = NUMREDPALS-1;
875 palette += STARTREDPALS;
877 else if(CPlayer->bonuscount)
879 palette = (CPlayer->bonuscount+7)>>3;
880 if(palette >= NUMBONUSPALS)
882 palette = NUMBONUSPALS-1;
884 palette += STARTBONUSPALS;
890 if(palette != sb_palette)
892 sb_palette = palette;
894 OGL_SetFilter( palette );
896 pal = (byte *)WR_CacheLumpNum(playpalette, PU_CACHE)+palette*768;
902 //---------------------------------------------------------------------------
904 // PROC DrawCommonBar
906 //---------------------------------------------------------------------------
908 void DrawCommonBar(void)
913 V_DrawPatch(0, 148, PatchLTFCTOP);
914 V_DrawPatch(290, 148, PatchRTFCTOP);
917 if(oldhealth != HealthMarker)
919 oldhealth = HealthMarker;
921 healthPos = HealthMarker;
930 healthPos = (healthPos*256)/100;
931 chainY = (HealthMarker == CPlayer->mo->health) ? 191 : 191+ChainWiggle;
932 V_DrawPatch(0, 190, PatchCHAINBACK);
933 V_DrawPatch(2+(healthPos%17), chainY, PatchCHAIN);
934 V_DrawPatch(17+healthPos, chainY, PatchLIFEGEM);
935 V_DrawPatch(0, 190, PatchLTFACE);
936 V_DrawPatch(276, 190, PatchRTFACE);
939 UpdateState |= I_STATBAR;
944 //---------------------------------------------------------------------------
948 //---------------------------------------------------------------------------
950 void DrawMainBar(void)
959 V_DrawPatch(180, 161, PatchBLACKSQ);
961 V_DrawPatch(182, 161, WR_CacheLumpNum(W_GetNumForName("useartia") + ArtifactFlash - 1, PU_CACHE));
963 oldarti = -1; // so that the correct artifact fills in after the flash
964 UpdateState |= I_STATBAR;
966 else if(oldarti != CPlayer->readyArtifact
967 || oldartiCount != CPlayer->inventory[inv_ptr].count)
970 V_DrawPatch(180, 161, PatchBLACKSQ);
972 if(CPlayer->readyArtifact > 0)
974 V_DrawPatch(179,160, W_CacheLumpName(patcharti[CPlayer->readyArtifact],
976 DrSmallNumber(CPlayer->inventory[inv_ptr].count, 201, 182);
978 oldarti = CPlayer->readyArtifact;
979 oldartiCount = CPlayer->inventory[inv_ptr].count;
981 UpdateState |= I_STATBAR;
989 for(i = 0; i < MAXPLAYERS; i++)
991 temp += CPlayer->frags[i];
997 V_DrawPatch(57, 171, PatchARMCLEAR);
998 DrINumber(temp, 61, 170);
1001 UpdateState |= I_STATBAR;
1007 temp = HealthMarker;
1021 V_DrawPatch(57, 171, PatchARMCLEAR);
1022 DrINumber(temp, 61, 170);
1024 UpdateState |= I_STATBAR;
1031 if(oldkeys != playerkeys)
1034 if(CPlayer->keys[key_yellow])
1036 V_DrawPatch(153, 164, W_CacheLumpName("ykeyicon", PU_CACHE));
1038 if(CPlayer->keys[key_green])
1040 V_DrawPatch(153, 172, W_CacheLumpName("gkeyicon", PU_CACHE));
1042 if(CPlayer->keys[key_blue])
1044 V_DrawPatch(153, 180, W_CacheLumpName("bkeyicon", PU_CACHE));
1047 oldkeys = playerkeys;
1048 UpdateState |= I_STATBAR;
1052 temp = CPlayer->ammo[wpnlev1info[CPlayer->readyweapon].ammo];
1054 if(oldammo != temp || oldweapon != CPlayer->readyweapon)
1057 V_DrawPatch(108, 161, PatchBLACKSQ);
1058 if(temp && CPlayer->readyweapon > 0 && CPlayer->readyweapon < 7)
1060 DrINumber(temp, 109, 162);
1061 V_DrawPatch(111, 172, W_CacheLumpName(
1062 ammopic[CPlayer->readyweapon-1], PU_CACHE));
1066 oldweapon = CPlayer->readyweapon;
1067 UpdateState |= I_STATBAR;
1072 if(oldarmor != CPlayer->armorpoints)
1074 V_DrawPatch(224, 171, PatchARMCLEAR);
1075 DrINumber(CPlayer->armorpoints, 228, 170);
1076 oldarmor = CPlayer->armorpoints;
1077 UpdateState |= I_STATBAR;
1081 //---------------------------------------------------------------------------
1083 // PROC DrawInventoryBar
1085 //---------------------------------------------------------------------------
1087 void DrawInventoryBar(void)
1093 UpdateState |= I_STATBAR;
1094 V_DrawPatch(34, 160, PatchINVBAR);
1095 for(i = 0; i < 7; i++)
1097 //V_DrawPatch(50+i*31, 160, W_CacheLumpName("ARTIBOX", PU_CACHE));
1098 if(CPlayer->inventorySlotNum > x+i
1099 && CPlayer->inventory[x+i].type != arti_none)
1101 V_DrawPatch(50+i*31, 160, W_CacheLumpName(
1102 patcharti[CPlayer->inventory[x+i].type], PU_CACHE));
1103 DrSmallNumber(CPlayer->inventory[x+i].count, 69+i*31, 182);
1106 V_DrawPatch(50+curpos*31, 189, PatchSELECTBOX);
1109 V_DrawPatch(38, 159,!(leveltime&4) ? PatchINVLFGEM1 :
1112 if(CPlayer->inventorySlotNum-x > 7)
1114 V_DrawPatch(269, 159,!(leveltime&4) ?
1115 PatchINVRTGEM1 : PatchINVRTGEM2);
1119 void DrawFullScreenStuff(void)
1125 UpdateState |= I_FULLSCRN;
1126 if(CPlayer->mo->health > 0)
1128 DrBNumber(CPlayer->mo->health, 5, 180);
1132 DrBNumber(0, 5, 180);
1137 for(i=0; i<MAXPLAYERS; i++)
1141 temp += CPlayer->frags[i];
1144 DrINumber(temp, 45, 185);
1148 if(CPlayer->readyArtifact > 0)
1150 V_DrawFuzzPatch(286, 170, W_CacheLumpName("ARTIBOX",
1152 V_DrawPatch(286, 170,
1153 W_CacheLumpName(patcharti[CPlayer->readyArtifact], PU_CACHE));
1154 DrSmallNumber(CPlayer->inventory[inv_ptr].count, 307, 192);
1160 for(i = 0; i < 7; i++)
1162 V_DrawFuzzPatch(50+i*31, 168, W_CacheLumpName("ARTIBOX",
1164 if(CPlayer->inventorySlotNum > x+i
1165 && CPlayer->inventory[x+i].type != arti_none)
1167 V_DrawPatch(50+i*31, 168, W_CacheLumpName(
1168 patcharti[CPlayer->inventory[x+i].type], PU_CACHE));
1169 DrSmallNumber(CPlayer->inventory[x+i].count, 69+i*31, 190);
1172 V_DrawPatch(50+curpos*31, 197, PatchSELECTBOX);
1175 V_DrawPatch(38, 167, !(leveltime&4) ? PatchINVLFGEM1 :
1178 if(CPlayer->inventorySlotNum-x > 7)
1180 V_DrawPatch(269, 167, !(leveltime&4) ?
1181 PatchINVRTGEM1 : PatchINVRTGEM2);
1186 //--------------------------------------------------------------------------
1188 // FUNC SB_Responder
1190 //--------------------------------------------------------------------------
1192 boolean SB_Responder(event_t *event)
1194 if(event->type == ev_keydown)
1196 if(HandleCheats(event->data1))
1197 { // Need to eat the key
1204 //--------------------------------------------------------------------------
1206 // FUNC HandleCheats
1208 // Returns true if the caller should eat the key.
1210 //--------------------------------------------------------------------------
1212 static boolean HandleCheats(byte key)
1217 if(netgame || gameskill == sk_nightmare)
1218 { // Can't cheat in a net-game, or in nightmare mode
1221 if(players[consoleplayer].health <= 0)
1222 { // Dead players can't cheat
1226 for(i = 0; Cheats[i].func != NULL; i++)
1228 if(CheatAddKey(&Cheats[i], key, &eat))
1230 Cheats[i].func(&players[consoleplayer], &Cheats[i]);
1231 S_StartSound(NULL, sfx_dorcls);
1237 //--------------------------------------------------------------------------
1241 // Returns true if the added key completed the cheat, false otherwise.
1243 //--------------------------------------------------------------------------
1245 static boolean CheatAddKey(Cheat_t *cheat, byte key, boolean *eat)
1249 cheat->pos = cheat->sequence;
1250 cheat->currentArg = 0;
1252 if(*cheat->pos == 0)
1255 cheat->args[cheat->currentArg++] = key;
1258 else if(CheatLookup[key] == *cheat->pos)
1264 cheat->pos = cheat->sequence;
1265 cheat->currentArg = 0;
1267 if(*cheat->pos == 0xff)
1269 cheat->pos = cheat->sequence;
1270 cheat->currentArg = 0;
1276 //--------------------------------------------------------------------------
1280 //--------------------------------------------------------------------------
1282 static void CheatGodFunc(player_t *player, Cheat_t *cheat)
1284 player->cheats ^= CF_GODMODE;
1285 if(player->cheats&CF_GODMODE)
1287 P_SetMessage(player, TXT_CHEATGODON, false);
1291 P_SetMessage(player, TXT_CHEATGODOFF, false);
1296 static void CheatNoClipFunc(player_t *player, Cheat_t *cheat)
1298 player->cheats ^= CF_NOCLIP;
1299 if(player->cheats&CF_NOCLIP)
1301 P_SetMessage(player, TXT_CHEATNOCLIPON, false);
1305 P_SetMessage(player, TXT_CHEATNOCLIPOFF, false);
1309 static void CheatWeaponsFunc(player_t *player, Cheat_t *cheat)
1312 //extern boolean *WeaponInShareware;
1314 player->armorpoints = 200;
1315 player->armortype = 2;
1316 if(!player->backpack)
1318 for(i = 0; i < NUMAMMO; i++)
1320 player->maxammo[i] *= 2;
1322 player->backpack = true;
1324 for(i = 0; i < NUMWEAPONS-1; i++)
1326 player->weaponowned[i] = true;
1330 player->weaponowned[wp_skullrod] = false;
1331 player->weaponowned[wp_phoenixrod] = false;
1332 player->weaponowned[wp_mace] = false;
1334 for(i = 0; i < NUMAMMO; i++)
1336 player->ammo[i] = player->maxammo[i];
1338 P_SetMessage(player, TXT_CHEATWEAPONS, false);
1341 static void CheatPowerFunc(player_t *player, Cheat_t *cheat)
1343 if(player->powers[pw_weaponlevel2])
1345 player->powers[pw_weaponlevel2] = 0;
1346 P_SetMessage(player, TXT_CHEATPOWEROFF, false);
1350 P_UseArtifact(player, arti_tomeofpower);
1351 P_SetMessage(player, TXT_CHEATPOWERON, false);
1355 static void CheatHealthFunc(player_t *player, Cheat_t *cheat)
1357 if(player->chickenTics)
1359 player->health = player->mo->health = MAXCHICKENHEALTH;
1363 player->health = player->mo->health = MAXHEALTH;
1365 P_SetMessage(player, TXT_CHEATHEALTH, false);
1368 static void CheatKeysFunc(player_t *player, Cheat_t *cheat)
1370 extern int playerkeys;
1372 player->keys[key_yellow] = true;
1373 player->keys[key_green] = true;
1374 player->keys[key_blue] = true;
1375 playerkeys = 7; // Key refresh flags
1376 P_SetMessage(player, TXT_CHEATKEYS, false);
1379 static void CheatSoundFunc(player_t *player, Cheat_t *cheat)
1381 DebugSound = !DebugSound;
1384 P_SetMessage(player, TXT_CHEATSOUNDON, false);
1388 P_SetMessage(player, TXT_CHEATSOUNDOFF, false);
1392 static void CheatTickerFunc(player_t *player, Cheat_t *cheat)
1394 extern int DisplayTicker;
1396 DisplayTicker = !DisplayTicker;
1399 P_SetMessage(player, TXT_CHEATTICKERON, false);
1403 P_SetMessage(player, TXT_CHEATTICKEROFF, false);
1407 static void CheatArtifact1Func(player_t *player, Cheat_t *cheat)
1409 P_SetMessage(player, TXT_CHEATARTIFACTS1, false);
1412 static void CheatArtifact2Func(player_t *player, Cheat_t *cheat)
1414 P_SetMessage(player, TXT_CHEATARTIFACTS2, false);
1417 static void CheatArtifact3Func(player_t *player, Cheat_t *cheat)
1424 type = cheat->args[0]-'a'+1;
1425 count = cheat->args[1]-'0';
1426 if(type == 26 && count == 0)
1428 for(i = arti_none+1; i < NUMARTIFACTS; i++)
1430 if(shareware && (i == arti_superhealth
1431 || i == arti_teleport))
1435 for(j = 0; j < 16; j++)
1437 P_GiveArtifact(player, i, NULL);
1440 P_SetMessage(player, TXT_CHEATARTIFACTS3, false);
1442 else if(type > arti_none && type < NUMARTIFACTS
1443 && count > 0 && count < 10)
1445 if(shareware && (type == arti_superhealth || type == arti_teleport))
1447 P_SetMessage(player, TXT_CHEATARTIFACTSFAIL, false);
1450 for(i = 0; i < count; i++)
1452 P_GiveArtifact(player, type, NULL);
1454 P_SetMessage(player, TXT_CHEATARTIFACTS3, false);
1458 P_SetMessage(player, TXT_CHEATARTIFACTSFAIL, false);
1462 static void CheatWarpFunc(player_t *player, Cheat_t *cheat)
1467 episode = cheat->args[0]-'0';
1468 map = cheat->args[1]-'0';
1469 if(M_ValidEpisodeMap(episode, map))
1471 G_DeferedInitNew(gameskill, episode, map);
1472 P_SetMessage(player, TXT_CHEATWARP, false);
1476 static void CheatChickenFunc(player_t *player, Cheat_t *cheat)
1478 extern boolean P_UndoPlayerChicken(player_t *player);
1480 if(player->chickenTics)
1482 if(P_UndoPlayerChicken(player))
1484 P_SetMessage(player, TXT_CHEATCHICKENOFF, false);
1487 else if(P_ChickenMorphPlayer(player))
1489 P_SetMessage(player, TXT_CHEATCHICKENON, false);
1493 static void CheatMassacreFunc(player_t *player, Cheat_t *cheat)
1496 P_SetMessage(player, TXT_CHEATMASSACRE, false);
1499 static void CheatIDKFAFunc(player_t *player, Cheat_t *cheat)
1502 if(player->chickenTics)
1506 for(i = 1; i < 8; i++)
1508 player->weaponowned[i] = false;
1510 player->pendingweapon = wp_staff;
1511 P_SetMessage(player, TXT_CHEATIDKFA, true);
1514 static void CheatIDDQDFunc(player_t *player, Cheat_t *cheat)
1516 P_DamageMobj(player->mo, NULL, player->mo, 10000);
1517 P_SetMessage(player, TXT_CHEATIDDQD, true);