1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2016 EDuke32 developers and contributors
4 
5 This file is part of EDuke32.
6 
7 EDuke32 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License version 2
9 as published by the Free Software Foundation.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 //-------------------------------------------------------------------------
22 
23 #include "cheats.h"
24 
25 #include "duke3d.h"
26 #include "osdcmds.h"
27 
28 char CheatStrings [NUMCHEATS][MAXCHEATLEN] =
29 {
30 #ifndef EDUKE32_STANDALONE
31     "cornholio",    // 0
32     "stuff",        // 1
33     "scotty###",    // 2
34     "coords",       // 3
35     "view",         // 4
36     "time",         // 5
37     "unlock",       // 6
38     "cashman",      // 7
39     "items",        // 8
40     "rate",         // 9
41     "skill#",       // 10
42     "beta",         // 11
43     "hyper",        // 12
44     "monsters",     // 13
45     "<RESERVED>",   // 14
46     "<RESERVED>",   // 15
47     "todd",         // 16
48     "showmap",      // 17
49     "kroz",         // 18
50     "allen",        // 19
51     "clip",         // 20
52     "weapons",      // 21
53     "inventory",    // 22
54     "keys",         // 23
55     "debug",        // 24
56     "<RESERVED>",   // 25
57     "cgs",          // 26
58 #endif
59 };
60 
61 char CheatDescriptions[NUMCHEATS][MAXCHEATDESC] =
62 {
63     "Toggle God Mode",
64     "Give Everything",
65     "Level Warp",
66     "Toggle Coordinate Display",
67     "Toggle 3rd-Person View",
68     "", // time
69     "Toggle All Locks",
70     "Toggle Cashman",
71     "Give All Items",
72     "Toggle Framerate Display",
73     "Change Skill",
74     "", // beta
75     "Toggle Hyper",
76     "Toggle Monsters",
77     "", // <RESERVED>
78     "", // <RESERVED>
79     "Matt Saettler.  matts@saettler.com", // todd
80     "Toggle Show All Map",
81     "", // kroz
82     "", // allen
83     "Toggle Clipping",
84     "Give Weapons",
85     "Give Inventory",
86     "Give Keys",
87     "Toggle Debug Data Dump",
88     "", // <RESERVED>
89     "", // cgs
90 };
91 
92 const uint32_t CheatFunctionFlags [NUMCHEATS] =
93 {
94     1 << CHEATFUNC_GOD,
95     1 << CHEATFUNC_GIVEEVERYTHING,
96     1 << CHEATFUNC_WARP,
97     1 << CHEATFUNC_COORDS,
98     1 << CHEATFUNC_VIEW,
99     0,
100     1 << CHEATFUNC_UNLOCK,
101     1 << CHEATFUNC_CASHMAN,
102     1 << CHEATFUNC_GIVEALLITEMS,
103     1 << CHEATFUNC_FRAMERATE,
104     1 << CHEATFUNC_SKILL,
105     1 << CHEATFUNC_QUOTEBETA,
106     1 << CHEATFUNC_HYPER,
107     1 << CHEATFUNC_MONSTERS,
108     0,
109     0,
110     1 << CHEATFUNC_QUOTETODD,
111     1 << CHEATFUNC_SHOWMAP,
112     1 << CHEATFUNC_GOD,
113     1 << CHEATFUNC_QUOTEALLEN,
114     1 << CHEATFUNC_CLIP,
115     1 << CHEATFUNC_GIVEWEAPONS,
116     1 << CHEATFUNC_GIVEINVENTORY,
117     1 << CHEATFUNC_GIVEKEYS,
118     1 << CHEATFUNC_DEBUG,
119     0,
120     (1 << CHEATFUNC_GOD) | (1 << CHEATFUNC_GIVEEVERYTHING),
121 };
122 
123 // KEEPINSYNC cheats.h: enum CheatCodeFunctions
124 // KEEPINSYNC menus.cpp: MenuEntry_t ME_CheatCodes[]
125 const uint8_t CheatFunctionIDs[NUMCHEATS] =
126 {
127     CHEAT_CASHMAN,
128     CHEAT_CORNHOLIO,
129     CHEAT_STUFF,
130     CHEAT_WEAPONS,
131     CHEAT_ITEMS,
132     CHEAT_INVENTORY,
133     CHEAT_KEYS,
134     CHEAT_HYPER,
135     CHEAT_VIEW,
136     CHEAT_SHOWMAP,
137     CHEAT_UNLOCK,
138     CHEAT_CLIP,
139     CHEAT_SCOTTY,
140     CHEAT_SKILL,
141     CHEAT_MONSTERS,
142     CHEAT_RATE,
143     CHEAT_BETA,
144     CHEAT_TODD,
145     CHEAT_ALLEN,
146     CHEAT_COORDS,
147     CHEAT_DEBUG,
148 };
149 
150 #ifndef EDUKE32_STANDALONE
G_SetupCheats(void)151 void G_SetupCheats(void)
152 {
153     // KEEPINSYNC: NAM_WW2GI_CHEATS
154     if (WW2GI)
155     {
156 #if 0
157         // WWII GI's original cheat prefix temporarily disabled because W conflicts with WSAD movement
158         CheatKeys[0] = CheatKeys[1] = sc_W;
159 #else
160         CheatKeys[0] = sc_G;
161         CheatKeys[1] = sc_I;
162 #endif
163 
164         Bstrcpy(CheatStrings[0], "2god");
165         Bstrcpy(CheatStrings[1], "2blood");
166         Bstrcpy(CheatStrings[2], "2level###");
167         Bstrcpy(CheatStrings[3], "2coords");
168         Bstrcpy(CheatStrings[4], "2view");
169         Bstrcpy(CheatStrings[5], "<RESERVED>");
170         Bstrcpy(CheatStrings[7], "<RESERVED>");
171         Bstrcpy(CheatStrings[8], "<RESERVED>");
172         Bstrcpy(CheatStrings[9], "2rate");
173         Bstrcpy(CheatStrings[10], "2skill");
174         Bstrcpy(CheatStrings[11], "<RESERVED>");
175         Bstrcpy(CheatStrings[12], "<RESERVED>");
176         Bstrcpy(CheatStrings[13], "<RESERVED>");
177         Bstrcpy(CheatStrings[16], "2matt");
178         Bstrcpy(CheatStrings[17], "2showmap");
179         Bstrcpy(CheatStrings[18], "2ryan");
180         Bstrcpy(CheatStrings[19], "<RESERVED>");
181         Bstrcpy(CheatStrings[20], "2clip");
182         Bstrcpy(CheatStrings[21], "2weapons");
183         Bstrcpy(CheatStrings[22], "2inventory");
184         Bstrcpy(CheatStrings[23], "<RESERVED>");
185         Bstrcpy(CheatStrings[24], "2debug");
186         Bstrcpy(CheatStrings[26], "2cgs");
187 
188         Bstrcpy(g_gametypeNames[0], "GI Match (Spawn)");
189         Bstrcpy(g_gametypeNames[2], "GI Match (No Spawn)");
190 }
191     else if (NAM)
192     {
193         CheatKeys[0] = sc_N;
194         CheatKeys[1] = sc_V;
195 
196         Bstrcpy(CheatStrings[0], "acaleb");
197         Bstrcpy(CheatStrings[1], "ablood");
198         Bstrcpy(CheatStrings[2], "alevel###");
199         Bstrcpy(CheatStrings[3], "acoords");
200         Bstrcpy(CheatStrings[4], "aview");
201         Bstrcpy(CheatStrings[5], "<RESERVED>");
202         Bstrcpy(CheatStrings[7], "<RESERVED>");
203         Bstrcpy(CheatStrings[8], "<RESERVED>");
204         Bstrcpy(CheatStrings[9], "arate");
205         Bstrcpy(CheatStrings[10], "askill");
206         Bstrcpy(CheatStrings[11], "<RESERVED>");
207         Bstrcpy(CheatStrings[12], "ahyper");
208         Bstrcpy(CheatStrings[13], "<RESERVED>");
209         Bstrcpy(CheatStrings[16], "amatt");
210         Bstrcpy(CheatStrings[17], "ashowmap");
211         Bstrcpy(CheatStrings[18], "agod");
212         Bstrcpy(CheatStrings[19], "<RESERVED>");
213         Bstrcpy(CheatStrings[20], "aclip");
214         Bstrcpy(CheatStrings[21], "aweapons");
215         Bstrcpy(CheatStrings[22], "ainventory");
216         Bstrcpy(CheatStrings[23], "<RESERVED>");
217         Bstrcpy(CheatStrings[24], "adebug");
218         Bstrcpy(CheatStrings[26], "acgs");
219 
220         Bstrcpy(g_gametypeNames[0], "GruntMatch (Spawn)");
221         Bstrcpy(g_gametypeNames[2], "GruntMatch (No Spawn)");
222     }
223 }
224 #endif
225 
doinvcheat(DukePlayer_t * const pPlayer,int32_t invidx,int32_t defaultnum,int32_t event)226 static void doinvcheat(DukePlayer_t * const pPlayer, int32_t invidx, int32_t defaultnum, int32_t event)
227 {
228     defaultnum = VM_OnEventWithReturn(event, pPlayer->i, myconnectindex, defaultnum);
229     if (defaultnum >= 0)
230         pPlayer->inv_amount[invidx] = defaultnum;
231 }
232 
G_CheatGetInv(DukePlayer_t * pPlayer)233 static void G_CheatGetInv(DukePlayer_t *pPlayer)
234 {
235     doinvcheat(pPlayer, GET_STEROIDS, 400, EVENT_CHEATGETSTEROIDS);
236     doinvcheat(pPlayer, GET_HEATS, 1200, EVENT_CHEATGETHEAT);
237     doinvcheat(pPlayer, GET_BOOTS, 200, EVENT_CHEATGETBOOT);
238     doinvcheat(pPlayer, GET_SHIELD, 100, EVENT_CHEATGETSHIELD);
239     doinvcheat(pPlayer, GET_SCUBA, 6400, EVENT_CHEATGETSCUBA);
240     doinvcheat(pPlayer, GET_HOLODUKE, 2400, EVENT_CHEATGETHOLODUKE);
241     doinvcheat(pPlayer, GET_JETPACK, 1600, EVENT_CHEATGETJETPACK);
242     doinvcheat(pPlayer, GET_FIRSTAID, pPlayer->max_player_health, EVENT_CHEATGETFIRSTAID);
243 }
244 
end_cheat(DukePlayer_t * const pPlayer)245 static void end_cheat(DukePlayer_t * const pPlayer)
246 {
247     pPlayer->cheat_phase = 0;
248     g_cheatBufLen = 0;
249     KB_FlushKeyboardQueue();
250     KB_ClearKeysDown();
251 }
252 
253 int g_cheatBufLen;
254 static int8_t cheatbuf[MAXCHEATLEN];
255 
G_DoCheats(void)256 void G_DoCheats(void)
257 {
258     auto const pPlayer = g_player[myconnectindex].ps;
259     int consoleCheat = 0;
260     int cheatNum;
261 
262     if (osdcmd_cheatsinfo_stat.cheatnum != -1)
263     {
264         cheatNum = osdcmd_cheatsinfo_stat.cheatnum;
265 
266         if (!FURY && ud.player_skill == 4)
267         {
268             switch (cheatNum)
269             {
270             case CHEAT_DEBUG:
271             case CHEAT_COORDS:
272             case CHEAT_RATE:
273             case CHEAT_RESERVED:
274             case CHEAT_RESERVED2:
275             case CHEAT_RESERVED3:
276                 break;
277             default:
278                 P_DoQuote(QUOTE_CHEATS_DISABLED, pPlayer);
279                 osdcmd_cheatsinfo_stat.cheatnum = -1;
280                 return;
281             }
282         }
283 
284         // JBF 20030914
285         osdcmd_cheatsinfo_stat.cheatnum = -1;
286         consoleCheat = 1;
287     }
288 
289     static int volumeOne = 0;
290 
291     if (VOLUMEONE && !volumeOne)
292     {
293         // change "scotty###" to "scotty##"
294         uint32_t const warpend = Bstrlen(CheatStrings[2]);
295         if (strcmp(&CheatStrings[2][warpend-3], "###") == 0)
296             CheatStrings[2][warpend-1] = '\0';
297 
298         Bstrcpy(CheatStrings[6], "<RESERVED>");
299         volumeOne = 1;
300     }
301 
302     if (consoleCheat && numplayers < 2 && ud.recstat == 0)
303         goto FOUNDCHEAT;
304 
305     if (pPlayer->gm & (MODE_TYPE|MODE_MENU))
306         return;
307 
308     if (pPlayer->cheat_phase == 1)
309     {
310         int ch;
311 
312         while (KB_KeyWaiting())
313         {
314             ch = Btolower(KB_GetCh());
315 
316             if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')))
317             {
318                 pPlayer->cheat_phase = 0;
319                 g_cheatBufLen = 0;
320                 //                P_DoQuote(QUOTE_46,pPlayer);
321                 return;
322             }
323 
324             cheatbuf[g_cheatBufLen++] = (int8_t) ch;
325             // This assertion is not obvious, but it should hold because of the
326             // cheat string matching logic below.
327             Bassert(g_cheatBufLen < (signed)sizeof(cheatbuf));
328             cheatbuf[g_cheatBufLen] = 0;
329             //            KB_ClearKeysDown();
330 
331             for (cheatNum=0; cheatNum < NUMCHEATCODES; cheatNum++)
332             {
333                 for (bssize_t j = 0; j<g_cheatBufLen; j++)
334                 {
335                     if (cheatbuf[j] == CheatStrings[cheatNum][j] || (CheatStrings[cheatNum][j] == '#' && ch >= '0' && ch <= '9'))
336                     {
337                         if (CheatStrings[cheatNum][j+1] == 0) goto FOUNDCHEAT;
338                         if (j == g_cheatBufLen-1) return;
339                     }
340                     else break;
341                 }
342             }
343 
344             pPlayer->cheat_phase = 0;
345             g_cheatBufLen = 0;
346             return;
347 
348         FOUNDCHEAT:;
349 
350             if (cheatNum == CHEAT_SCOTTY)
351             {
352                 size_t const i = Bstrlen(CheatStrings[cheatNum])-3+VOLUMEONE;
353                 if (!consoleCheat)
354                 {
355                     // JBF 20030914
356                     int32_t volnume, levnume;
357                     if (VOLUMEALL)
358                     {
359                         volnume = cheatbuf[i] - '0';
360                         levnume = (cheatbuf[i+1] - '0')*10+(cheatbuf[i+2]-'0');
361                     }
362                     else
363                     {
364                         volnume = cheatbuf[i] - '0';
365                         levnume = cheatbuf[i+1] - '0';
366                     }
367 
368                     volnume--;
369                     levnume--;
370 
371                     ud.m_volume_number = volnume;
372                     ud.m_level_number = levnume;
373                 }
374                 else
375                 {
376                     // JBF 20030914
377                     ud.m_volume_number = osdcmd_cheatsinfo_stat.volume;
378                     ud.m_level_number = osdcmd_cheatsinfo_stat.level;
379                 }
380             }
381             else if (cheatNum == CHEAT_SKILL)
382             {
383                 if (!consoleCheat)
384                 {
385                     size_t const i = Bstrlen(CheatStrings[cheatNum])-1;
386                     ud.m_player_skill = cheatbuf[i] - '1';
387                 }
388                 else
389                 {
390                     ud.m_player_skill = osdcmd_cheatsinfo_stat.volume;
391                 }
392             }
393 
394             int const originalCheatNum = cheatNum;
395             cheatNum = VM_OnEventWithReturn(EVENT_ACTIVATECHEAT, pPlayer->i, myconnectindex, cheatNum);
396 
397             // potential cleanup
398             if (originalCheatNum != cheatNum)
399             {
400                 if (originalCheatNum == CHEAT_SCOTTY)
401                 {
402                     ud.m_volume_number = ud.volume_number;
403                     ud.m_level_number = ud.level_number;
404                 }
405                 else if (originalCheatNum == CHEAT_SKILL)
406                 {
407                     ud.m_player_skill = ud.player_skill;
408                 }
409             }
410 
411             {
412                 switch (cheatNum)
413                 {
414                 case CHEAT_WEAPONS:
415                 {
416                     int const weaponLimit = (VOLUMEONE) ? SHRINKER_WEAPON : MAX_WEAPONS;
417 
418                     for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < weaponLimit; weaponNum++)
419                     {
420                         P_AddAmmo(pPlayer, weaponNum, pPlayer->max_ammo_amount[weaponNum]);
421                         pPlayer->gotweapon |= (1<<weaponNum);
422                     }
423 
424                     P_DoQuote(QUOTE_CHEAT_ALL_WEAPONS, pPlayer);
425 
426                     end_cheat(pPlayer);
427                 }
428                     return;
429 
430                 case CHEAT_INVENTORY:
431                     G_CheatGetInv(pPlayer);
432                     P_DoQuote(QUOTE_CHEAT_ALL_INV, pPlayer);
433                     end_cheat(pPlayer);
434                     return;
435 
436                 case CHEAT_KEYS:
437                     pPlayer->got_access =  7;
438                     KB_FlushKeyboardQueue();
439                     P_DoQuote(QUOTE_CHEAT_ALL_KEYS, pPlayer);
440                     end_cheat(pPlayer);
441                     return;
442 
443                 case CHEAT_DEBUG:
444                     g_Debug = 1-g_Debug;
445 
446                     G_DumpDebugInfo();
447                     Bsprintf(tempbuf, "Gamevars dumped to log");
448                     G_AddUserQuote(tempbuf);
449                     Bsprintf(tempbuf, "Map dumped to debug.map");
450                     G_AddUserQuote(tempbuf);
451                     end_cheat(pPlayer);
452                     break;
453 
454                 case CHEAT_CLIP:
455                     ud.noclip = !ud.noclip;
456                     P_DoQuote(QUOTE_CHEAT_NOCLIP-!ud.noclip, pPlayer);
457                     end_cheat(pPlayer);
458                     return;
459 
460                 case CHEAT_RESERVED2:
461                     pPlayer->player_par = 0;
462                     pPlayer->gm = MODE_EOL;
463                     end_cheat(pPlayer);
464                     return;
465 
466                 case CHEAT_ALLEN:
467                     P_DoQuote(QUOTE_CHEAT_ALLEN, pPlayer);
468                     end_cheat(pPlayer);
469                     return;
470 
471                 case CHEAT_CORNHOLIO:
472                 case CHEAT_KROZ:
473                 case CHEAT_COMEGETSOME:
474                 {
475                     const int32_t pi = pPlayer->i;
476 
477                     ud.god = 1-ud.god;
478 
479                     if (ud.god)
480                     {
481                         pus = 1;
482                         pub = 1;
483                         sprite[pi].cstat = 257;
484 
485                         actor[pi].t_data[0] = 0;
486                         actor[pi].t_data[1] = 0;
487                         actor[pi].t_data[2] = 0;
488                         actor[pi].t_data[3] = 0;
489                         actor[pi].t_data[4] = 0;
490                         actor[pi].t_data[5] = 0;
491 
492                         sprite[pi].hitag = 0;
493                         sprite[pi].lotag = 0;
494                         sprite[pi].pal = pPlayer->palookup;
495 
496                         if (cheatNum != CHEAT_COMEGETSOME)
497                         {
498                             P_DoQuote(QUOTE_CHEAT_GODMODE_ON, pPlayer);
499                         }
500                         else
501                         {
502                             Bstrcpy(apStrings[QUOTE_RESERVED4], "Come Get Some!");
503 
504                             S_PlaySound(DUKE_GETWEAPON2);
505                             P_DoQuote(QUOTE_RESERVED4, pPlayer);
506                             G_CheatGetInv(pPlayer);
507 
508                             for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS; weaponNum++)
509                                 pPlayer->gotweapon |= (1<<weaponNum);
510 
511                             for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS; weaponNum++)
512                                 P_AddAmmo(pPlayer, weaponNum, pPlayer->max_ammo_amount[weaponNum]);
513 
514                             pPlayer->got_access = 7;
515                         }
516                     }
517                     else
518                     {
519                         sprite[pi].extra = pPlayer->max_player_health;
520                         actor[pi].extra = -1;
521                         pPlayer->last_extra = pPlayer->max_player_health;
522                         P_DoQuote(QUOTE_CHEAT_GODMODE_OFF, pPlayer);
523                     }
524 
525                     sprite[pi].extra = pPlayer->max_player_health;
526                     actor[pi].extra = 0;
527 
528                     if (cheatNum != CHEAT_COMEGETSOME)
529                         pPlayer->dead_flag = 0;
530 
531                     end_cheat(pPlayer);
532                     return;
533                 }
534 
535                 case CHEAT_STUFF:
536                 {
537                     int const weaponLimit = (VOLUMEONE) ? SHRINKER_WEAPON : MAX_WEAPONS;
538 
539                     for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < weaponLimit; weaponNum++)
540                         pPlayer->gotweapon |= (1<<weaponNum);
541 
542                     for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < weaponLimit; weaponNum++)
543                         P_AddAmmo(pPlayer, weaponNum, pPlayer->max_ammo_amount[weaponNum]);
544 
545                     G_CheatGetInv(pPlayer);
546                     pPlayer->got_access = 7;
547                     P_DoQuote(QUOTE_CHEAT_EVERYTHING, pPlayer);
548 
549                     //                    P_DoQuote(QUOTE_21,pPlayer);
550                     pPlayer->inven_icon = ICON_FIRSTAID;
551 
552                     end_cheat(pPlayer);
553                     return;
554                 }
555 
556                 case CHEAT_SCOTTY:
557                 {
558                     int32_t const volnume = ud.m_volume_number, levnume = ud.m_level_number;
559 
560                     if ((!VOLUMEONE || volnume == 0) && (unsigned)volnume < (unsigned)g_volumeCnt &&
561                         (unsigned)levnume < MAXLEVELS && g_mapInfo[volnume*MAXLEVELS + levnume].filename != NULL)
562                     {
563                         ud.volume_number = volnume;
564                         ud.level_number = levnume;
565 
566 #if 0
567                         if (numplayers > 1 && g_netServer)
568                             Net_NewGame(volnume, levnume);
569                         else
570 #endif
571                             pPlayer->gm |= MODE_RESTART;
572                     }
573 
574                     end_cheat(pPlayer);
575                     return;
576                 }
577 
578                 case CHEAT_SKILL:
579                     ud.player_skill = ud.m_player_skill;
580 
581 #if 0
582                     if (numplayers > 1 && g_netServer)
583                         Net_NewGame(ud.m_volume_number, ud.m_level_number);
584                     else
585 #endif
586                         pPlayer->gm |= MODE_RESTART;
587 
588                     end_cheat(pPlayer);
589                     return;
590 
591                 case CHEAT_COORDS:
592 #ifdef USE_OPENGL
593                     if (++ud.coords >= 3) ud.coords = 0;
594 #else
595                     if (++ud.coords >= 2) ud.coords = 0;
596 #endif
597                     end_cheat(pPlayer);
598                     return;
599 
600                 case CHEAT_VIEW:
601                     pPlayer->over_shoulder_on ^= 1;
602                     CAMERADIST = 0;
603                     CAMERACLOCK = (int32_t) totalclock;
604                     //                    P_DoQuote(QUOTE_CHEATS_DISABLED,pPlayer);
605                     end_cheat(pPlayer);
606                     return;
607 
608                 case CHEAT_TIME:
609                     //                    P_DoQuote(QUOTE_21,pPlayer);
610                     end_cheat(pPlayer);
611                     return;
612 
613                 case CHEAT_UNLOCK:
614                     if (VOLUMEONE) return;
615 
616                     for (bssize_t i=numsectors-1; i>=0; i--) //Unlock
617                     {
618                         int const lotag = sector[i].lotag;
619                         if (lotag == -1 || lotag == 32767) continue;
620                         if ((lotag & 0x7fff) > 2)
621                         {
622                             if (lotag & (uint16_t)~16384u)
623                                 sector[i].lotag &= (uint16_t)~16384u;
624                             G_OperateSectors(i, pPlayer->i);
625                         }
626                     }
627                     G_OperateForceFields(pPlayer->i, -1);
628 
629                     P_DoQuote(QUOTE_CHEAT_UNLOCK, pPlayer);
630                     end_cheat(pPlayer);
631                     return;
632 
633                 case CHEAT_CASHMAN:
634                     ud.cashman = 1-ud.cashman;
635                     end_cheat(pPlayer);
636                     return;
637 
638                 case CHEAT_ITEMS:
639                     G_CheatGetInv(pPlayer);
640                     pPlayer->got_access = 7;
641                     P_DoQuote(QUOTE_CHEAT_EVERYTHING, pPlayer);
642                     end_cheat(pPlayer);
643                     return;
644 
645                 case CHEAT_SHOWMAP: // SHOW ALL OF THE MAP TOGGLE;
646                     ud.showallmap = !ud.showallmap;
647 
648                     for (char & i : show2dsector)
649                         i = ud.showallmap*255;
650 
651                     P_DoQuote(ud.showallmap ? QUOTE_SHOW_MAP_ON : QUOTE_SHOW_MAP_OFF,
652                         pPlayer);
653 
654                     end_cheat(pPlayer);
655                     return;
656 
657                 case CHEAT_TODD:
658                     if (NAM)
659                     {
660                         Bstrcpy(apStrings[QUOTE_RESERVED4], CheatDescriptions[CHEAT_TODD]);
661                         P_DoQuote(QUOTE_RESERVED4, pPlayer);
662                     }
663                     else
664                     {
665                         P_DoQuote(QUOTE_CHEAT_TODD, pPlayer);
666                     }
667 
668                     end_cheat(pPlayer);
669                     return;
670 
671                 case CHEAT_RATE:
672                     if (++ud.showfps > 3)
673                         ud.showfps = 0;
674 
675                     end_cheat(pPlayer);
676                     return;
677 
678                 case CHEAT_BETA:
679                     P_DoQuote(QUOTE_CHEAT_BETA, pPlayer);
680                     end_cheat(pPlayer);
681                     return;
682 
683                 case CHEAT_HYPER:
684                     pPlayer->inv_amount[GET_STEROIDS] = 399;
685                     pPlayer->inv_amount[GET_HEATS] = 1200;
686                     P_DoQuote(QUOTE_CHEAT_STEROIDS, pPlayer);
687                     end_cheat(pPlayer);
688                     return;
689 
690                 case CHEAT_MONSTERS:
691                 {
692                     const char *s [] = { "On", "Off", "On (2)" };
693 
694                     if (++g_noEnemies == 3)
695                         g_noEnemies = 0;
696 
697                     Bsprintf(apStrings[QUOTE_RESERVED4], "Monsters: %s", s[g_noEnemies]);
698                     P_DoQuote(QUOTE_RESERVED4, pPlayer);
699 
700                     end_cheat(pPlayer);
701                     return;
702                 }
703 
704                 case CHEAT_RESERVED:
705                 case CHEAT_RESERVED3:
706                     ud.eog = 1;
707                     pPlayer->player_par = 0;
708                     pPlayer->gm |= MODE_EOL;;
709                     end_cheat(pPlayer);
710                     return;
711 
712                 default:
713                     end_cheat(pPlayer);
714                     return;
715                 }
716             }
717         }
718     }
719     else
720     {
721         if (KB_KeyPressed((uint8_t) CheatKeys[0]))
722         {
723             if (pPlayer->cheat_phase >= 0 && numplayers < 2 && ud.recstat == 0)
724             {
725                 if (CheatKeys[0] == CheatKeys[1])
726                     KB_ClearKeyDown((uint8_t) CheatKeys[0]);
727                 pPlayer->cheat_phase = -1;
728             }
729         }
730 
731         if (KB_KeyPressed((uint8_t) CheatKeys[1]))
732         {
733             if (pPlayer->cheat_phase == -1)
734             {
735                 if (!FURY && ud.player_skill == 4)
736                 {
737                     P_DoQuote(QUOTE_CHEATS_DISABLED, pPlayer);
738                     pPlayer->cheat_phase = 0;
739                 }
740                 else
741                 {
742                     pPlayer->cheat_phase = 1;
743                     //                    P_DoQuote(QUOTE_25,pPlayer);
744                 }
745                 g_cheatBufLen = 0;
746                 KB_FlushKeyboardQueue();
747             }
748             else if (pPlayer->cheat_phase != 0)
749             {
750                 pPlayer->cheat_phase = 0;
751                 g_cheatBufLen = 0;
752                 KB_ClearKeyDown((uint8_t) CheatKeys[0]);
753                 KB_ClearKeyDown((uint8_t) CheatKeys[1]);
754             }
755         }
756     }
757 }
758