diff --git a/docs/rh-log.txt b/docs/rh-log.txt index ed660f4f8a..258eb2bc70 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,6 @@ +August 30, 2008 (Changes by Graf Zahl) +- Added Blzut3's patch for a real Chex Quest game mode. + August 29, 2008 (Changes by Graf Zahl) - Fixed: SKIP_SUPER doesn't work for inventory items so it must be disabled for them diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index 795af7cd3a..c025624eb5 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -229,7 +229,7 @@ void CT_Drawer (void) } // draw the prompt, text, and cursor - ChatQueue[len] = gameinfo.gametype == GAME_Doom ? '_' : '['; + ChatQueue[len] = gameinfo.gametype & GAME_DoomChex ? '_' : '['; ChatQueue[len+1] = '\0'; if (con_scaletext < 2) { diff --git a/src/d_main.cpp b/src/d_main.cpp index 00bbcd649f..82feebb8d1 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -667,7 +667,7 @@ void D_Display () FTexture *tex; int x; - tex = TexMan[gameinfo.gametype & (GAME_Doom|GAME_Strife) ? "M_PAUSE" : "PAUSED"]; + tex = TexMan[gameinfo.gametype & (GAME_DoomStrifeChex) ? "M_PAUSE" : "PAUSED"]; x = (SCREENWIDTH - tex->GetWidth()*CleanXfac)/2 + tex->LeftOffset*CleanXfac; screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE); @@ -2457,24 +2457,6 @@ void D_DoomMain (void) DecalLibrary.Clear (); DecalLibrary.ReadAllDecals (); - // Patch the game for Chex quest differences - if (gameinfo.flags & GI_CHEX_QUEST) - { - // remove the drop items from the zombie and shotgunguy - // (this could be done with a DECORATE lump but would need - // as much code to load it.) - PClass *info; - - info = (PClass*)PClass::FindClass("Zombieman"); - if (info) info->Meta.SetMetaInt (ACMETA_DropItems, 0); - - info = (PClass*)PClass::FindClass("ShotgunGuy"); - if (info) info->Meta.SetMetaInt (ACMETA_DropItems, 0); - - int lump = Wads.CheckNumForFullName("chex.deh", 0); - if (lump >= 0) DoDehPatch(NULL, true, lump); - } - // [RH] Try adding .deh and .bex files on the command line. // If there are none, try adding any in the config file. diff --git a/src/f_finale.cpp b/src/f_finale.cpp index d1a932688d..6c9609318f 100644 --- a/src/f_finale.cpp +++ b/src/f_finale.cpp @@ -393,9 +393,9 @@ void F_TextWrite (void) return; // draw some of the text onto the screen - leftmargin = (gameinfo.gametype & (GAME_Doom|GAME_Strife|GAME_Hexen) ? 10 : 20) - 160; + leftmargin = (gameinfo.gametype & (GAME_DoomStrifeChex|GAME_Hexen) ? 10 : 20) - 160; rowheight = screen->Font->GetHeight () + - (gameinfo.gametype & (GAME_Doom|GAME_Strife) ? 3 : -1); + (gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1); scale = (CleanXfac != 1 || CleanYfac != 1); cx = leftmargin; @@ -405,7 +405,7 @@ void F_TextWrite (void) } else { - cy = (gameinfo.gametype & (GAME_Doom|GAME_Strife) ? 10 : 5) - 100; + cy = (gameinfo.gametype & (GAME_DoomStrifeChex) ? 10 : 5) - 100; } ch = FinaleText.GetChars(); diff --git a/src/g_level.cpp b/src/g_level.cpp index c0a96ee1c1..d10b11a096 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1689,7 +1689,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) { int cstype = SBarInfoScript->GetGameType(); - if(cstype == GAME_Doom) //Did the user specify a "base" + if(cstype == GAME_Doom || cstype == GAME_Chex) //Did the user specify a "base" { StatusBar = CreateDoomStatusBar (); } @@ -1712,7 +1712,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) } if (StatusBar == NULL) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { StatusBar = CreateDoomStatusBar (); } diff --git a/src/g_shared/a_armor.cpp b/src/g_shared/a_armor.cpp index dc76e1d9a2..9cca7f2501 100644 --- a/src/g_shared/a_armor.cpp +++ b/src/g_shared/a_armor.cpp @@ -41,6 +41,7 @@ void ABasicArmor::Tick () { switch (gameinfo.gametype) { + case GAME_Chex: case GAME_Doom: Icon = TexMan.CheckForTexture (SavePercent == FRACUNIT/3 ? "ARM1A0" : "ARM2A0", FTexture::TEX_Any); break; diff --git a/src/g_shared/a_keys.cpp b/src/g_shared/a_keys.cpp index 9d8c00a267..d62688a987 100644 --- a/src/g_shared/a_keys.cpp +++ b/src/g_shared/a_keys.cpp @@ -211,6 +211,10 @@ static void ParseLock(FScanner &sc) { if (gameinfo.gametype != GAME_Strife) keynum=-1; } + else if (sc.Compare("CHEX")) + { + if (gameinfo.gametype != GAME_Chex) keynum=-1; + } else sc.UnGet(); ignorekey = true; diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index cea9374425..bb17295785 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -262,7 +262,7 @@ AAmmo *AWeapon::AddAmmo (AActor *other, const PClass *ammotype, int amount) // [BC] This behavior is from the original Doom. Give 5/2 times as much ammo when // we pick up a weapon in deathmatch. - if (( deathmatch ) && ( gameinfo.gametype == GAME_Doom )) + if (( deathmatch ) && ( gameinfo.gametype & GAME_DoomChex )) amount = amount * 5 / 2; // extra ammo in baby mode and nightmare mode diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index a2dbdcafec..97efa360e6 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1177,7 +1177,7 @@ void DBaseStatusBar::Draw (EHudState state) { int y, i, time = level.time / TICRATE, height; int totaltime = level.totaltime / TICRATE; - EColorRange highlight = (gameinfo.gametype == GAME_Doom) ? + EColorRange highlight = (gameinfo.gametype & GAME_DoomChex) ? CR_UNTRANSLATED : CR_YELLOW; height = screen->Font->GetHeight () * CleanYfac; diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 1eb832b8cc..508cd068e7 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -225,7 +225,7 @@ void FGameConfigFile::DoGameSetup (const char *gamename) { const char *key; const char *value; - enum { Doom, Heretic, Hexen, Strife } game; + enum { Doom, Heretic, Hexen, Strife, Chex } game; if (strcmp (gamename, "Heretic") == 0) game = Heretic; @@ -233,6 +233,8 @@ void FGameConfigFile::DoGameSetup (const char *gamename) game = Hexen; else if (strcmp (gamename, "Strife") == 0) game = Strife; + else if (strcmp (gamename, "Chex") == 0) + game = Chex; else game = Doom; @@ -663,6 +665,18 @@ void FGameConfigFile::SetupWeaponList (const char *gamename) LocalWeapons.Slots[7].AddWeapon ("Mauler"); LocalWeapons.Slots[8].AddWeapon ("Sigil"); } + else if (strcmp (gamename, "Chex") == 0) + { + LocalWeapons.Slots[1].AddWeapon ("Bootspoon"); + LocalWeapons.Slots[1].AddWeapon ("SuperBootspork"); + LocalWeapons.Slots[2].AddWeapon ("MiniZorcher"); + LocalWeapons.Slots[3].AddWeapon ("LargeZorcher"); + LocalWeapons.Slots[3].AddWeapon ("SuperLargeZorcher"); + LocalWeapons.Slots[4].AddWeapon ("RapidZorcher"); + LocalWeapons.Slots[5].AddWeapon ("ZorchPropulsor"); + LocalWeapons.Slots[6].AddWeapon ("PhasingZorcher"); + LocalWeapons.Slots[7].AddWeapon ("LAZDevice"); + } else // Doom { LocalWeapons.Slots[1].AddWeapon ("Fist"); diff --git a/src/gi.cpp b/src/gi.cpp index d35cb12759..eb1ddcbe11 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -40,9 +40,9 @@ gameinfo_t gameinfo; -const char *GameNames[9] = +const char *GameNames[17] = { - NULL, "Doom", "Heretic", NULL, "Hexen", NULL, NULL, NULL, "Strife" + NULL, "Doom", "Heretic", NULL, "Hexen", NULL, NULL, NULL, "Strife", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Chex" }; @@ -278,12 +278,12 @@ gameinfo_t ChexGameInfo = "FLOOR7_2", &DoomBorder, 0, - GAME_Doom, + GAME_Chex, 100, "F_SKY1", 24*FRACUNIT, "xlat/doom.txt", - { "mapinfo/doomcommon.txt", "mapinfo/chex.txt" }, + { "mapinfo/chex.txt", NULL }, MAKERGB(95,175,87), }; diff --git a/src/gi.h b/src/gi.h index 92234723bd..532e4e13c3 100644 --- a/src/gi.h +++ b/src/gi.h @@ -58,13 +58,16 @@ enum EGameType GAME_Heretic = 2, GAME_Hexen = 4, GAME_Strife = 8, + GAME_Chex = 16, //Chex is basically Doom, but we need to have a different set of actors. - GAME_Raven = GAME_Heretic|GAME_Hexen, - GAME_DoomStrife = GAME_Doom|GAME_Strife + GAME_Raven = GAME_Heretic|GAME_Hexen, + GAME_DoomStrife = GAME_Doom|GAME_Strife, + GAME_DoomChex = GAME_Doom|GAME_Chex, + GAME_DoomStrifeChex = GAME_Doom|GAME_Strife|GAME_Chex }; #endif -extern const char *GameNames[9]; +extern const char *GameNames[17]; typedef struct { diff --git a/src/gstrings.h b/src/gstrings.h index 4267adc177..5abbea9e15 100644 --- a/src/gstrings.h +++ b/src/gstrings.h @@ -45,6 +45,7 @@ extern FStringTable GStrings; // QuitGame messages #define NUM_QUITDOOMMESSAGES 15 #define NUM_QUITSTRIFEMESSAGES 8 +#define NUM_QUITCHEXMESSAGES 2 extern const char *endmsg[]; diff --git a/src/info.h b/src/info.h index 0f254b1192..250f08fdec 100644 --- a/src/info.h +++ b/src/info.h @@ -184,9 +184,12 @@ enum EGameType GAME_Heretic = 2, GAME_Hexen = 4, GAME_Strife = 8, + GAME_Chex = 16, - GAME_Raven = GAME_Heretic|GAME_Hexen, - GAME_DoomStrife = GAME_Doom|GAME_Strife + GAME_Raven = GAME_Heretic|GAME_Hexen, + GAME_DoomStrife = GAME_Doom|GAME_Strife, + GAME_DoomChex = GAME_Doom|GAME_Chex, + GAME_DoomStrifeChex = GAME_Doom|GAME_Strife|GAME_Chex }; #endif diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index a235564b72..5b3ecf973d 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -81,10 +81,20 @@ void cht_DoCheat (player_t *player, int cheat) // fall through to CHT_GOD case CHT_GOD: player->cheats ^= CF_GODMODE; - if (player->cheats & CF_GODMODE) - msg = GStrings("STSTR_DQDON"); + if (gameinfo.gametype != GAME_Chex) + { + if (player->cheats & CF_GODMODE) + msg = GStrings("STSTR_DQDON"); + else + msg = GStrings("STSTR_DQDOFF"); + } else - msg = GStrings("STSTR_DQDOFF"); + { + if (player->cheats & CF_GODMODE) + msg = GStrings("STSTR_CDQDON"); + else + msg = GStrings("STSTR_CDQDOFF"); + } SB_state = screen->GetPageCount (); break; @@ -160,7 +170,10 @@ void cht_DoCheat (player_t *player, int cheat) { player->mo->GiveInventoryType (type); } - msg = GStrings("STSTR_CHOPPERS"); + if(gameinfo.gametype != GAME_Chex) + msg = GStrings("STSTR_CHOPPERS"); + else + msg = GStrings("STSTR_CCHOPPERS"); } // [RH] The original cheat also set powers[pw_invulnerability] to true. // Since this is a timer and not a boolean, it effectively turned off @@ -191,7 +204,10 @@ void cht_DoCheat (player_t *player, int cheat) cht_Give (player, "ammo"); cht_Give (player, "keys"); cht_Give (player, "armor"); - msg = GStrings("STSTR_KFAADDED"); + if(gameinfo.gametype != GAME_Chex) + msg = GStrings("STSTR_KFAADDED"); + else + msg = GStrings("STSTR_CKFAADDED"); break; case CHT_IDFA: @@ -199,7 +215,10 @@ void cht_DoCheat (player_t *player, int cheat) cht_Give (player, "weapons"); cht_Give (player, "ammo"); cht_Give (player, "armor"); - msg = GStrings("STSTR_FAADDED"); + if(gameinfo.gametype != GAME_Chex) + msg = GStrings("STSTR_FAADDED"); + else + msg = GStrings("STSTR_CFAADDED"); break; case CHT_BEHOLDV: @@ -622,6 +641,10 @@ void cht_Give (player_t *player, const char *name, int amount) { type = PClass::FindClass ("Backpack"); } + else if (gameinfo.gametype == GAME_Chex) + { + type = PClass::FindClass ("Zorchpack"); + } else { // Hexen doesn't have a backpack, foo! type = NULL; @@ -850,6 +873,10 @@ void cht_Take (player_t *player, const char *name, int amount) { type = PClass::FindClass ("Backpack"); } + else if (gameinfo.gametype == GAME_Chex) + { + type = PClass::FindClass ("Zorchpack"); + } else { // Hexen doesn't have a backpack, foo! type = NULL; diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 5448ff33ae..f2a03d5478 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -926,7 +926,7 @@ void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave) // void M_DrawLoad (void) { - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { FTexture *title = TexMan["M_LOADG"]; screen->DrawTexture (title, @@ -952,7 +952,7 @@ void M_DrawLoad (void) // void M_DrawSaveLoadBorder (int x, int y, int len) { - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { int i; @@ -1272,7 +1272,10 @@ void M_LoadGame (int choice) { if (netgame) { - M_StartMessage (GStrings("LOADNET"), NULL, false); + if(gameinfo.gametype == GAME_Chex) + M_StartMessage (GStrings("CLOADNET"), NULL, false); + else + M_StartMessage (GStrings("LOADNET"), NULL, false); return; } @@ -1289,7 +1292,7 @@ void M_LoadGame (int choice) // void M_DrawSave() { - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { FTexture *title = TexMan["M_SAVEG"]; screen->DrawTexture (title, @@ -1401,7 +1404,10 @@ void M_QuickSave () M_SaveGame (0); return; } - mysnprintf (tempstring, countof(tempstring), GStrings("QSPROMPT"), quickSaveSlot->Title); + if(gameinfo.gametype == GAME_Chex) + mysnprintf (tempstring, countof(tempstring), GStrings("CQSPROMPT"), quickSaveSlot->Title); + else + mysnprintf (tempstring, countof(tempstring), GStrings("QSPROMPT"), quickSaveSlot->Title); strcpy (savegamestring, quickSaveSlot->Title); M_StartMessage (tempstring, M_QuickSaveResponse, true); } @@ -1425,7 +1431,10 @@ void M_QuickLoad () { if (netgame) { - M_StartMessage (GStrings("QLOADNET"), NULL, false); + if(gameinfo.gametype == GAME_Chex) + M_StartMessage (GStrings("CQLOADNET"), NULL, false); + else + M_StartMessage (GStrings("QLOADNET"), NULL, false); return; } @@ -1437,7 +1446,10 @@ void M_QuickLoad () M_LoadGame (0); return; } - mysnprintf (tempstring, countof(tempstring), GStrings("QLPROMPT"), quickSaveSlot->Title); + if(gameinfo.gametype == GAME_Chex) + mysnprintf (tempstring, countof(tempstring), GStrings("CQLPROMPT"), quickSaveSlot->Title); + else + mysnprintf (tempstring, countof(tempstring), GStrings("QLPROMPT"), quickSaveSlot->Title); M_StartMessage (tempstring, M_QuickLoadResponse, true); } @@ -1499,7 +1511,7 @@ void M_DrawReadThis () // void M_DrawMainMenu (void) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { screen->DrawTexture (TexMan["M_DOOM"], 94, 2, DTA_Clean, true, TAG_DONE); } @@ -1542,9 +1554,9 @@ void M_DrawHereticMainMenu () // void M_DrawNewGame(void) { - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { - screen->DrawTexture (TexMan[gameinfo.gametype == GAME_Doom ? "M_NEWG" : "M_NGAME"], 96, 14, DTA_Clean, true, TAG_DONE); + screen->DrawTexture (TexMan[gameinfo.gametype & GAME_DoomChex ? "M_NEWG" : "M_NGAME"], 96, 14, DTA_Clean, true, TAG_DONE); screen->DrawTexture (TexMan["M_SKILL"], 54, 38, DTA_Clean, true, TAG_DONE); } } @@ -1553,12 +1565,15 @@ void M_NewGame(int choice) { if (netgame && !demoplayback) { - M_StartMessage (GStrings("NEWGAME"), NULL, false); + if(gameinfo.gametype == GAME_Chex) + M_StartMessage (GStrings("CNEWGAME"), NULL, false); + else + M_StartMessage (GStrings("NEWGAME"), NULL, false); return; } // Set up episode menu positioning - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { EpiDef.x = 48; EpiDef.y = 63; @@ -1679,7 +1694,7 @@ static void M_DrawClassMenu () if (ClassMenuDef.numitems > 4 && gameinfo.gametype & GAME_Raven) tit_y = 2; - screen->DrawText (gameinfo.gametype == GAME_Doom ? CR_RED : CR_UNTRANSLATED, + screen->DrawText (gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED, 160 - BigFont->StringWidth (text)/2, tit_y, text, DTA_Clean, true, TAG_DONE); @@ -1738,7 +1753,7 @@ static void DrawHexenSkillMenu() // void M_DrawEpisode () { - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { screen->DrawTexture (TexMan["M_EPISOD"], 54, 38, DTA_Clean, true, TAG_DONE); } @@ -1790,6 +1805,10 @@ void M_Episode (int choice) M_StartMessage(GStrings("SWSTRING"),NULL,false); //M_SetupNextMenu(&ReadDef); } + else if (gameinfo.gametype == GAME_Chex) + { + M_StartMessage(GStrings("CSWSTRING"),NULL,false); + } else { showSharewareMessage = 3*TICRATE; @@ -1818,7 +1837,10 @@ static void SCClass (int option) { if (netgame) { - M_StartMessage (GStrings("NEWGAME"), NULL, false); + if(gameinfo.gametype == GAME_Chex) + M_StartMessage (GStrings("CNEWGAME"), NULL, false); + else + M_StartMessage (GStrings("NEWGAME"), NULL, false); return; } @@ -1846,7 +1868,10 @@ static void M_ChooseClass (int choice) { if (netgame) { - M_StartMessage (GStrings("NEWGAME"), NULL, false); + if(gameinfo.gametype == GAME_Chex) + M_StartMessage (GStrings("CNEWGAME"), NULL, false); + else + M_StartMessage (GStrings("NEWGAME"), NULL, false); return; } @@ -1899,11 +1924,17 @@ void M_EndGame(int choice) if (netgame) { - M_StartMessage(GStrings("NETEND"),NULL,false); + if(gameinfo.gametype == GAME_Chex) + M_StartMessage(GStrings("CNETEND"),NULL,false); + else + M_StartMessage(GStrings("NETEND"),NULL,false); return; } - - M_StartMessage(GStrings("ENDGAME"),M_EndGameResponse,true); + + if(gameinfo.gametype == GAME_Chex) + M_StartMessage(GStrings("CENDGAME"),M_EndGameResponse,true); + else + M_StartMessage(GStrings("ENDGAME"),M_EndGameResponse,true); } @@ -1966,12 +1997,19 @@ void M_QuitGame (int choice) { // We pick index 0 which is language sensitive, // or one at random, between 1 and maximum number. - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { - int quitmsg = gametic % (gameinfo.gametype == GAME_Doom ? NUM_QUITDOOMMESSAGES : NUM_QUITSTRIFEMESSAGES - 1); - if (quitmsg != 0 || gameinfo.gametype == GAME_Strife) + int quitmsg = 0;gametic % (gameinfo.gametype == GAME_Doom ? (gameinfo.gametype != GAME_Chex ? NUM_QUITDOOMMESSAGES : NUM_QUITCHEXMESSAGES - 1) : NUM_QUITSTRIFEMESSAGES - 1); + if (gameinfo.gametype == GAME_Doom) + quitmsg = gametic % NUM_QUITDOOMMESSAGES; + else if (gameinfo.gametype == GAME_Strife) + quitmsg = gametic % NUM_QUITSTRIFEMESSAGES - 1; + else //Chex quest has 2 messages but one is more likely to show + quitmsg = (gametic % NUM_QUITCHEXMESSAGES + 6) > NUM_QUITCHEXMESSAGES ? NUM_QUITCHEXMESSAGES - 1 : (gametic % NUM_QUITCHEXMESSAGES + 6); + + if (quitmsg != 0 || gameinfo.gametype == GAME_Strife || gameinfo.gametype == GAME_Chex) { - EndString.Format("QUITMSG%d", quitmsg + (gameinfo.gametype == GAME_Doom ? 0 : NUM_QUITDOOMMESSAGES + 1)); + EndString.Format("QUITMSG%d", quitmsg + (gameinfo.gametype == GAME_Doom ? 0 : (gameinfo.gametype == GAME_Chex ? NUM_QUITDOOMMESSAGES + NUM_QUITSTRIFEMESSAGES : NUM_QUITDOOMMESSAGES + 1))); EndString.Format("%s\n\n%s", GStrings(EndString), GStrings("DOSY")); } else @@ -2061,7 +2099,7 @@ static void M_PlayerSetupDrawer () EColorRange label, value; DWORD color; - if (!(gameinfo.gametype & (GAME_Doom|GAME_Strife))) + if (!(gameinfo.gametype & (GAME_DoomStrifeChex))) { xo = 5; yo = 5; @@ -2077,7 +2115,7 @@ static void M_PlayerSetupDrawer () // Draw title const char * text = GStrings("MNU_PLAYERSETUP"); - screen->DrawText (gameinfo.gametype == GAME_Doom ? CR_RED : CR_UNTRANSLATED, + screen->DrawText (gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED, 160 - BigFont->StringWidth (text)/2, 15, text, DTA_Clean, true, TAG_DONE); @@ -3210,7 +3248,7 @@ void M_Drawer () if (color == CR_UNTRANSLATED) { // The default DBIGFONT is white but Doom's default should be red. - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { color = CR_RED; } @@ -3241,12 +3279,12 @@ void M_Drawer () screen->SetFont (ConFont); screen->DrawText (CR_RED, x - 16, currentMenu->y + itemOn*LINEHEIGHT + - (!(gameinfo.gametype & (GAME_Doom|GAME_Strife)) ? 6 : -1), "\xd", + (!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd", DTA_Clean, true, TAG_DONE); screen->SetFont (SmallFont); } } - else if (gameinfo.gametype == GAME_Doom) + else if (gameinfo.gametype & GAME_DoomChex) { screen->DrawTexture (TexMan[skullName[whichSkull]], x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT, @@ -3398,7 +3436,7 @@ void M_Init (void) atterm (M_Deinit); - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { TopLevelMenu = currentMenu = &MainDef; if (gameinfo.gametype == GAME_Strife) @@ -3429,10 +3467,10 @@ void M_Init (void) lastSaveSlot = NULL; strcpy (NewSaveNode.Title, ""); - underscore[0] = (gameinfo.gametype & (GAME_Doom|GAME_Strife)) ? '_' : '['; + underscore[0] = (gameinfo.gametype & (GAME_DoomStrifeChex)) ? '_' : '['; underscore[1] = '\0'; - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { LINEHEIGHT = 16; } @@ -3494,7 +3532,7 @@ void M_Init (void) ClassMenuDef.numitems = 1; } - if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) + if (gameinfo.gametype & (GAME_DoomStrifeChex)) { ClassMenuDef.x = 48; ClassMenuDef.y = 63; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 7246fcdf8f..0f5f1416fb 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -605,6 +605,7 @@ static bool FindFreeName (FString &fullname, const char *extension) case GAME_Heretic: gamename = "Heretic_"; break; case GAME_Hexen: gamename = "Hexen_"; break; case GAME_Strife: gamename = "Strife_"; break; + case GAME_Chex: gamename = "Chex_"; break; default: gamename = ""; break; } diff --git a/src/m_options.cpp b/src/m_options.cpp index b4ba51feea..56ee844cf4 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -1374,7 +1374,7 @@ static BYTE BitTranslate[32]; void M_OptInit (void) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { LabelColor = CR_UNTRANSLATED; ValueColor = CR_GRAY; @@ -1658,7 +1658,7 @@ void M_OptDrawer () if (BigFont && CurrentMenu->texttitle) { screen->SetFont (BigFont); - screen->DrawText (gameinfo.gametype == GAME_Doom ? CR_RED : CR_UNTRANSLATED, + screen->DrawText (gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED, 160-BigFont->StringWidth (CurrentMenu->texttitle)/2, 10, CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE); screen->SetFont (SmallFont); @@ -2185,7 +2185,7 @@ void M_OptResponder (event_t *ev) { maxitems = 15; } - if (gameinfo.gametype != GAME_Doom) + if (!(gameinfo.gametype & GAME_DoomChex)) { maxitems -= 2; rowheight = 9; diff --git a/src/namedef.h b/src/namedef.h index 3be9657c72..ab933d26ec 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -82,6 +82,7 @@ xx(StrifePlayer) xx(FighterPlayer) xx(ClericPlayer) xx(MagePlayer) +xx(ChexPlayer) xx(ChickenPlayer) xx(PigPlayer) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index a269cfeb02..720a0643c6 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1412,7 +1412,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround) return P_LookForEnemies (actor, allaround); } - if (!(gameinfo.gametype & (GAME_Doom|GAME_Strife)) && + if (!(gameinfo.gametype & (GAME_DoomStrifeChex)) && !multiplayer && players[0].health <= 0) { // Single player game and player is dead; look for monsters diff --git a/src/p_enemy_a_lookex.cpp b/src/p_enemy_a_lookex.cpp index 5d45490cdc..89be42e717 100644 --- a/src/p_enemy_a_lookex.cpp +++ b/src/p_enemy_a_lookex.cpp @@ -548,7 +548,7 @@ bool P_NewLookPlayers (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxd return P_NewLookEnemies (actor, fov, mindist, maxdist, chasegoal); } - if (!(gameinfo.gametype & (GAME_Doom|GAME_Strife)) && + if (!(gameinfo.gametype & (GAME_DoomStrifeChex)) && !multiplayer && players[0].health <= 0) { // Single player game and player is dead; look for monsters diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 14dddb6d6e..4185dfe10f 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -321,7 +321,7 @@ static int GibHealth(AActor *actor) return -abs( actor->GetClass()->Meta.GetMetaInt ( AMETA_GibHealth, - gameinfo.gametype == GAME_Doom ? + gameinfo.gametype & GAME_DoomChex ? -actor->GetDefault()->health : -actor->GetDefault()->health/2)); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 264301ce54..cbe0b93c61 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1896,7 +1896,7 @@ void P_ZMovement (AActor *mo) if (mo->z <= mo->floorz) { if ((mo->flags & MF_MISSILE) && - (gameinfo.gametype != GAME_Doom || !(mo->flags & MF_NOCLIP))) + (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP))) { mo->z = mo->floorz; if (mo->flags2 & MF2_BOUNCETYPE) @@ -2006,7 +2006,7 @@ void P_ZMovement (AActor *mo) mo->momz = -mo->momz; } if (mo->flags & MF_MISSILE && - (gameinfo.gametype != GAME_Doom || !(mo->flags & MF_NOCLIP))) + (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP))) { if (mo->flags3 & MF3_CEILINGHUGGER) { @@ -4025,7 +4025,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc th = Spawn (bloodcls, x, y, z, ALLOW_REPLACE); th->momz = FRACUNIT*2; th->angle = dir; - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { th->tics -= pr_spawnblood() & 3; @@ -4039,7 +4039,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc } // Moved out of the blood actor so that replacing blood is easier - if (gameinfo.gametype & GAME_DoomStrife) + if (gameinfo.gametype & GAME_DoomStrifeChex) { if (gameinfo.gametype == GAME_Strife) { @@ -4861,7 +4861,7 @@ void AActor::Crash() if (crashstate == NULL) { int gibhealth = -abs(GetClass()->Meta.GetMetaInt (AMETA_GibHealth, - gameinfo.gametype == GAME_Doom ? -GetDefault()->health : -GetDefault()->health/2)); + gameinfo.gametype & GAME_DoomChex ? -GetDefault()->health : -GetDefault()->health/2)); if (health < gibhealth) { // Extreme death diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index c6c08237a1..595e95976e 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -344,7 +344,7 @@ static void ParseOuter (FScanner &sc) break; case OUT_IFDOOM: - if (gameinfo.gametype != GAME_Doom) + if (!(gameinfo.gametype & GAME_DoomChex)) { ifskip = true; } diff --git a/src/p_user.cpp b/src/p_user.cpp index 2c1650c13e..23dd67c1ed 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -125,6 +125,11 @@ void SetupPlayerClasses () newclass.Type = PClass::FindClass (NAME_StrifePlayer); PlayerClasses.Push (newclass); } + else if (gameinfo.gametype == GAME_Chex) + { + newclass.Type = PClass::FindClass (NAME_ChexPlayer); + PlayerClasses.Push (newclass); + } } CCMD (clearplayerclasses) diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 701883afa0..b553350d0b 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -86,7 +86,7 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) } else { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { if (flags & ML_RESERVED_ETERNITY) { diff --git a/src/r_things.cpp b/src/r_things.cpp index 34835254dd..36fe76dcea 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -523,7 +523,7 @@ void R_InitSkins (void) if (stricmp (sc.String, "heretic") == 0) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { transtype = PClass::FindClass (NAME_HereticPlayer); skins[i].othergame = true; @@ -547,7 +547,7 @@ void R_InitSkins (void) transtype = PClass::FindClass (NAME_DoomPlayer); skins[i].othergame = true; } - else if (gameinfo.gametype != GAME_Doom) + else if (!(gameinfo.gametype & GAME_DoomChex)) { remove = true; } @@ -618,7 +618,7 @@ void R_InitSkins (void) // [GRB] Assume Doom skin by default if (!remove && basetype == NULL) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { basetype = transtype = PClass::FindClass (NAME_DoomPlayer); } @@ -849,7 +849,7 @@ void R_InitSprites () clearbufshort (zeroarray, MAXWIDTH, 0); // [RH] Create a standard translation to map skins between Heretic and Doom - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype == GAME_DoomChex) { R_CreateSkinTranslation ("SPALHTIC"); } diff --git a/src/r_translate.cpp b/src/r_translate.cpp index dcc7418c73..10f058997a 100644 --- a/src/r_translate.cpp +++ b/src/r_translate.cpp @@ -363,7 +363,7 @@ void R_InitTranslationTables () } // Create the standard translation tables - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { for (i = 0x70; i < 0x80; i++) { // map green ramp to gray, brown, red @@ -575,7 +575,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s bases = s; basev = v; - if (gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Strife) + if (gameinfo.gametype & GAME_DoomStrifeChex) { // Build player sprite translation s -= 0.23f; diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 975d30ef19..7ed3cdec53 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1267,8 +1267,8 @@ static void S_AddSNDINFO (int lump) } break; - case SI_IfDoom: - if (gameinfo.gametype != GAME_Doom) + case SI_IfDoom: //also Chex + if (!(gameinfo.gametype & GAME_DoomChex)) { skipToEndIf = true; } diff --git a/src/st_stuff.cpp b/src/st_stuff.cpp index 2e75fe994c..452718e045 100644 --- a/src/st_stuff.cpp +++ b/src/st_stuff.cpp @@ -153,6 +153,22 @@ static BYTE CheatStoneCold[] = { 's','t','o','n','e','c','o','l','d',255 }; static BYTE CheatElvis[] = { 'e','l','v','i','s',255 }; static BYTE CheatTopo[] = { 't','o','p','o',255 }; +//[BL] Graf will probably get rid of this +static BYTE CheatJoelKoenigs[] = { 'j','o','e','l','k','o','e','n','i','g','s',255 }; +static BYTE CheatDavidBrus[] = { 'd','a','v','i','d','b','r','u','s',255 }; +static BYTE CheatScottHolman[] = { 's','c','o','t','t','h','o','l','m','a','n',255 }; +static BYTE CheatMikeKoenigs[] = { 'm','i','k','e','k','o','e','n','i','g','s',255 }; +static BYTE CheatCharlesJacobi[] = { 'c','h','a','r','l','e','s','j','a','c','o','b','i',255 }; +static BYTE CheatAndrewBenson[] = { 'a','n','d','r','e','w','b','e','n','s','o','n',255 }; +static BYTE CheatDeanHyers[] = { 'd','e','a','n','h','y','e','r','s',255 }; +static BYTE CheatMaryBregi[] = { 'm','a','r','y','b','r','e','g','i',255 }; +static BYTE CheatAllen[] = { 'a','l','l','e','n',255 }; +static BYTE CheatDigitalCafe[] = { 'd','i','g','i','t','a','l','c','a','f','e',255 }; +static BYTE CheatJoshuaStorms[] = { 'j','o','s','h','u','a','s','t','o','r','m','s',255 }; +static BYTE CheatLeeSnyder[] = { 'l','e','e','s','n','y','d','e','r',0,0,255 }; +static BYTE CheatKimHyers[] = { 'k','i','m','h','y','e','r','s',255 }; +static BYTE CheatShrrill[] = { 's','h','r','r','i','l','l',255 }; + static cheatseq_t DoomCheats[] = { { CheatMus, 0, 1, 0, {0,0}, Cht_Music }, @@ -246,6 +262,25 @@ static cheatseq_t StrifeCheats[] = { CheatLego, 0, 0, 0, {CHT_LEGO,0}, Cht_Generic }, }; +static cheatseq_t ChexCheats[] = +{ + { CheatMus, 0, 1, 0, {0,0}, Cht_Music }, + { CheatKimHyers, 0, 1, 0, {0,0}, Cht_MyPos }, + { CheatShrrill, 0, 0, 0, {0,0}, Cht_AutoMap }, + { CheatDavidBrus, 0, 0, 0, {CHT_IDDQD,0}, Cht_Generic }, + { CheatMikeKoenigs, 0, 0, 0, {CHT_IDKFA,0}, Cht_Generic }, + { CheatScottHolman, 0, 0, 0, {CHT_IDFA,0}, Cht_Generic }, + { CheatCharlesJacobi, 0, 0, 0, {CHT_NOCLIP,0}, Cht_Generic }, + { CheatAndrewBenson, 0, 0, 0, {CHT_BEHOLDV,0}, Cht_Generic }, + { CheatDeanHyers, 0, 0, 0, {CHT_BEHOLDS,0}, Cht_Generic }, + { CheatMaryBregi, 0, 0, 0, {CHT_BEHOLDI,0}, Cht_Generic }, + { CheatAllen, 0, 0, 0, {CHT_BEHOLDR,0}, Cht_Generic }, + { CheatDigitalCafe, 0, 0, 0, {CHT_BEHOLDA,0}, Cht_Generic }, + { CheatJoshuaStorms, 0, 0, 0, {CHT_BEHOLDL,0}, Cht_Generic }, + { CheatJoelKoenigs, 0, 0, 0, {CHT_CHAINSAW,0}, Cht_Generic }, + { CheatLeeSnyder, 0, 0, 0, {0,0}, Cht_ChangeLevel } +}; + extern bool CheckCheatmode (); // Respond to keyboard input events, intercept cheats. @@ -282,6 +317,11 @@ bool ST_Responder (event_t *ev) numcheats = countof(StrifeCheats); break; + case GAME_Chex: + cheats = ChexCheats; + numcheats = countof(ChexCheats); + break; + default: return false; } diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 7237fa0ad2..08e4210e47 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -857,6 +857,10 @@ static void ActorGame (FScanner &sc, AActor *defaults, Baggage &bag) { bag.Info->GameFilter |= GAME_Strife; } + else if (sc.Compare ("Chex")) + { + bag.Info->GameFilter |= GAME_Chex; + } else if (sc.Compare ("Any")) { bag.Info->GameFilter = GAME_Any; @@ -1940,8 +1944,8 @@ static void InventoryPickupflash (FScanner &sc, AInventory *defaults, Baggage &b static void InventoryPickupmsg (FScanner &sc, AInventory *defaults, Baggage &bag) { // allow game specific pickup messages - const char * games[] = {"Doom", "Heretic", "Hexen", "Raven", "Strife", NULL}; - int gamemode[]={GAME_Doom, GAME_Heretic, GAME_Hexen, GAME_Raven, GAME_Strife}; + const char * games[] = {"Doom", "Heretic", "Hexen", "Raven", "Strife", "Chex", NULL}; + int gamemode[]={GAME_Doom, GAME_Heretic, GAME_Hexen, GAME_Raven, GAME_Strife, GAME_Chex}; sc.MustGetString(); int game = sc.MatchString(games); diff --git a/src/v_font.cpp b/src/v_font.cpp index 0b4288266b..f7f97cd634 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -286,7 +286,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, BYTE usedcolors[256], identity[256]; double *luminosity; int maxyoffs; - bool doomtemplate = gameinfo.gametype == GAME_Doom ? strncmp (nametemplate, "STCFN", 5) == 0 : false; + bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false; bool stcfn121 = false; Chars = new CharData[count]; @@ -2092,7 +2092,7 @@ void V_InitFonts() } if (!(BigFont=FFont::FindFont("BigFont"))) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { BigFont = new FSingleLumpFont ("BigFont", Wads.GetNumForName ("DBIGFONT")); } diff --git a/src/w_wad.cpp b/src/w_wad.cpp index e6eb5840ec..74189a44eb 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -1412,7 +1412,7 @@ void FWadCollection::RenameSprites (int startlump) // When not playing Doom rename all BLOD sprites to BLUD so that // the same blood states can be used everywhere - if (gameinfo.gametype != GAME_Doom) + if (!(gameinfo.gametype & GAME_DoomChex)) { if (*(DWORD *)LumpInfo[i].name == MAKE_ID('B', 'L', 'O', 'D')) { diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 7c5b443feb..0808cdbd5e 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -64,8 +64,8 @@ CVAR (Bool, wi_noautostartmap, false, CVAR_ARCHIVE) void WI_loadData (); void WI_unloadData (); -#define NEXTSTAGE (gameinfo.gametype == GAME_Doom ? "weapons/rocklx" : "doors/dr1_clos") -#define PASTSTATS (gameinfo.gametype == GAME_Doom ? "weapons/shotgr" : "plats/pt1_stop") +#define NEXTSTAGE (gameinfo.gametype & GAME_DoomChex ? "weapons/rocklx" : "doors/dr1_clos") +#define PASTSTATS (gameinfo.gametype & GAME_DoomChex ? "weapons/shotgr" : "plats/pt1_stop") // GLOBAL LOCATIONS #define WI_TITLEY 2 @@ -314,6 +314,7 @@ void WI_LoadBackground(bool isenterpic) lumpname = NULL; switch(gameinfo.gametype) { + case GAME_Chex: case GAME_Doom: if (gamemode != commercial) { @@ -688,14 +689,14 @@ static void WI_DrawCharPatch (FTexture *patch, int x, int y) { screen->DrawTexture (patch, x, y, DTA_Clean, true, - DTA_ShadowAlpha, (gameinfo.gametype == GAME_Doom) ? 0 : FRACUNIT/2, + DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : FRACUNIT/2, TAG_DONE); } else { screen->DrawTexture (patch, x, y, DTA_Clean, true, - DTA_ShadowAlpha, (gameinfo.gametype == GAME_Doom) ? 0 : FRACUNIT/2, + DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : FRACUNIT/2, DTA_Translation, BigFont->GetColorTranslation (CR_UNTRANSLATED), // otherwise it doesn't look good in Strife! TAG_DONE); } @@ -779,7 +780,7 @@ void WI_drawLF () if (y < NG_STATSY - screen->Font->GetHeight()*3/4) { // don't draw 'finished' if the level name is too high! - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { screen->DrawTexture(finished, 160 - finished->GetWidth()/2, y, DTA_Clean, true, TAG_DONE); } @@ -809,7 +810,7 @@ void WI_drawEL () // draw "entering" // be careful with the added height so that it works for oversized 'entering' patches! - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { screen->DrawTexture(entering, (SCREENWIDTH - entering->GetWidth() * CleanXfac) / 2, y * CleanYfac, DTA_CleanNoMove, true, TAG_DONE); y += entering->GetHeight() + screen->Font->GetHeight()/4; @@ -1557,7 +1558,7 @@ void WI_drawNetgameStats () WI_drawLF(); - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { // draw stat titles (top line) screen->DrawTexture (kills, NG_STATSX+NG_SPACINGX-kills->GetWidth(), NG_STATSY, DTA_Clean, true, TAG_DONE); @@ -1675,7 +1676,7 @@ void WI_updateStats () { WI_updateAnimatedBack (); - if ((gameinfo.gametype != GAME_Doom || acceleratestage) + if ((!(gameinfo.gametype & GAME_DoomChex) || acceleratestage) && sp_state != 10) { if (acceleratestage) @@ -1694,7 +1695,7 @@ void WI_updateStats () if (sp_state == 2) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { cnt_kills[0] += 2; @@ -1710,7 +1711,7 @@ void WI_updateStats () } else if (sp_state == 4) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { cnt_items[0] += 2; @@ -1726,7 +1727,7 @@ void WI_updateStats () } else if (sp_state == 6) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { cnt_secret[0] += 2; @@ -1742,7 +1743,7 @@ void WI_updateStats () } else if (sp_state == 8) { - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { if (!(bcnt&3)) S_Sound (CHAN_VOICE | CHAN_UI, "weapons/pistol", 1, ATTN_NONE); @@ -1800,7 +1801,7 @@ void WI_drawStats (void) WI_drawLF(); - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { screen->DrawTexture (kills, SP_STATSX, SP_STATSY, DTA_Clean, true, TAG_DONE); WI_drawPercent (320 - SP_STATSX, SP_STATSY, cnt_kills[0], wbs->maxkills); @@ -1956,7 +1957,7 @@ void WI_loadData(void) int i; char name[9]; - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & GAME_DoomChex) { wiminus = TexMan["WIMINUS"]; // minus sign percent = TexMan["WIPCNT"]; // percent sign diff --git a/src/win32/i_crash.cpp b/src/win32/i_crash.cpp index ed4c4b205b..e0e9416e61 100644 --- a/src/win32/i_crash.cpp +++ b/src/win32/i_crash.cpp @@ -944,7 +944,7 @@ static void AddStackInfo (HANDLE file, void *dumpaddress, DWORD code, CONTEXT *c } #endif Writef (file, " "); - for (i = 0; i < max*sizeof(void*); ++i) + for (i = 0; i < int(max*sizeof(void*)); ++i) { if (!SafeReadMemory ((BYTE *)scan + i, &peekb, 1)) { diff --git a/src/win32/st_start.cpp b/src/win32/st_start.cpp index 66c7512c4b..bf44922dd2 100644 --- a/src/win32/st_start.cpp +++ b/src/win32/st_start.cpp @@ -1092,7 +1092,7 @@ void ST_Endoom() if (showendoom == 0) exit(0); int endoom_lump = Wads.CheckNumForName ( - gameinfo.gametype == GAME_Doom? "ENDOOM" : + gameinfo.gametype & GAME_DoomChex ? "ENDOOM" : gameinfo.gametype == GAME_Heretic? "ENDTEXT" : gameinfo.gametype == GAME_Strife? "ENDSTRF" : NULL); diff --git a/wadsrc/static/actors/chex/chexammo.txt b/wadsrc/static/actors/chex/chexammo.txt new file mode 100644 index 0000000000..1117bbe760 --- /dev/null +++ b/wadsrc/static/actors/chex/chexammo.txt @@ -0,0 +1,86 @@ +// Renaming and changing messages + +// Mini Zorch ----------------------------------------------------------------- + +actor MiniZorchRecharge : Clip 2007 +{ + Game Chex + inventory.pickupmessage "$GOTZORCHRECHARGE" +} + +actor MiniZorchPack : Clip 2048 +{ + Game Chex + Inventory.PickupMessage "$GOTMINIZORCHPACK" + Inventory.Amount 50 + States + { + Spawn: + AMMO A -1 + Stop + } +} + +// Large Zorch ---------------------------------------------------------------- + +actor LargeZorchRecharge : Shell 2008 +{ + Game Chex + inventory.pickupmessage "$GOTLARGEZORCHERRECHARGE" +} + +actor LargeZorchPack : Shell 2049 +{ + Game Chex + Inventory.PickupMessage "GOTLARGEZORCHERPACK" + Inventory.Amount 20 + States + { + Spawn: + SBOX A -1 + Stop + } +} + +// Zorch Propulsor ------------------------------------------------------------ + +actor PropulsorZorch : RocketAmmo 2010 +{ + Game Chex + inventory.pickupmessage "$GOTPROPULSORRECHARGE" +} + +actor PropulsorZorchPack : RocketAmmo 2046 +{ + Game Chex + Inventory.PickupMessage "$GOTPROPULSORPACK" + Inventory.Amount 5 + States + { + Spawn: + BROK A -1 + Stop + } +} + +// Phasing Zorch -------------------------------------------------------------- + +actor PhasingZorch : Cell 2047 +{ + Game Chex + inventory.pickupmessage "$GOTPHASINGZORCHERRECHARGE" +} + +actor PhasingZorchPack : Cell 17 +{ + Game Chex + SpawnID 142 + Inventory.PickupMessage "$GOTPHASINGZORCHERPACK" + Inventory.Amount 100 + States + { + Spawn: + CELP A -1 + Stop + } +} diff --git a/wadsrc/static/actors/chex/chexdecorations.txt b/wadsrc/static/actors/chex/chexdecorations.txt new file mode 100644 index 0000000000..877df883e4 --- /dev/null +++ b/wadsrc/static/actors/chex/chexdecorations.txt @@ -0,0 +1,205 @@ +// Doom items renamed with height changes + +// Civilians ------------------------------------------------------------------ + +actor Civilian1 : GreenTorch 45 +{ + game Chex + height 54 +} + +actor Civilian2 : ShortGreenTorch 56 +{ + game Chex + height 54 +} + +actor Civilian3 : ShortRedTorch 57 +{ + game Chex + height 48 +} + +actor DeadChexWarrior : DeadMarine 15 +{ + game Chex +} + +actor DeadChexWarrior2 : GibbedMarine 10 +{ + game Chex +} + +actor DeadChexWarrior3 : GibbedMarineExtra 12 +{ + game Chex +} + +// Landing Zone --------------------------------------------------------------- + +actor LandingLight : Column 2028 +{ + game Chex + height 35 +} + +actor Spaceship : TechPillar 48 +{ + game Chex + height 52 +} + +// Trees and Plants ----------------------------------------------------------- + +actor AppleTree : Stalagtite 47 +{ + game Chex + height 92 +} + +actor BananaTree : BigTree 54 +{ + game Chex + height 108 +} + +actor HangingFlowerPot : Meat2 50 +{ + game Chex +} + +actor HangingFlowerPot2 : Meat3 51 +{ + game Chex +} + +actor HangingFlowerPotNonSolid : HangingFlowerPot 59 +{ + game Chex + -SOLID + radius 20 +} + +actor HangingFlowerPot2NonSolid : HangingFlowerPot2 61 +{ + game Chex + -SOLID + radius 20 +} + +actor OrangeTree : TorchTree 43 +{ + game Chex + height 92 +} + +actor SubmergedPlant : ShortGreenColumn 31 +{ + game Chex + height 42 +} + +actor TallFlower : HeadsOnAStick 28 +{ + game Chex + height 25 +} + +actor TallFlower2 : DeadStick 25 +{ + game Chex + height 25 +} + +// Slime Fountain ------------------------------------------------------------- + +actor SlimeFountain : BlueTorch 44 +{ + game Chex + height 48 +} + +// Cavern Decorations --------------------------------------------------------- + +actor CavernBat : BloodyTwitch 49 +{ + game Chex + height 52 +} + +actor CavernBatNonSolid : CavernBat 63 +{ + game Chex + -SOLID + radius 20 +} + +actor CavernColumn : TallRedColumn 32 +{ + game Chex + height 128 +} + +actor CavernStalactite : Meat5 53 +{ + game Chex + height 48 +} + +actor CavernStalagmite : TallGreenColumn 30 +{ + game Chex + height 60 +} + +actor NonSolidCavernStalactite : CavernStalactite 62 +{ + game Chex + -SOLID + radius 20 +} + +// Misc. Props ---------------------------------------------------------------- + +actor ChemicalBurner : EvilEye 41 +{ + game Chex + height 25 +} + +actor ChemicalFlask : Candlestick 34 +{ + game Chex + renderstyle translucent + alpha 0.75 +} + +// Who's idea was it to put an invisible thing on E1M4? +actor DeadCycloptisCommonus : DeadDemon 21 +{ + game Chex +} + +actor FlagOnPole : SkullColumn 37 +{ + game Chex + height 128 +} + +actor GasTank : Candelabra 35 +{ + game Chex + height 36 +} + +actor LightColumn : ShortBlueTorch 55 +{ + game Chex + height 86 +} + +actor MineCart : ShortRedColumn 33 +{ + game Chex + height 30 +} diff --git a/wadsrc/static/actors/chex/chexitems.txt b/wadsrc/static/actors/chex/chexitems.txt new file mode 100644 index 0000000000..0247672c04 --- /dev/null +++ b/wadsrc/static/actors/chex/chexitems.txt @@ -0,0 +1,68 @@ + +// General Pickups ============================================================ + +// Health --------------------------------------------------------------------- + +actor GlassOfWater : HealthBonus 2014 +{ + game Chex + inventory.pickupmessage "$GOTWATER" +} + +actor BowlOfFruit : Stimpack 2011 +{ + game Chex + inventory.pickupmessage "$GOTFRUIT" +} + +actor BowlOfVegetables : Medikit 2012 +{ + game Chex + inventory.pickupmessage "$GOTVEGETABLES" + health.lowmessage 25, "$GOTVEGETABLESNEED" +} + +actor SuperchargeBreakfast : Soulsphere 2013 +{ + game Chex + inventory.pickupmessage "$GOTBREAKFAST" +} + +// Armor ---------------------------------------------------------------------- + +actor SlimeRepellent : ArmorBonus 2015 +{ + game Chex + inventory.pickupmessage "$GOTREPELLENT" +} + +actor ChexArmor : GreenArmor 2018 +{ + game Chex + inventory.pickupmessage "$GOTCHEXARMOR" +} + +actor SuperChexArmor : BlueArmor 2019 +{ + game Chex + inventory.pickupmessage "$GOTSUPERCHEXARMOR" +} + +// Powerups =================================================================== + +actor ComputerAreaMap : Allmap 2026 +{ + game Chex +} + +actor SlimeProofSuit : RadSuit 2025 +{ + game Chex + inventory.pickupmessage "$GOTSLIMESUIT" +} + +actor Zorchpack : Backpack 8 +{ + game Chex + inventory.pickupmessage "$GOTZORCHPACK" +} diff --git a/wadsrc/static/actors/chex/chexkeys.txt b/wadsrc/static/actors/chex/chexkeys.txt new file mode 100644 index 0000000000..60c9ce54ed --- /dev/null +++ b/wadsrc/static/actors/chex/chexkeys.txt @@ -0,0 +1,19 @@ +// These are merely renames of the Doom cards + +actor ChexBlueCard : BlueCard 5 +{ + Game Chex + inventory.pickupmessage "$GOTCBLUEKEY" +} + +actor ChexYellowCard : YellowCard 6 +{ + Game Chex + inventory.pickupmessage "$GOTCYELLOWKEY" +} + +actor ChexRedCard : RedCard 13 +{ + Game Chex + inventory.pickupmessage "$GOTCREDKEY" +} diff --git a/wadsrc/static/actors/chex/chexmonsters.txt b/wadsrc/static/actors/chex/chexmonsters.txt new file mode 100644 index 0000000000..3ee9f43f73 --- /dev/null +++ b/wadsrc/static/actors/chex/chexmonsters.txt @@ -0,0 +1,89 @@ + +//=========================================================================== +// +// Flemoidus Commonus +// +//=========================================================================== + +actor FlemoidusCommonus : ZombieMan 3004 +{ + Game Chex + DropItem "" + States + { + Missile: + stop + Melee: + goto Super::Missile + } +} + +//=========================================================================== +// +// Flemoidus Bipedicus +// +//=========================================================================== + +actor FlemoidusBipedicus : ShotgunGuy 9 +{ + Game Chex + DropItem "" + States + { + Missile: + stop + Melee: + goto Super::Missile + } +} + +//=========================================================================== +// +// Flemoidus Bipedicus w/ Armor +// +//=========================================================================== + +actor ArmoredFlemoidusBipedicus : DoomImp 3001 +{ + Game Chex +} + +//=========================================================================== +// +// Flemoidus Cycloptis Commonus +// +//=========================================================================== + +actor FlemoidusCycloptisCommonus : Demon 3002 +{ + Game Chex +} + +//=========================================================================== +// +// The Flembrane +// +//=========================================================================== + +actor Flembrane : BaronOfHell 3003 +{ + Game Chex + radius 44 + height 100 + speed 0 + States + { + Missile: + BOSS EF 3 A_FaceTarget + BOSS G 0 A_BruisAttack + goto See + } +} + +//=========================================================================== + +actor ChexSoul : LostSoul 3006 +{ + Game Chex + height 0 +} diff --git a/wadsrc/static/actors/chex/chexplayer.txt b/wadsrc/static/actors/chex/chexplayer.txt new file mode 100644 index 0000000000..d9e654f4e5 --- /dev/null +++ b/wadsrc/static/actors/chex/chexplayer.txt @@ -0,0 +1,11 @@ +// Chex Warrior + +actor ChexPlayer : DoomPlayer +{ + player.displayname "Chex Warrior" + player.crouchsprite "" + player.colorrange 192, 207 //Not perfect, but its better than everyone being blue. + player.startitem "MiniZorcher" + player.startitem "Bootspoon" + player.startitem "MiniZorchRecharge", 50 +} diff --git a/wadsrc/static/actors/chex/chexweapons.txt b/wadsrc/static/actors/chex/chexweapons.txt new file mode 100644 index 0000000000..dde9fd9e04 --- /dev/null +++ b/wadsrc/static/actors/chex/chexweapons.txt @@ -0,0 +1,64 @@ +// Same as Doom weapons, but the obituaries are removed. + +actor Bootspoon : Fist +{ + obituary "" +} + +actor SuperBootspork : Chainsaw 2005 +{ + obituary "" +} + +actor MiniZorcher : Pistol +{ + obituary "" + inventory.pickupmessage "$GOTMINIZORCHER" + states + { + Spawn: + stop + } +} + +actor LargeZorcher : Shotgun 2001 +{ + game Chex + obituary "" + inventory.pickupmessage "$GOTLARGEZORCHER" +} + +actor SuperLargeZorcher : SuperShotgun 82 +{ + game Chex + obituary "" + inventory.pickupmessage "$GOTSUPERLARGEZORCHER" +} + +actor RapidZorcher : Chaingun 2002 +{ + game Chex + obituary "" + inventory.pickupmessage "$GOTRAPIDZORCHER" +} + +actor ZorchPropulsor : RocketLauncher 2003 +{ + game Chex + obituary "" + inventory.pickupmessage "$GOTZORCHPROPULSOR" +} + +actor PhasingZorcher : PlasmaRifle 2004 +{ + game Chex + obituary "" + inventory.pickupmessage "$GOTPHASINGZORCHER" +} + +actor LAZDevice : BFG9000 2006 +{ + game Chex + obituary "" + inventory.pickupmessage "$GOTLAZDEVICE" +} diff --git a/wadsrc/static/decorate.txt b/wadsrc/static/decorate.txt index 6df4f842ae..d2178dccd9 100644 --- a/wadsrc/static/decorate.txt +++ b/wadsrc/static/decorate.txt @@ -167,3 +167,11 @@ #include "actors/strife/templar.txt" #include "actors/strife/zombie.txt" #include "actors/strife/sigil.txt" + +#include "actors/chex/chexmonsters.txt" +#include "actors/chex/chexkeys.txt" +#include "actors/chex/chexammo.txt" +#include "actors/chex/chexweapons.txt" +#include "actors/chex/chexitems.txt" +#include "actors/chex/chexdecorations.txt" +#include "actors/chex/chexplayer.txt" diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index aa0150ea9b..07c7e8a3dc 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -37,6 +37,10 @@ QUITMSG20 = "fine! just kill and run!"; QUITMSG21 = "you can quit...\nbut you can't hide..."; QUITMSG22 = "whaaa, what's the matter?\nmommy says dinnertime?"; +// Quit Chex messages +QUITMSG23 = "Don't give up now...do\nyou still wish to quit?"; +QUITMSG24 = "please don't leave, we\nneed your help!"; //7 times as likely to show + LOADNET = "you can't do load while in a net game!\n\npress a key."; QLOADNET = "you can't quickload during a netgame!\n\npress a key."; QSAVESPOT = "you haven't picked a quicksave slot yet!\n\npress a key."; @@ -1301,3 +1305,75 @@ BBA_SCROTUM = "%o suffered scrotum separation"; BBA_POPULATION = "%o volunteered for population control"; BBA_SUICIDE = "%o has suicided"; BBA_DARWIN = "%o received the Darwin Award"; + +// Chex Quest Strings +CHUSTR_E1M1 = "E1M1: Landing Zone"; +CHUSTR_E1M2 = "E1M2: Storage Facility"; +CHUSTR_E1M3 = "E1M3: Experimental Lab"; +CHUSTR_E1M4 = "E1M4: Arboretum"; +CHUSTR_E1M5 = "E1M5: Caverns of Bazoik"; + +CE1TEXT = + "Mission accomplished.\n" + "\n" + "Are you prepared for the next mission?\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "Press the escape key to continue..."; + +CE2TEXT = "You've done it!"; +CE3TEXT = "Wonderful Job!"; +CE4TEXT = "Fantastic"; + +CLOADNET = "you can't do load while in a net quest!\n\npress a key."; +CQSPROMPT = "quicksave over your quest named\n\n'%s'?\n\npress y or n."; +CQLOADNET = "you can't quickload during a netquest!\n\npress a key."; +CQLPROMPT = "do you want to quickload the quest named\n\n'%s'?\n\npress y or n."; +CNEWGAME = "you can't start a new quest\nwhile in a network quest.\n\npress a key."; + +CNIGHTMARE = "Careful, this will be tough.\nDo you wish to continue?\n\npress y or n."; + +CSWSTRING = "this is Chex(R) Quest. look for\n\nfuture levels at www.chexquest.com.\n\npress a key."; + +CNETEND = "you can't end a netquest!\n\npress a key."; +CENDGAME = "are you sure you want to end the quest?\n\npress y or n."; + +GOTCHEXARMOR = "Picked up the Chex(R) Armor."; +GOTSUPERCHEXARMOR = "Picked up the Super Chex(R) Armor!"; +GOTWATER = "Picked up a glass of water."; +GOTREPELLENT = "Picked up slime repellent."; +GOTBREAKFAST = "Supercharge Breakfast!"; +GOTCBLUEKEY = "Picked up a blue key."; +GOTCYELLOWKEY = "Picked up a yallow key."; +GOTCREDKEY = "Picked up a red key."; +GOTFRUIT = "Picked up a bowl of fruit."; +GOTVEGETABLESNEED = "Picked up some needed vegetables!"; +GOTVEGETABLES = "Picked up a bowl of vegetables."; +GOTSLIMESUIT = "Slimeproof Suit"; +GOTZORCHRECHARGE = "Picked up a mini zorch recharge."; +GOTMINIZORCHPACK = "Picked up a mini zorch pack."; +GOTPROPULSORRECHARGE = "Picked up a zorch propulsor recharge."; +GOTPROPULSORPACK = "Picked up a zorch propulsor pack."; +GOTPHASINGZORCHERRECHARGE = "Picked up a phasing zorcher recharge"; +GOTPHASINGZORCHERPACK = "Picked up a phasing zorcher pack."; +GOTLARGEZORCHERRECHARGE = "Picked up a large zorcher recharge."; +GOTLARGEZORCHERPACK = "Picked up a large zorcher pack."; +GOTZORCHPACK = "Picked up a Zorchpak!"; +GOTLAZDEVICE = "You got the LAZ Device!"; +GOTRAPIDZORCHER = "You got the Rapid Zorcher!"; +GOTSUPERBOOTSPORK = "You got the Super Bootspork!"; +GOTZORCHPROPULSOR = "You got the Zorch Propulsor!"; +GOTPHASINGZORCHER = "You got the Phasing Zorcher!"; +GOTLARGEZORCHER = "You got the Large Zorcher!"; +GOTSUPERLARGEZORCHER = "You got the Super Large Zorcher!"; +GOTMINIZORCHER = "Picked up a Mini Zorcher."; + +STSTR_CDQDON = "Invincible Mode ON"; +STSTR_CDQDOFF = "Invincible Mode OFF"; +STSTR_CFAADDED = "Zorch Added"; +STSTR_CKFAADDED = "Super Zorch Added"; +STSTR_CCHOPPERS = "... Eat Chex(R)!"; diff --git a/wadsrc/static/lockdefs.txt b/wadsrc/static/lockdefs.txt index d16d68e47a..a6ddd74bad 100644 --- a/wadsrc/static/lockdefs.txt +++ b/wadsrc/static/lockdefs.txt @@ -558,3 +558,58 @@ Lock 51 Strife Mapcolor 150 150 150 } +// +// Chex Locks +// + +Lock 1 Chex +{ + ChexRedCard + Message "$PD_REDC" + RemoteMessage "$PD_REDCO" + Mapcolor 255 0 0 +} + + +Lock 2 Chex +{ + ChexBlueCard + Message "$PD_BLUEC" + RemoteMessage "$PD_BLUECO" + Mapcolor 0 0 255 +} + + +Lock 3 Chex +{ + ChexYellowCard + Message "$PD_YELLOWC" + RemoteMessage "$PD_YELLOWCO" + Mapcolor 255 255 0 +} + +Lock 129 Chex +{ + ChexRedCard + Message "$PD_REDK" + RemoteMessage "$PD_REDO" + Mapcolor 255 0 0 +} + + +Lock 130 Chex +{ + ChexBlueCard + Message "$PD_BLUEK" + RemoteMessage "$PD_BLUEO" + Mapcolor 0 0 255 +} + + +Lock 131 Chex +{ + ChexYellowCard + Message "$PD_YELLOWK" + RemoteMessage "$PD_YELLOWO" + Mapcolor 255 255 0 +} diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index 2c6b412ee1..efd805e7e0 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -1,3 +1,37 @@ +skill baby + AmmoFactor 2 + DamageFactor 0.5 + EasyBossBrain + SpawnFilter "Baby" + PicName "M_JKILL" + Key i + +skill easy + EasyBossBrain + SpawnFilter "Easy" + PicName "M_ROUGH" + Key h + +skill normal + SpawnFilter "Normal" + PicName "M_HURT" + Key h + +skill hard + SpawnFilter "Hard" + PicName "M_ULTRA" + Key u + +skill nightmare + AmmoFactor 2 + FastMonsters + DisableCheats + RespawnTime 12 + SpawnFilter "Nightmare" + PicName "M_NMARE" + MustConfirm "$CNIGHTMARE" + Key n + // MAPINFO for Chex Quest clearepisodes @@ -7,7 +41,7 @@ episode e1m1 // Registered/Retail Episode 1 -map E1M1 lookup HUSTR_E1M1 +map E1M1 lookup CHUSTR_E1M1 levelnum 1 titlepatch WILV00 next E1M2 @@ -18,7 +52,7 @@ par 30 sucktime 1 music D_E1M1 -map E1M2 lookup HUSTR_E1M2 +map E1M2 lookup CHUSTR_E1M2 levelnum 2 titlepatch WILV01 next E1M3 @@ -29,7 +63,7 @@ par 75 sucktime 1 music D_E1M2 -map E1M3 lookup HUSTR_E1M3 +map E1M3 lookup CHUSTR_E1M3 levelnum 3 titlepatch WILV02 next E1M4 @@ -40,7 +74,7 @@ par 120 sucktime 1 music D_E1M3 -map E1M4 lookup HUSTR_E1M4 +map E1M4 lookup CHUSTR_E1M4 levelnum 4 titlepatch WILV03 next E1M5 @@ -51,7 +85,7 @@ par 90 sucktime 1 music D_E1M4 -map E1M5 lookup HUSTR_E1M5 +map E1M5 lookup CHUSTR_E1M5 levelnum 5 titlepatch WILV04 next EndGame1 @@ -68,20 +102,20 @@ music D_E1M5 clusterdef 1 flat FLOOR4_8 music D_VICTOR -exittext lookup E1TEXT +exittext lookup CE1TEXT clusterdef 2 flat SFLR6_1 music D_VICTOR -exittext lookup E2TEXT +exittext lookup CE2TEXT clusterdef 3 flat MFLR8_4 music D_VICTOR -exittext lookup E3TEXT +exittext lookup CE3TEXT clusterdef 4 flat MFLR8_3 music D_VICTOR -exittext lookup E4TEXT +exittext lookup CE4TEXT