]> icculus.org git repositories - theoddone33/hheretic.git/blob - base/sb_bar.c
Initial revision
[theoddone33/hheretic.git] / base / sb_bar.c
1
2 // SB_bar.c
3
4 #include "doomdef.h"
5 #include "p_local.h"
6 #include "soundst.h"
7
8 #ifdef RENDER3D
9 #include "ogl_def.h"
10 #define PATCH_REF       int
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)
17 #else
18 #define PATCH_REF       patch_t*
19 #define INVALID_PATCH   0
20 #define WR_CacheLumpNum(a,b)        W_CacheLumpNum(a,b)
21 #endif
22
23 // Macros
24
25 #define CHEAT_ENCRYPT(a) \
26         ((((a)&1)<<5)+ \
27         (((a)&2)<<1)+ \
28         (((a)&4)<<4)+ \
29         (((a)&8)>>3)+ \
30         (((a)&16)>>3)+ \
31         (((a)&32)<<2)+ \
32         (((a)&64)>>2)+ \
33         (((a)&128)>>4))
34
35 // Types
36
37 typedef struct Cheat_s
38 {
39         void (*func)(player_t *player, struct Cheat_s *cheat);
40         byte *sequence;
41         byte *pos;
42         int args[2];
43         int currentArg;
44 } Cheat_t;
45
46 // Private Functions
47
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);
75
76 // Public Data
77
78 boolean DebugSound; // debug flag for displaying sound info
79
80 boolean inventory;
81 int curpos;
82 int inv_ptr;
83 int ArtifactFlash;
84
85 // Private Data
86
87 static int HealthMarker;
88 static int ChainWiggle;
89 static player_t *CPlayer;
90 int playpalette;
91
92 PATCH_REF PatchLTFACE;
93 PATCH_REF PatchRTFACE;
94 PATCH_REF PatchBARBACK;
95 PATCH_REF PatchCHAIN;
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;
119 //byte *ShadeTables;
120 extern byte *screen;
121 int FontBNumBase;
122 int spinbooklump;
123 int spinflylump;
124
125 static byte CheatLookup[256];
126
127 // Toggle god mode
128 static byte CheatGodSeq[] =
129 {
130         CHEAT_ENCRYPT('q'),
131         CHEAT_ENCRYPT('u'),
132         CHEAT_ENCRYPT('i'),
133         CHEAT_ENCRYPT('c'),
134         CHEAT_ENCRYPT('k'),
135         CHEAT_ENCRYPT('e'),
136         CHEAT_ENCRYPT('n'),
137         0xff
138 };
139
140 // Toggle no clipping mode
141 static byte CheatNoClipSeq[] =
142 {
143         CHEAT_ENCRYPT('k'),
144         CHEAT_ENCRYPT('i'),
145         CHEAT_ENCRYPT('t'),
146         CHEAT_ENCRYPT('t'),
147         CHEAT_ENCRYPT('y'),
148         0xff
149 };
150
151 // Get all weapons and ammo
152 static byte CheatWeaponsSeq[] =
153 {
154         CHEAT_ENCRYPT('r'),
155         CHEAT_ENCRYPT('a'),
156         CHEAT_ENCRYPT('m'),
157         CHEAT_ENCRYPT('b'),
158         CHEAT_ENCRYPT('o'),
159         0xff
160 };
161
162 // Toggle tome of power
163 static byte CheatPowerSeq[] =
164 {
165         CHEAT_ENCRYPT('s'),
166         CHEAT_ENCRYPT('h'),
167         CHEAT_ENCRYPT('a'),
168         CHEAT_ENCRYPT('z'),
169         CHEAT_ENCRYPT('a'),
170         CHEAT_ENCRYPT('m'),
171         0xff, 0
172 };
173
174 // Get full health
175 static byte CheatHealthSeq[] =
176 {
177         CHEAT_ENCRYPT('p'),
178         CHEAT_ENCRYPT('o'),
179         CHEAT_ENCRYPT('n'),
180         CHEAT_ENCRYPT('c'),
181         CHEAT_ENCRYPT('e'),
182         0xff
183 };
184
185 // Get all keys
186 static byte CheatKeysSeq[] =
187 {
188         CHEAT_ENCRYPT('s'),
189         CHEAT_ENCRYPT('k'),
190         CHEAT_ENCRYPT('e'),
191         CHEAT_ENCRYPT('l'),
192         0xff, 0
193 };
194
195 // Toggle sound debug info
196 static byte CheatSoundSeq[] =
197 {
198         CHEAT_ENCRYPT('n'),
199         CHEAT_ENCRYPT('o'),
200         CHEAT_ENCRYPT('i'),
201         CHEAT_ENCRYPT('s'),
202         CHEAT_ENCRYPT('e'),
203         0xff
204 };
205
206 // Toggle ticker
207 static byte CheatTickerSeq[] =
208 {
209         CHEAT_ENCRYPT('t'),
210         CHEAT_ENCRYPT('i'),
211         CHEAT_ENCRYPT('c'),
212         CHEAT_ENCRYPT('k'),
213         CHEAT_ENCRYPT('e'),
214         CHEAT_ENCRYPT('r'),
215         0xff, 0
216 };
217
218 // Get an artifact 1st stage (ask for type)
219 static byte CheatArtifact1Seq[] =
220 {
221         CHEAT_ENCRYPT('g'),
222         CHEAT_ENCRYPT('i'),
223         CHEAT_ENCRYPT('m'),
224         CHEAT_ENCRYPT('m'),
225         CHEAT_ENCRYPT('e'),
226         0xff
227 };
228
229 // Get an artifact 2nd stage (ask for count)
230 static byte CheatArtifact2Seq[] =
231 {
232         CHEAT_ENCRYPT('g'),
233         CHEAT_ENCRYPT('i'),
234         CHEAT_ENCRYPT('m'),
235         CHEAT_ENCRYPT('m'),
236         CHEAT_ENCRYPT('e'),
237         0, 0xff, 0
238 };
239
240 // Get an artifact final stage
241 static byte CheatArtifact3Seq[] =
242 {
243         CHEAT_ENCRYPT('g'),
244         CHEAT_ENCRYPT('i'),
245         CHEAT_ENCRYPT('m'),
246         CHEAT_ENCRYPT('m'),
247         CHEAT_ENCRYPT('e'),
248         0, 0, 0xff
249 };
250
251 // Warp to new level
252 static byte CheatWarpSeq[] =
253 {
254         CHEAT_ENCRYPT('e'),
255         CHEAT_ENCRYPT('n'),
256         CHEAT_ENCRYPT('g'),
257         CHEAT_ENCRYPT('a'),
258         CHEAT_ENCRYPT('g'),
259         CHEAT_ENCRYPT('e'),
260         0, 0, 0xff, 0
261 };
262
263 // Save a screenshot
264 static byte CheatChickenSeq[] =
265 {
266         CHEAT_ENCRYPT('c'),
267         CHEAT_ENCRYPT('o'),
268         CHEAT_ENCRYPT('c'),
269         CHEAT_ENCRYPT('k'),
270         CHEAT_ENCRYPT('a'),
271         CHEAT_ENCRYPT('d'),
272         CHEAT_ENCRYPT('o'),
273         CHEAT_ENCRYPT('o'),
274         CHEAT_ENCRYPT('d'),
275         CHEAT_ENCRYPT('l'),
276         CHEAT_ENCRYPT('e'),
277         CHEAT_ENCRYPT('d'),
278         CHEAT_ENCRYPT('o'),
279         CHEAT_ENCRYPT('o'),
280         0xff, 0
281 };
282
283 // Kill all monsters
284 static byte CheatMassacreSeq[] =
285 {
286         CHEAT_ENCRYPT('m'),
287         CHEAT_ENCRYPT('a'),
288         CHEAT_ENCRYPT('s'),
289         CHEAT_ENCRYPT('s'),
290         CHEAT_ENCRYPT('a'),
291         CHEAT_ENCRYPT('c'),
292         CHEAT_ENCRYPT('r'),
293         CHEAT_ENCRYPT('e'),
294         0xff, 0
295 };
296
297 static byte CheatIDKFASeq[] =
298 {
299         CHEAT_ENCRYPT('i'),
300         CHEAT_ENCRYPT('d'),
301         CHEAT_ENCRYPT('k'),
302         CHEAT_ENCRYPT('f'),
303         CHEAT_ENCRYPT('a'),
304         0xff, 0
305 };
306
307 static byte CheatIDDQDSeq[] =
308 {
309         CHEAT_ENCRYPT('i'),
310         CHEAT_ENCRYPT('d'),
311         CHEAT_ENCRYPT('d'),
312         CHEAT_ENCRYPT('q'),
313         CHEAT_ENCRYPT('d'),
314         0xff, 0
315 };
316
317 static Cheat_t Cheats[] =
318 {
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
336 };
337
338 //---------------------------------------------------------------------------
339 //
340 // PROC SB_Init
341 //
342 //---------------------------------------------------------------------------
343
344 void SB_Init(void)
345 {
346         int i;
347         int startLump;
348
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);
354         if(deathmatch)
355         {
356                 PatchSTATBAR = W_CacheLumpName("STATBAR", PU_STATIC);
357         }
358         else
359         {
360                 PatchSTATBAR = W_CacheLumpName("LIFEBAR", PU_STATIC);
361         }
362         if(!netgame)
363         { // single player game uses red life gem
364                 PatchLIFEGEM = W_CacheLumpName("LIFEGEM2", PU_STATIC);
365         }
366         else
367         {
368                 PatchLIFEGEM = WR_CacheLumpNum(W_GetNumForName("LIFEGEM0")
369                         + consoleplayer, PU_STATIC);
370         }
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++)
383         {
384                 PatchINumbers[i] = WR_CacheLumpNum(startLump+i, PU_STATIC);
385         }
386         PatchNEGATIVE = W_CacheLumpName("NEGNUM", PU_STATIC);
387         FontBNumBase = W_GetNumForName("FONTB16");
388         startLump = W_GetNumForName("SMALLIN0");
389         for(i = 0; i < 10; i++)
390         {
391                 PatchSmNumbers[i] = WR_CacheLumpNum(startLump+i, PU_STATIC);
392         }
393         playpalette = W_GetNumForName("PLAYPAL");
394         spinbooklump = W_GetNumForName("SPINBK0");
395         spinflylump = W_GetNumForName("SPFLY0");
396         for(i = 0; i < 256; i++)
397         {
398                 CheatLookup[i] = CHEAT_ENCRYPT(i);
399         }
400 }
401
402 //---------------------------------------------------------------------------
403 //
404 // PROC SB_Ticker
405 //
406 //---------------------------------------------------------------------------
407
408 void SB_Ticker(void)
409 {
410         int delta;
411         int curHealth;
412
413         if(leveltime&1)
414         {
415                 ChainWiggle = P_Random()&1;
416         }
417         curHealth = players[consoleplayer].mo->health;
418         if(curHealth < 0)
419         {
420                 curHealth = 0;
421         }
422         if(curHealth < HealthMarker)
423         {
424                 delta = (HealthMarker-curHealth)>>2;
425                 if(delta < 1)
426                 {
427                         delta = 1;
428                 }
429                 else if(delta > 8)
430                 {
431                         delta = 8;
432                 }
433                 HealthMarker -= delta;
434         }
435         else if(curHealth > HealthMarker)
436         {
437                 delta = (curHealth-HealthMarker)>>2;
438                 if(delta < 1)
439                 {
440                         delta = 1;
441                 }
442                 else if(delta > 8)
443                 {
444                         delta = 8;
445                 }
446                 HealthMarker += delta;
447         }
448 }
449
450 //---------------------------------------------------------------------------
451 //
452 // PROC DrINumber
453 //
454 // Draws a three digit number.
455 //
456 //---------------------------------------------------------------------------
457
458 static void DrINumber(signed int val, int x, int y)
459 {
460         PATCH_REF patch;
461         int oldval;
462
463         oldval = val;
464         if(val < 0)
465         {
466                 if(val < -9)
467                 {
468                         V_DrawPatch(x+1, y+1, W_CacheLumpName("LAME", PU_CACHE));
469                 }
470                 else
471                 {
472                         val = -val;
473                         V_DrawPatch(x+18, y, PatchINumbers[val]);
474                         V_DrawPatch(x+9, y, PatchNEGATIVE);
475                 }
476                 return;
477         }
478         if(val > 99)
479         {
480                 patch = PatchINumbers[val/100];
481                 V_DrawPatch(x, y, patch);
482         }
483         val = val%100;
484         if(val > 9 || oldval > 99)
485         {
486                 patch = PatchINumbers[val/10];
487                 V_DrawPatch(x+9, y, patch);
488         }
489         val = val%10;
490         patch = PatchINumbers[val];
491         V_DrawPatch(x+18, y, patch);
492 }
493
494 //---------------------------------------------------------------------------
495 //
496 // PROC DrBNumber
497 //
498 // Draws a three digit number using FontB
499 //
500 //---------------------------------------------------------------------------
501
502 static void DrBNumber(signed int val, int x, int y)
503 {
504         patch_t* patch;
505         int xpos;
506         int oldval;
507
508         oldval = val;
509         xpos = x;
510         if(val < 0)
511         {
512                 val = 0;
513         }
514         if(val > 99)
515         {
516                 patch = W_CacheLumpNum(FontBNumBase+val/100, PU_CACHE);
517 #ifdef RENDER3D
518         OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/100);
519 #else
520                 V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
521 #endif
522         }
523         val = val%100;
524         xpos += 12;
525         if(val > 9 || oldval > 99)
526         {
527                 patch = W_CacheLumpNum(FontBNumBase+val/10, PU_CACHE);
528 #ifdef RENDER3D
529         OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/10);
530 #else
531                 V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
532 #endif
533         }
534         val = val%10;
535         xpos += 12;
536         patch = W_CacheLumpNum(FontBNumBase+val, PU_CACHE);
537 #ifdef RENDER3D
538     OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/1);
539 #else
540         V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
541 #endif
542 }
543
544 //---------------------------------------------------------------------------
545 //
546 // PROC DrSmallNumber
547 //
548 // Draws a small two digit number.
549 //
550 //---------------------------------------------------------------------------
551
552 static void DrSmallNumber(int val, int x, int y)
553 {
554         PATCH_REF patch;
555
556         if(val == 1)
557         {
558                 return;
559         }
560         if(val > 9)
561         {
562                 patch = PatchSmNumbers[val/10];
563                 V_DrawPatch(x, y, patch);
564         }
565         val = val%10;
566         patch = PatchSmNumbers[val];
567         V_DrawPatch(x+4, y, patch);
568 }
569
570 //---------------------------------------------------------------------------
571 //
572 // PROC ShadeLine
573 //
574 //---------------------------------------------------------------------------
575
576 static void ShadeLine(int x, int y, int height, int shade)
577 {
578         byte *dest;
579         byte *shades;
580
581         shades = colormaps+9*256+shade*2*256;
582         dest = screen+y*SCREENWIDTH+x;
583         while(height--)
584         {
585                 *(dest) = *(shades+*dest);
586                 dest += SCREENWIDTH;
587         }
588 }
589
590 //---------------------------------------------------------------------------
591 //
592 // PROC ShadeChain
593 //
594 //---------------------------------------------------------------------------
595
596 static void ShadeChain(void)
597 {
598         int i;
599
600         for(i = 0; i < 16; i++)
601         {
602                 ShadeLine(277+i, 190, 10, i/2);
603                 ShadeLine(19+i, 190, 10, 7-(i/2));
604         }
605 }
606
607 //---------------------------------------------------------------------------
608 //
609 // PROC DrawSoundInfo
610 //
611 // Displays sound debugging information.
612 //
613 //---------------------------------------------------------------------------
614
615 static void DrawSoundInfo(void)
616 {
617         int i;
618         SoundInfo_t s;
619         ChanInfo_t *c;
620         char text[32];
621         int x;
622         int y;
623         int xPos[7] = {1, 75, 112, 156, 200, 230, 260};
624
625         if(leveltime&16)
626         {
627                 MN_DrTextA("*** SOUND DEBUG INFO ***", xPos[0], 20);
628         }
629         S_GetChannelInfo(&s);
630         if(s.channelCount == 0)
631         {
632                 return;
633         }
634         x = 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++)
643         {
644                 c = &s.chan[i];
645                 x = 0;
646                 y = 40+i*10;
647                 if(c->mo == NULL)
648                 { // Channel is unused
649                         MN_DrTextA("------", xPos[0], y);
650                         continue;
651                 }
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);
667         }
668         UpdateState |= I_FULLSCRN;
669         BorderNeedRefresh = true;
670 }
671
672 //---------------------------------------------------------------------------
673 //
674 // PROC SB_Drawer
675 //
676 //---------------------------------------------------------------------------
677
678 char patcharti[][10] =
679 {
680         {"ARTIBOX"},    // none
681         {"ARTIINVU"},   // invulnerability
682         {"ARTIINVS"},   // invisibility
683         {"ARTIPTN2"},   // health
684         {"ARTISPHL"},   // superhealth
685         {"ARTIPWBK"},   // tomeofpower
686         {"ARTITRCH"},   // torch
687         {"ARTIFBMB"},   // firebomb
688         {"ARTIEGGC"},   // egg
689         {"ARTISOAR"},   // fly
690         {"ARTIATLP"}    // teleport
691 };
692
693 char ammopic[][10] =
694 {
695         {"INAMGLD"},
696         {"INAMBOW"},
697         {"INAMBST"},
698         {"INAMRAM"},
699         {"INAMPNX"},
700         {"INAMLOB"}
701 };
702
703 int SB_state = -1;
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;
713
714 int playerkeys = 0;
715
716 extern boolean automapactive;
717
718 void SB_Drawer(void)
719 {
720         int frame;
721         static boolean hitCenterFrame;
722
723         // Sound info debug stuff
724         if(DebugSound == true)
725         {
726                 DrawSoundInfo();
727         }
728         CPlayer = &players[consoleplayer];
729         if(viewheight == SCREENHEIGHT && !automapactive)
730         {
731                 DrawFullScreenStuff();
732                 SB_state = -1;
733         }
734         else
735         {
736 #ifndef RENDER3D
737                 if(SB_state == -1)
738                 {
739 #endif
740                         V_DrawPatch(0, 158, PatchBARBACK);
741                         if(players[consoleplayer].cheats&CF_GODMODE)
742                         {
743                                 V_DrawPatch(16, 167, W_CacheLumpName("GOD1", PU_CACHE));
744                                 V_DrawPatch(287, 167, W_CacheLumpName("GOD2", PU_CACHE));
745                         }
746                         oldhealth = -1;
747 #ifndef RENDER3D
748                 }
749 #endif
750                 DrawCommonBar();
751                 if(!inventory)
752                 {
753 #ifndef RENDER3D
754                         if(SB_state != 0)
755                         {
756 #endif
757                                 // Main interface
758                                 V_DrawPatch(34, 160, PatchSTATBAR);
759                                 oldarti = 0;
760                                 oldammo = -1;
761                                 oldarmor = -1;
762                                 oldweapon = -1;
763                                 oldfrags = -9999; //can't use -1, 'cuz of negative frags
764                                 oldlife = -1;
765                                 oldkeys = -1;
766 #ifndef RENDER3D
767                         }
768 #endif
769                         DrawMainBar();
770                         SB_state = 0;
771                 }
772                 else
773                 {
774                         if(SB_state != 1)
775                         {
776                                 V_DrawPatch(34, 160, PatchINVBAR);
777                         }
778                         DrawInventoryBar();
779                         SB_state = 1;
780                 }
781         }
782         SB_PaletteFlash();
783
784         // Flight icons
785         if(CPlayer->powers[pw_flight])
786         {
787                 if(CPlayer->powers[pw_flight] > BLINKTHRESHOLD
788                         || !(CPlayer->powers[pw_flight]&16))
789                 {
790                         frame = (leveltime/3)&15;
791                         if(CPlayer->mo->flags2&MF2_FLY)
792                         {
793                                 if(hitCenterFrame && (frame != 15 && frame != 0))
794                                 {
795                                         V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+15, PU_CACHE));
796                                 }
797                                 else
798                                 {
799                                         V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+frame, PU_CACHE));
800                                         hitCenterFrame = false;
801                                 }
802                         }
803                         else
804                         {
805                                 if(!hitCenterFrame && (frame != 15 && frame != 0))
806                                 {
807                                         V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+frame, PU_CACHE));
808                                         hitCenterFrame = false;
809                                 }
810                                 else
811                                 {
812                                         V_DrawPatch(20, 17, WR_CacheLumpNum(spinflylump+15, PU_CACHE));
813                                         hitCenterFrame = true;
814                                 }
815                         }
816                         BorderTopRefresh = true;
817                         UpdateState |= I_MESSAGES;
818                 }
819                 else
820                 {
821                         BorderTopRefresh = true;
822                         UpdateState |= I_MESSAGES;
823                 }
824         }
825
826         if(CPlayer->powers[pw_weaponlevel2] && !CPlayer->chickenTics)
827         {
828                 if(CPlayer->powers[pw_weaponlevel2] > BLINKTHRESHOLD
829                         || !(CPlayer->powers[pw_weaponlevel2]&16))
830                 {
831                         frame = (leveltime/3)&15;
832                         V_DrawPatch(300, 17, WR_CacheLumpNum(spinbooklump+frame, PU_CACHE));
833                         BorderTopRefresh = true;
834                         UpdateState |= I_MESSAGES;
835                 }
836                 else
837                 {
838                         BorderTopRefresh = true;
839                         UpdateState |= I_MESSAGES;
840                 }
841         }
842 /*
843                 if(CPlayer->powers[pw_weaponlevel2] > BLINKTHRESHOLD
844                         || (CPlayer->powers[pw_weaponlevel2]&8))
845                 {
846                         V_DrawPatch(291, 0, W_CacheLumpName("ARTIPWBK", PU_CACHE));
847                 }
848                 else
849                 {
850                         BorderTopRefresh = true;
851                 }
852         }
853 */
854 }
855
856 // sets the new palette based upon current values of player->damagecount
857 // and player->bonuscount
858 void SB_PaletteFlash(void)
859 {
860         static int sb_palette = 0;
861         int palette;
862 #ifndef RENDER3D
863         byte *pal;
864 #endif
865
866         CPlayer = &players[consoleplayer];
867
868         if(CPlayer->damagecount)
869         {
870                 palette = (CPlayer->damagecount+7)>>3;
871                 if(palette >= NUMREDPALS)
872                 {
873                         palette = NUMREDPALS-1;
874                 }
875                 palette += STARTREDPALS;
876         }
877         else if(CPlayer->bonuscount)
878         {
879                 palette = (CPlayer->bonuscount+7)>>3;
880                 if(palette >= NUMBONUSPALS)
881                 {
882                         palette = NUMBONUSPALS-1;
883                 }
884                 palette += STARTBONUSPALS;
885         }
886         else
887         {
888                 palette = 0;
889         }
890         if(palette != sb_palette)
891         {
892                 sb_palette = palette;
893 #ifdef RENDER3D
894         OGL_SetFilter( palette );
895 #else
896                 pal = (byte *)WR_CacheLumpNum(playpalette, PU_CACHE)+palette*768;
897                 I_SetPalette(pal);
898 #endif
899         }
900 }
901
902 //---------------------------------------------------------------------------
903 //
904 // PROC DrawCommonBar
905 //
906 //---------------------------------------------------------------------------
907
908 void DrawCommonBar(void)
909 {
910         int chainY;
911         int healthPos;
912
913         V_DrawPatch(0, 148, PatchLTFCTOP);
914         V_DrawPatch(290, 148, PatchRTFCTOP);
915
916 #ifndef RENDER3D
917         if(oldhealth != HealthMarker)
918         {
919                 oldhealth = HealthMarker;
920 #endif
921                 healthPos = HealthMarker;
922                 if(healthPos < 0)
923                 {
924                         healthPos = 0;
925                 }
926                 if(healthPos > 100)
927                 {
928                         healthPos = 100;
929                 }
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);
937                 ShadeChain();
938 #ifndef RENDER3D
939                 UpdateState |= I_STATBAR;
940         }
941 #endif
942 }
943
944 //---------------------------------------------------------------------------
945 //
946 // PROC DrawMainBar
947 //
948 //---------------------------------------------------------------------------
949
950 void DrawMainBar(void)
951 {
952         int i;
953         int temp;
954
955         // Ready artifact
956         if(ArtifactFlash)
957         {
958 #ifndef RENDER3D
959                 V_DrawPatch(180, 161, PatchBLACKSQ);
960 #endif
961                 V_DrawPatch(182, 161, WR_CacheLumpNum(W_GetNumForName("useartia") + ArtifactFlash - 1, PU_CACHE));
962                 ArtifactFlash--;
963                 oldarti = -1; // so that the correct artifact fills in after the flash
964                 UpdateState |= I_STATBAR;
965         }
966         else if(oldarti != CPlayer->readyArtifact
967                 || oldartiCount != CPlayer->inventory[inv_ptr].count)
968         {
969 #ifndef RENDER3D
970                 V_DrawPatch(180, 161, PatchBLACKSQ);
971 #endif
972                 if(CPlayer->readyArtifact > 0)
973                 {
974                         V_DrawPatch(179,160, W_CacheLumpName(patcharti[CPlayer->readyArtifact],
975                                 PU_CACHE));
976                         DrSmallNumber(CPlayer->inventory[inv_ptr].count, 201, 182);
977                 }
978                 oldarti = CPlayer->readyArtifact;
979                 oldartiCount = CPlayer->inventory[inv_ptr].count;
980 #ifndef RENDER3D
981                 UpdateState |= I_STATBAR;
982 #endif
983         }
984
985         // Frags
986         if(deathmatch)
987         {
988                 temp = 0;
989                 for(i = 0; i < MAXPLAYERS; i++)
990                 {
991                         temp += CPlayer->frags[i];
992                 }
993 #ifndef RENDER3D
994                 if(temp != oldfrags)
995                 {
996 #endif
997                         V_DrawPatch(57, 171, PatchARMCLEAR);
998                         DrINumber(temp, 61, 170);
999 #ifndef RENDER3D
1000                         oldfrags = temp;
1001                         UpdateState |= I_STATBAR;
1002                 }
1003 #endif
1004         }
1005         else
1006         {
1007                 temp = HealthMarker;
1008                 if(temp < 0)
1009                 {
1010                         temp = 0;
1011                 }
1012                 else if(temp > 100)
1013                 {
1014                         temp = 100;
1015                 }
1016 #ifndef RENDER3D
1017                 if(oldlife != temp)
1018                 {
1019                         oldlife = temp;
1020 #endif
1021                         V_DrawPatch(57, 171, PatchARMCLEAR);
1022                         DrINumber(temp, 61, 170);
1023 #ifndef RENDER3D
1024                         UpdateState |= I_STATBAR;
1025                 }
1026 #endif
1027         }
1028
1029         // Keys
1030 #ifndef RENDER3D
1031         if(oldkeys != playerkeys)
1032         {
1033 #endif
1034                 if(CPlayer->keys[key_yellow])
1035                 {
1036                         V_DrawPatch(153, 164, W_CacheLumpName("ykeyicon", PU_CACHE));
1037                 }
1038                 if(CPlayer->keys[key_green])
1039                 {
1040                         V_DrawPatch(153, 172, W_CacheLumpName("gkeyicon", PU_CACHE));
1041                 }
1042                 if(CPlayer->keys[key_blue])
1043                 {
1044                         V_DrawPatch(153, 180, W_CacheLumpName("bkeyicon", PU_CACHE));
1045                 }
1046 #ifndef RENDER3D
1047                 oldkeys = playerkeys;
1048                 UpdateState |= I_STATBAR;
1049         }
1050 #endif
1051         // Ammo
1052         temp = CPlayer->ammo[wpnlev1info[CPlayer->readyweapon].ammo];
1053 #ifndef RENDER3D
1054         if(oldammo != temp || oldweapon != CPlayer->readyweapon)
1055         {
1056 #endif
1057                 V_DrawPatch(108, 161, PatchBLACKSQ);
1058                 if(temp && CPlayer->readyweapon > 0 && CPlayer->readyweapon < 7)
1059                 {
1060                         DrINumber(temp, 109, 162);
1061                         V_DrawPatch(111, 172, W_CacheLumpName(
1062                                 ammopic[CPlayer->readyweapon-1], PU_CACHE));
1063                 }
1064 #ifndef RENDER3D
1065                 oldammo = temp;
1066                 oldweapon = CPlayer->readyweapon;
1067                 UpdateState |= I_STATBAR;
1068         }
1069 #endif
1070
1071         // Armor
1072         if(oldarmor != CPlayer->armorpoints)
1073         {
1074                 V_DrawPatch(224, 171, PatchARMCLEAR);
1075                 DrINumber(CPlayer->armorpoints, 228, 170);
1076                 oldarmor = CPlayer->armorpoints;
1077                 UpdateState |= I_STATBAR;
1078         }
1079 }
1080
1081 //---------------------------------------------------------------------------
1082 //
1083 // PROC DrawInventoryBar
1084 //
1085 //---------------------------------------------------------------------------
1086
1087 void DrawInventoryBar(void)
1088 {
1089         int i;
1090         int x;
1091
1092         x = inv_ptr-curpos;
1093         UpdateState |= I_STATBAR;
1094         V_DrawPatch(34, 160, PatchINVBAR);
1095         for(i = 0; i < 7; i++)
1096         {
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)
1100                 {
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);
1104                 }
1105         }
1106         V_DrawPatch(50+curpos*31, 189, PatchSELECTBOX);
1107         if(x != 0)
1108         {
1109                 V_DrawPatch(38, 159,!(leveltime&4) ? PatchINVLFGEM1 :
1110                         PatchINVLFGEM2);
1111         }
1112         if(CPlayer->inventorySlotNum-x > 7)
1113         {
1114                 V_DrawPatch(269, 159,!(leveltime&4) ?
1115                         PatchINVRTGEM1 : PatchINVRTGEM2);
1116         }
1117 }
1118
1119 void DrawFullScreenStuff(void)
1120 {
1121         int i;
1122         int x;
1123         int temp;
1124
1125         UpdateState |= I_FULLSCRN;
1126         if(CPlayer->mo->health > 0)
1127         {
1128                 DrBNumber(CPlayer->mo->health, 5, 180);
1129         }
1130         else
1131         {
1132                 DrBNumber(0, 5, 180);
1133         }
1134         if(deathmatch)
1135         {
1136                 temp = 0;
1137                 for(i=0; i<MAXPLAYERS; i++)
1138                 {
1139                         if(playeringame[i])
1140                         {
1141                                 temp += CPlayer->frags[i];
1142                         }
1143                 }
1144                 DrINumber(temp, 45, 185);
1145         }
1146         if(!inventory)
1147         {
1148                 if(CPlayer->readyArtifact > 0)
1149                 {
1150                         V_DrawFuzzPatch(286, 170, W_CacheLumpName("ARTIBOX",
1151                                 PU_CACHE));
1152                         V_DrawPatch(286, 170,
1153                                 W_CacheLumpName(patcharti[CPlayer->readyArtifact], PU_CACHE));
1154                         DrSmallNumber(CPlayer->inventory[inv_ptr].count, 307, 192);
1155                 }
1156         }
1157         else
1158         {
1159                 x = inv_ptr-curpos;
1160                 for(i = 0; i < 7; i++)
1161                 {
1162                         V_DrawFuzzPatch(50+i*31, 168, W_CacheLumpName("ARTIBOX",
1163                                 PU_CACHE));
1164                         if(CPlayer->inventorySlotNum > x+i
1165                                 && CPlayer->inventory[x+i].type != arti_none)
1166                         {
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);
1170                         }
1171                 }
1172                 V_DrawPatch(50+curpos*31, 197, PatchSELECTBOX);
1173                 if(x != 0)
1174                 {
1175                         V_DrawPatch(38, 167, !(leveltime&4) ? PatchINVLFGEM1 :
1176                                 PatchINVLFGEM2);
1177                 }
1178                 if(CPlayer->inventorySlotNum-x > 7)
1179                 {
1180                         V_DrawPatch(269, 167, !(leveltime&4) ?
1181                                 PatchINVRTGEM1 : PatchINVRTGEM2);
1182                 }
1183         }
1184 }
1185
1186 //--------------------------------------------------------------------------
1187 //
1188 // FUNC SB_Responder
1189 //
1190 //--------------------------------------------------------------------------
1191
1192 boolean SB_Responder(event_t *event)
1193 {
1194         if(event->type == ev_keydown)
1195         {
1196                 if(HandleCheats(event->data1))
1197                 { // Need to eat the key
1198                         return(true);
1199                 }
1200         }
1201         return(false);
1202 }
1203
1204 //--------------------------------------------------------------------------
1205 //
1206 // FUNC HandleCheats
1207 //
1208 // Returns true if the caller should eat the key.
1209 //
1210 //--------------------------------------------------------------------------
1211
1212 static boolean HandleCheats(byte key)
1213 {
1214         int i;
1215         boolean eat;
1216
1217         if(netgame || gameskill == sk_nightmare)
1218         { // Can't cheat in a net-game, or in nightmare mode
1219                 return(false);
1220         }
1221         if(players[consoleplayer].health <= 0)
1222         { // Dead players can't cheat
1223                 return(false);
1224         }
1225         eat = false;
1226         for(i = 0; Cheats[i].func != NULL; i++)
1227         {
1228                 if(CheatAddKey(&Cheats[i], key, &eat))
1229                 {
1230                         Cheats[i].func(&players[consoleplayer], &Cheats[i]);
1231                         S_StartSound(NULL, sfx_dorcls);
1232                 }
1233         }
1234         return(eat);
1235 }
1236
1237 //--------------------------------------------------------------------------
1238 //
1239 // FUNC CheatAddkey
1240 //
1241 // Returns true if the added key completed the cheat, false otherwise.
1242 //
1243 //--------------------------------------------------------------------------
1244
1245 static boolean CheatAddKey(Cheat_t *cheat, byte key, boolean *eat)
1246 {
1247         if(!cheat->pos)
1248         {
1249                 cheat->pos = cheat->sequence;
1250                 cheat->currentArg = 0;
1251         }
1252         if(*cheat->pos == 0)
1253         {
1254                 *eat = true;
1255                 cheat->args[cheat->currentArg++] = key;
1256                 cheat->pos++;
1257         }
1258         else if(CheatLookup[key] == *cheat->pos)
1259         {
1260                 cheat->pos++;
1261         }
1262         else
1263         {
1264                 cheat->pos = cheat->sequence;
1265                 cheat->currentArg = 0;
1266         }
1267         if(*cheat->pos == 0xff)
1268         {
1269                 cheat->pos = cheat->sequence;
1270                 cheat->currentArg = 0;
1271                 return(true);
1272         }
1273         return(false);
1274 }
1275
1276 //--------------------------------------------------------------------------
1277 //
1278 // CHEAT FUNCTIONS
1279 //
1280 //--------------------------------------------------------------------------
1281
1282 static void CheatGodFunc(player_t *player, Cheat_t *cheat)
1283 {
1284         player->cheats ^= CF_GODMODE;
1285         if(player->cheats&CF_GODMODE)
1286         {
1287                 P_SetMessage(player, TXT_CHEATGODON, false);
1288         }
1289         else
1290         {
1291                 P_SetMessage(player, TXT_CHEATGODOFF, false);
1292         }
1293         SB_state = -1;
1294 }
1295
1296 static void CheatNoClipFunc(player_t *player, Cheat_t *cheat)
1297 {
1298         player->cheats ^= CF_NOCLIP;
1299         if(player->cheats&CF_NOCLIP)
1300         {
1301                 P_SetMessage(player, TXT_CHEATNOCLIPON, false);
1302         }
1303         else
1304         {
1305                 P_SetMessage(player, TXT_CHEATNOCLIPOFF, false);
1306         }
1307 }
1308
1309 static void CheatWeaponsFunc(player_t *player, Cheat_t *cheat)
1310 {
1311         int i;
1312         //extern boolean *WeaponInShareware;
1313
1314         player->armorpoints = 200;
1315         player->armortype = 2;
1316         if(!player->backpack)
1317         {
1318                 for(i = 0; i < NUMAMMO; i++)
1319                 {
1320                         player->maxammo[i] *= 2;
1321                 }
1322                 player->backpack = true;
1323         }
1324         for(i = 0; i < NUMWEAPONS-1; i++)
1325         {
1326                 player->weaponowned[i] = true;
1327         }
1328         if(shareware)
1329         {
1330                 player->weaponowned[wp_skullrod] = false;
1331                 player->weaponowned[wp_phoenixrod] = false;
1332                 player->weaponowned[wp_mace] = false;
1333         }
1334         for(i = 0; i < NUMAMMO; i++)
1335         {
1336                 player->ammo[i] = player->maxammo[i];
1337         }
1338         P_SetMessage(player, TXT_CHEATWEAPONS, false);
1339 }
1340
1341 static void CheatPowerFunc(player_t *player, Cheat_t *cheat)
1342 {
1343         if(player->powers[pw_weaponlevel2])
1344         {
1345                 player->powers[pw_weaponlevel2] = 0;
1346                 P_SetMessage(player, TXT_CHEATPOWEROFF, false);
1347         }
1348         else
1349         {
1350                 P_UseArtifact(player, arti_tomeofpower);
1351                 P_SetMessage(player, TXT_CHEATPOWERON, false);
1352         }
1353 }
1354
1355 static void CheatHealthFunc(player_t *player, Cheat_t *cheat)
1356 {
1357         if(player->chickenTics)
1358         {
1359                 player->health = player->mo->health = MAXCHICKENHEALTH;
1360         }
1361         else
1362         {
1363                 player->health = player->mo->health = MAXHEALTH;
1364         }
1365         P_SetMessage(player, TXT_CHEATHEALTH, false);
1366 }
1367
1368 static void CheatKeysFunc(player_t *player, Cheat_t *cheat)
1369 {
1370         extern int playerkeys;
1371
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);
1377 }
1378
1379 static void CheatSoundFunc(player_t *player, Cheat_t *cheat)
1380 {
1381         DebugSound = !DebugSound;
1382         if(DebugSound)
1383         {
1384                 P_SetMessage(player, TXT_CHEATSOUNDON, false);
1385         }
1386         else
1387         {
1388                 P_SetMessage(player, TXT_CHEATSOUNDOFF, false);
1389         }
1390 }
1391
1392 static void CheatTickerFunc(player_t *player, Cheat_t *cheat)
1393 {
1394         extern int DisplayTicker;
1395
1396         DisplayTicker = !DisplayTicker;
1397         if(DisplayTicker)
1398         {
1399                 P_SetMessage(player, TXT_CHEATTICKERON, false);
1400         }
1401         else
1402         {
1403                 P_SetMessage(player, TXT_CHEATTICKEROFF, false);
1404         }
1405 }
1406
1407 static void CheatArtifact1Func(player_t *player, Cheat_t *cheat)
1408 {
1409         P_SetMessage(player, TXT_CHEATARTIFACTS1, false);
1410 }
1411
1412 static void CheatArtifact2Func(player_t *player, Cheat_t *cheat)
1413 {
1414         P_SetMessage(player, TXT_CHEATARTIFACTS2, false);
1415 }
1416
1417 static void CheatArtifact3Func(player_t *player, Cheat_t *cheat)
1418 {
1419         int i;
1420         int j;
1421         artitype_t type;
1422         int count;
1423
1424         type = cheat->args[0]-'a'+1;
1425         count = cheat->args[1]-'0';
1426         if(type == 26 && count == 0)
1427         { // All artifacts
1428                 for(i = arti_none+1; i < NUMARTIFACTS; i++)
1429                 {
1430                         if(shareware && (i == arti_superhealth
1431                                 || i == arti_teleport))
1432                         {
1433                                 continue;
1434                         }
1435                         for(j = 0; j < 16; j++)
1436                         {
1437                                 P_GiveArtifact(player, i, NULL);
1438                         }
1439                 }
1440                 P_SetMessage(player, TXT_CHEATARTIFACTS3, false);
1441         }
1442         else if(type > arti_none && type < NUMARTIFACTS
1443                 && count > 0 && count < 10)
1444         {
1445                 if(shareware && (type == arti_superhealth || type == arti_teleport))
1446                 {
1447                         P_SetMessage(player, TXT_CHEATARTIFACTSFAIL, false);
1448                         return;
1449                 }
1450                 for(i = 0; i < count; i++)
1451                 {
1452                         P_GiveArtifact(player, type, NULL);
1453                 }
1454                 P_SetMessage(player, TXT_CHEATARTIFACTS3, false);
1455         }
1456         else
1457         { // Bad input
1458                 P_SetMessage(player, TXT_CHEATARTIFACTSFAIL, false);
1459         }
1460 }
1461
1462 static void CheatWarpFunc(player_t *player, Cheat_t *cheat)
1463 {
1464         int episode;
1465         int map;
1466
1467         episode = cheat->args[0]-'0';
1468         map = cheat->args[1]-'0';
1469         if(M_ValidEpisodeMap(episode, map))
1470         {
1471                 G_DeferedInitNew(gameskill, episode, map);
1472                 P_SetMessage(player, TXT_CHEATWARP, false);
1473         }
1474 }
1475
1476 static void CheatChickenFunc(player_t *player, Cheat_t *cheat)
1477 {
1478         extern boolean P_UndoPlayerChicken(player_t *player);
1479
1480         if(player->chickenTics)
1481         {
1482                 if(P_UndoPlayerChicken(player))
1483                 {
1484                         P_SetMessage(player, TXT_CHEATCHICKENOFF, false);
1485                 }
1486         }
1487         else if(P_ChickenMorphPlayer(player))
1488         {
1489                 P_SetMessage(player, TXT_CHEATCHICKENON, false);
1490         }
1491 }
1492
1493 static void CheatMassacreFunc(player_t *player, Cheat_t *cheat)
1494 {
1495         P_Massacre();
1496         P_SetMessage(player, TXT_CHEATMASSACRE, false);
1497 }
1498
1499 static void CheatIDKFAFunc(player_t *player, Cheat_t *cheat)
1500 {
1501         int i;
1502         if(player->chickenTics)
1503         {
1504                 return;
1505         }
1506         for(i = 1; i < 8; i++)
1507         {
1508                 player->weaponowned[i] = false;
1509         }
1510         player->pendingweapon = wp_staff;
1511         P_SetMessage(player, TXT_CHEATIDKFA, true);
1512 }
1513
1514 static void CheatIDDQDFunc(player_t *player, Cheat_t *cheat)
1515 {
1516         P_DamageMobj(player->mo, NULL, player->mo, 10000);
1517         P_SetMessage(player, TXT_CHEATIDDQD, true);
1518 }