diff --git a/specs/usdf_gzdoom.txt b/specs/usdf_gzdoom.txt new file mode 100644 index 000000000..6c71d3b9c --- /dev/null +++ b/specs/usdf_gzdoom.txt @@ -0,0 +1,63 @@ +=============================================================================== +GZDoom Strife Dialog Format v1.0 +based on ZDoom Strife Dialog Format ZDoom v1.1 - 23.08.2010 + + Copyright (c) 2019 Rachael Alexanderson + uses ZDoom Strife Dialog Format ZDoom v1.1 as a template, + original document Copyright (c) 2010 Christoph Oelckers. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + +=============================================================================== + +======================================= +I. Grammar / Syntax +======================================= + + No changes. + +======================================= +II. Implementation Semantics +======================================= + + No changes. + +======================================= +III. Changes to ZSDF spec +======================================= + + GZDoom Strife Dialogue format implements the ZSDF base specification as described with + the improvement of being able to name pages using strings. + + GZDoom-format dialogues need to start with this line: + + namespace = "GZDoom"; + + +--------------------- +III.A : Conversations +--------------------- + + This block only lists the newly added fields. Currently GZDoom only modifies the following + fields and adds the "pagename" field to the specification: + + conversation // Starts a dialog. + { + page + { + pagename = ; // names the current page, for linking using links or responses + link = ; // if int, uses the old system of linking page by number + // if string, will parse item links to a named page + + choice + { + next = ; // same as link above, can either go to a name or id + } + } + } + +=============================================================================== +EOF +=============================================================================== diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 957f3b0a2..cbe7f1047 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -544,6 +544,11 @@ static void ParseReplies (const char *name, int pos, FStrifeDialogueReply **repl // The next node to use when this reply is chosen. reply->NextNode = rsp->Link; + if (reply->NextNode < 0) + { + reply->NextNode *= -1; + reply->CloseDialog = false; + } // The message to record in the log for this reply. reply->LogNumber = rsp->Log; @@ -1090,14 +1095,13 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply if (reply->NextNode != 0) { int rootnode = npc->ConversationRoot; - const bool isNegative = reply->NextNode < 0; - const unsigned next = (unsigned)(rootnode + (isNegative ? -1 : 1) * reply->NextNode - 1); + const unsigned next = (unsigned)(rootnode + reply->NextNode - 1); if (next < Level->StrifeDialogues.Size()) { npc->Conversation = Level->StrifeDialogues[next]; - if (isNegative) + if (!(reply->CloseDialog)) { if (gameaction != ga_slideshow) { diff --git a/src/p_conversation.h b/src/p_conversation.h index 63e7707d9..d102e59f7 100644 --- a/src/p_conversation.h +++ b/src/p_conversation.h @@ -24,6 +24,8 @@ struct FStrifeDialogueNode TArray ItemCheck; int ThisNodeNum = 0; // location of this node in StrifeDialogues int ItemCheckNode = 0; // index into StrifeDialogues + FString ThisNodeName = nullptr; + FString ItemCheckNodeName = nullptr; PClassActor *SpeakerType = nullptr; FString SpeakerName; @@ -54,7 +56,9 @@ struct FStrifeDialogueReply FString LogString; int NextNode = 0; // index into StrifeDialogues int LogNumber = 0; + FString NextNodeName = nullptr; bool NeedsGold = false; + bool CloseDialog = true; }; struct MapData; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 75e18fa37..6cd290c1b 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1143,7 +1143,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da // Handle active damage modifiers (e.g. PowerDamage) if (damage > 0 && !(flags & DMG_NO_ENHANCE)) { - damage = source->GetModifiedDamage(mod, damage, false, inflictor, source, flags); + damage = source->GetModifiedDamage(mod, damage, false, inflictor, target, flags); } } // Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers. diff --git a/src/p_usdf.cpp b/src/p_usdf.cpp index cf579e790..e88bbeda8 100644 --- a/src/p_usdf.cpp +++ b/src/p_usdf.cpp @@ -44,6 +44,7 @@ #define Zd 1 #define St 2 +#define Gz 4 class USDFParser : public UDMFParserBase { @@ -62,7 +63,7 @@ class USDFParser : public UDMFParserBase { type = GetStrifeType(CheckInt(key)); } - else if (namespace_bits == Zd) + else if (namespace_bits & ( Zd | Gz )) { PClassActor *cls = PClass::FindActor(CheckString(key)); if (cls == nullptr) @@ -188,7 +189,10 @@ class USDFParser : public UDMFParserBase break; case NAME_Nextpage: - reply->NextNode = CheckInt(key); + if (namespace_bits != Gz || sc.TokenType == TK_IntConst) + reply->NextNode = CheckInt(key); + else + reply->NextNodeName = CheckString(key); break; case NAME_Closedialog: @@ -202,7 +206,7 @@ class USDFParser : public UDMFParserBase break; case NAME_SpecialName: - if (namespace_bits == Zd) + if (namespace_bits & ( Zd | Gz )) reply->ActionSpecial = P_FindLineSpecial(CheckString(key)); break; @@ -225,7 +229,7 @@ class USDFParser : public UDMFParserBase case NAME_Require: case NAME_Exclude: // Require and Exclude are exclusive to namespace ZDoom. [FishyClockwork] - if (key == NAME_Cost || namespace_bits == Zd) + if (key == NAME_Cost || (namespace_bits & ( Zd | Gz ))) { ParseCostRequireExclude(reply, key); break; @@ -256,7 +260,15 @@ class USDFParser : public UDMFParserBase reply->QuickNo = ""; } reply->LogString = LogString; - if(!closeDialog) reply->NextNode *= -1; + if (reply->NextNode < 0) // compatibility: handle negative numbers + { + reply->CloseDialog = !closeDialog; + reply->NextNode *= -1; + } + else + { + reply->CloseDialog = closeDialog; + } return true; } @@ -318,6 +330,13 @@ class USDFParser : public UDMFParserBase { switch(key) { + case NAME_Pagename: + if (namespace_bits != Gz) + sc.ScriptMessage("'PageName' keyword only supported in the GZDoom namespace!"); + else + node->ThisNodeName = CheckString(key); + break; + case NAME_Name: SpeakerName = CheckString(key); break; @@ -327,7 +346,7 @@ class USDFParser : public UDMFParserBase break; case NAME_Userstring: - if (namespace_bits == Zd) + if (namespace_bits & ( Zd | Gz )) { node->UserData = CheckString(key); } @@ -341,7 +360,7 @@ class USDFParser : public UDMFParserBase FString soundname = "svox/"; soundname += name; node->SpeakerVoice = FSoundID(S_FindSound(soundname)); - if (node->SpeakerVoice == 0 && namespace_bits == Zd) + if (node->SpeakerVoice == 0 && (namespace_bits & ( Zd | Gz ))) { node->SpeakerVoice = FSoundID(S_FindSound(name)); } @@ -358,12 +377,15 @@ class USDFParser : public UDMFParserBase break; case NAME_Link: - node->ItemCheckNode = CheckInt(key); + if (namespace_bits != Gz || sc.TokenType == TK_IntConst) + node->ItemCheckNode = CheckInt(key); + else + node->ItemCheckNodeName = CheckString(key); break; case NAME_Goodbye: // Custom goodbyes are exclusive to namespace ZDoom. [FishyClockwork] - if (namespace_bits == Zd) + if (namespace_bits & ( Zd | Gz )) { Goodbye = CheckString(key); } @@ -425,14 +447,14 @@ class USDFParser : public UDMFParserBase break; case NAME_Id: - if (namespace_bits == Zd) + if (namespace_bits & ( Zd | Gz )) { dlgid = CheckInt(key); } break; case NAME_Class: - if (namespace_bits == Zd) + if (namespace_bits & ( Zd | Gz )) { clsid = CheckString(key); } @@ -487,6 +509,9 @@ public: namespc = sc.String; switch(namespc) { + case NAME_GZDoom: + namespace_bits = Gz; + break; case NAME_ZDoom: namespace_bits = Zd; break; @@ -501,7 +526,7 @@ public: } else { - sc.ScriptMessage("Map does not define a namespace.\n"); + sc.ScriptMessage("Dialog script does not define a namespace.\n"); return false; } @@ -524,6 +549,58 @@ public: Skip(); } } + + if (namespace_bits == Gz) // string page name linker + { + int numnodes = Level->StrifeDialogues.Size(); + int usedstrings = false; + + TMap nameToIndex; + for (int i = 0; i < numnodes; i++) + { + FString key = Level->StrifeDialogues[i]->ThisNodeName; + if (key.IsNotEmpty()) + { + key.ToLower(); + if (nameToIndex.CheckKey(key)) + Printf("Warning! Duplicate page name '%s'!\n", Level->StrifeDialogues[i]->ThisNodeName.GetChars()); + else + nameToIndex[key] = i; + usedstrings = true; + } + } + if (usedstrings) + { + for (int i = 0; i < numnodes; i++) + { + FString itemLinkKey = Level->StrifeDialogues[i]->ItemCheckNodeName; + if (itemLinkKey.IsNotEmpty()) + { + itemLinkKey.ToLower(); + if (nameToIndex.CheckKey(itemLinkKey)) + Level->StrifeDialogues[i]->ItemCheckNode = nameToIndex[itemLinkKey] + 1; + else + Printf("Warning! Reference to non-existent item-linked dialogue page name '%s' in page %i!\n", Level->StrifeDialogues[i]->ItemCheckNodeName.GetChars(), i); + } + + FStrifeDialogueReply *NodeCheck = Level->StrifeDialogues[i]->Children; + while (NodeCheck) + { + if (NodeCheck->NextNodeName.IsNotEmpty()) + { + FString key = NodeCheck->NextNodeName; + key.ToLower(); + if (nameToIndex.CheckKey(key)) + NodeCheck->NextNode = nameToIndex[key] + 1; + else + Printf("Warning! Reference to non-existent reply-linked dialogue page name '%s' in page %i!\n", NodeCheck->NextNodeName.GetChars(), i); + } + NodeCheck = NodeCheck->Next; + } + } + } + + } return true; } }; diff --git a/src/posix/sdl/i_input.cpp b/src/posix/sdl/i_input.cpp index 10c46a4a4..626b9580f 100644 --- a/src/posix/sdl/i_input.cpp +++ b/src/posix/sdl/i_input.cpp @@ -379,7 +379,12 @@ void MessagePump (const SDL_Event &sev) else { event.type = EV_KeyDown; - event.data1 = sev.wheel.y > 0 ? KEY_MWHEELUP : KEY_MWHEELDOWN; + + if (sev.wheel.y != 0) + event.data1 = sev.wheel.y > 0 ? KEY_MWHEELUP : KEY_MWHEELDOWN; + else + event.data1 = sev.wheel.x > 0 ? KEY_MWHEELRIGHT : KEY_MWHEELLEFT; + D_PostEvent (&event); event.type = EV_KeyUp; D_PostEvent (&event); diff --git a/src/utility/namedef.h b/src/utility/namedef.h index f47720066..9fb39bfc6 100644 --- a/src/utility/namedef.h +++ b/src/utility/namedef.h @@ -565,6 +565,7 @@ xx(Monsterpush) xx(ZDoom) xx(ZDoomTranslated) xx(Vavoom) +xx(GZDoom) xx(Xpanningfloor) xx(Ypanningfloor) @@ -742,6 +743,7 @@ xx(Require) xx(Exclude) xx(Userstring) xx(Sky) +xx(Pagename) // Special menus xx(Mainmenu) diff --git a/src/v_font.cpp b/src/v_font.cpp index b1ce4812a..37a54d381 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -990,9 +990,9 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) return new FSingleLumpFont (name, lump); } } - FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any); - if (picnum.isValid()) - { + FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any); + if (picnum.isValid()) + { FTexture *tex = TexMan.GetTexture(picnum); if (tex && tex->GetSourceLump() >= folderfile) { @@ -1002,7 +1002,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) if (folderdata.Size() > 0) { return new FFont(name, nullptr, name, HU_FONTSTART, HU_FONTSIZE, 1, -1); - } + } } return font; } @@ -1111,22 +1111,22 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla int position = '!' + i; mysnprintf(buffer, countof(buffer), nametemplate, i + start); - lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch); - if (doomtemplate && lump.isValid() && i + start == 121) - { // HACKHACK: Don't load STCFN121 in doom(2), because - // it's not really a lower-case 'y' but a '|'. - // Because a lot of wads with their own font seem to foolishly - // copy STCFN121 and make it a '|' themselves, wads must - // provide STCFN120 (x) and STCFN122 (z) for STCFN121 to load as a 'y'. - if (!TexMan.CheckForTexture("STCFN120", ETextureType::MiscPatch).isValid() || - !TexMan.CheckForTexture("STCFN122", ETextureType::MiscPatch).isValid()) - { - // insert the incorrectly named '|' graphic in its correct position. - position = 124; - } - } - if (lump.isValid()) + lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch); + if (doomtemplate && lump.isValid() && i + start == 121) + { // HACKHACK: Don't load STCFN121 in doom(2), because + // it's not really a lower-case 'y' but a '|'. + // Because a lot of wads with their own font seem to foolishly + // copy STCFN121 and make it a '|' themselves, wads must + // provide STCFN120 (x) and STCFN122 (z) for STCFN121 to load as a 'y'. + if (!TexMan.CheckForTexture("STCFN120", ETextureType::MiscPatch).isValid() || + !TexMan.CheckForTexture("STCFN122", ETextureType::MiscPatch).isValid()) { + // insert the incorrectly named '|' graphic in its correct position. + position = 124; + } + } + if (lump.isValid()) + { if (position < minchar) minchar = position; if (position > maxchar) maxchar = position; charMap.Insert(position, TexMan.GetTexture(lump)); @@ -1189,7 +1189,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla { Chars[i].OriginalPic = pic; Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (pic->GetImage()), ""); - Chars[i].TranslatedPic->Scale = pic->Scale; + Chars[i].TranslatedPic->CopySize(pic); Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar); TexMan.AddTexture(Chars[i].TranslatedPic); } @@ -1209,18 +1209,18 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla if (SpaceWidth == 0) // An explicit override from the .inf file must always take precedence { - if (spacewidth != -1) - { - SpaceWidth = spacewidth; - } + if (spacewidth != -1) + { + SpaceWidth = spacewidth; + } else if ('N'-FirstChar >= 0 && 'N'-FirstChar < count && Chars['N' - FirstChar].TranslatedPic != nullptr) - { + { SpaceWidth = (Chars['N' - FirstChar].XMove + 1) / 2; - } - else - { - SpaceWidth = 4; - } + } + else + { + SpaceWidth = 4; + } } if (FontHeight == 0) FontHeight = fontheight; @@ -2381,7 +2381,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (!noTranslate) { Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), ""); - Chars[i].TranslatedPic->Scale = charlumps[i]->Scale; + Chars[i].TranslatedPic->CopySize(charlumps[i]); Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar); TexMan.AddTexture(Chars[i].TranslatedPic); } @@ -3059,29 +3059,29 @@ void V_InitFonts() { SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", "defsmallfont2", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } - } + } if (!(BigFont = V_GetFont("BigFont"))) { if (gameinfo.gametype & GAME_Raven) { BigFont = new FFont ("BigFont", "FONTB%02u", "defbigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1); } - } + } if (!(ConFont = V_GetFont("ConsoleFont", "CONFONT"))) - { + { ConFont = SmallFont; - } + } if (!(IntermissionFont = FFont::FindFont("IntermissionFont"))) - { + { if (gameinfo.gametype & GAME_DoomChex) - { + { IntermissionFont = FFont::FindFont("IntermissionFont_Doom"); - } + } if (IntermissionFont == nullptr) - { + { IntermissionFont = BigFont; + } } - } // This can only happen if gzdoom.pk3 is corrupted. ConFont should always be present. if (ConFont == nullptr) { @@ -3095,11 +3095,11 @@ void V_InitFonts() if (SmallFont2 == nullptr) { SmallFont2 = SmallFont; - } + } if (BigFont == nullptr) - { + { BigFont = SmallFont; - } + } } diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index c1056e673..12d5db1b5 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -425,6 +425,7 @@ IWad Compatibility = "Shorttex" MustContain = "MAP01" BannerColors = "a8 00 00", "a8 a8 a8" + Load = "nerve.wad" } diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index c0af8b13e..fbbd2e166 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1778,6 +1778,27 @@ CNTRLMNU_TOGGLERUN = "Toggle Run"; CNTRLMNU_STRAFE = "Strafe"; CNTRLMNU_SCOREBOARD = "Show Scoreboard"; CNTRLMNU_TOGGLESCOREBOARD = "Toggle Scoreboard"; +CNTRLMNU_ACTION = "Action"; +CNTRLMNU_ACTION_TITLE = "Customize Action Controls"; +CNTRLMNU_CHAT_TITLE = "Customize Chat Controls"; +CNTRLMNU_WEAPONS_TITLE = "Customize Weapon Controls"; +CNTRLMNU_INVENTORY_TITLE = "Customize Inventory Controls"; +CNTRLMNU_OTHER_TITLE = "Customize Other Controls"; +CNTRLMNU_POPUPS_TITLE = "Strife Popup Screens Controls"; +CNTRLMNU_PAUSE = "Pause"; +CNTRLMNU_DISPLAY_INC = "Increase Display Size"; +CNTRLMNU_DISPLAY_DEC = "Decrease Display Size"; +CNTRLMNU_OPEN_HELP = "Open Help"; +CNTRLMNU_OPEN_SAVE = "Open Save Menu"; +CNTRLMNU_OPEN_LOAD = "Open Load Menu"; +CNTRLMNU_OPEN_OPTIONS = "Open Options Menu"; +CNTRLMNU_OPEN_DISPLAY = "Open Display Menu"; +CNTRLMNU_QUICKSAVE = "Quicksave"; +CNTRLMNU_QUICKLOAD = "Quickload"; +CNTRLMNU_EXIT_TO_MAIN = "Exit to Main Menu"; +CNTRLMNU_TOGGLE_MESSAGES = "Toggle Messages"; +CNTRLMNU_MENU_QUIT = "Quit Game"; +CNTRLMNU_ADJUST_GAMMA = "Adjust Gamma"; CNTRLMNU_CHAT = "Chat"; CNTRLMNU_SAY = "Say"; CNTRLMNU_TEAMSAY = "Team say"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index d90160f92..f24b139fc 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -425,81 +425,192 @@ ListMenu "PlayerMenu" OptionMenu "CustomizeControls" protected { Title "$CNTRLMNU_TITLE" + + StaticText "" + Submenu "$CNTRLMNU_ACTION" , "ActionControlsMenu" + + StaticText "" + Submenu "$CNTRLMNU_CHAT" , "ChatControlsMenu" + + StaticText "" + Submenu "$CNTRLMNU_WEAPONS" , "WeaponsControlMenu" + + StaticText "" + Submenu "$CNTRLMNU_INVENTORY" , "InventoryControlsMenu" + + StaticText "" + Submenu "$CNTRLMNU_OTHER" , "OtherControlsMenu" + + StaticText "" + Submenu "$CNTRLMNU_POPUPS" , "StrifeControlsMenu" + + StaticText "" + Submenu "$MAPCNTRLMNU_CONTROLS" , "MapControlsMenu" +} + +OptionMenu "ActionControlsMenu" protected +{ + Title "$CNTRLMNU_ACTION_TITLE" ScrollTop 2 - StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" - StaticText "" - StaticText "$CNTRLMNU_CONTROLS", 1 - Control "$CNTRLMNU_ATTACK", "+attack" - Control "$CNTRLMNU_ALTATTACK", "+altattack" - Control "$CNTRLMNU_RELOAD", "+reload" - Control "$CNTRLMNU_ZOOM", "+zoom" - Control "$CNTRLMNU_USER1", "+user1" - Control "$CNTRLMNU_USER2", "+user2" - Control "$CNTRLMNU_USER3", "+user3" - Control "$CNTRLMNU_USER4", "+user4" - Control "$CNTRLMNU_USE", "+use" - Control "$CNTRLMNU_FORWARD", "+forward" - Control "$CNTRLMNU_BACK", "+back" - Control "$CNTRLMNU_MOVELEFT", "+moveleft" - Control "$CNTRLMNU_MOVERIGHT", "+moveright" - Control "$CNTRLMNU_TURNLEFT", "+left" - Control "$CNTRLMNU_TURNRIGHT", "+right" - Control "$CNTRLMNU_TURN180", "turn180" - Control "$CNTRLMNU_JUMP", "+jump" - Control "$CNTRLMNU_CROUCH", "+crouch" - Control "$CNTRLMNU_TOGGLECROUCH", "crouch" - Control "$CNTRLMNU_MOVEUP", "+moveup" - Control "$CNTRLMNU_MOVEDOWN", "+movedown" - Control "$CNTRLMNU_LAND", "land" - Control "$CNTRLMNU_MOUSELOOK", "+mlook" - Control "$CNTRLMNU_KEYBOARDLOOK", "+klook" - Control "$CNTRLMNU_LOOKUP", "+lookup" - Control "$CNTRLMNU_LOOKDOWN", "+lookdown" - Control "$CNTRLMNU_CENTERVIEW", "centerview" - Control "$CNTRLMNU_RUN", "+speed" - Control "$CNTRLMNU_TOGGLERUN", "toggle cl_run" - Control "$CNTRLMNU_STRAFE", "+strafe" - Control "$CNTRLMNU_SCOREBOARD", "+showscores" - Control "$CNTRLMNU_TOGGLESCOREBOARD", "togglescoreboard" - StaticText "" - StaticText "$CNTRLMNU_CHAT", 1 - Control "$CNTRLMNU_SAY", "messagemode" - Control "$CNTRLMNU_TEAMSAY", "messagemode2" - StaticText "" - StaticText "$CNTRLMNU_WEAPONS", 1 - Control "$CNTRLMNU_NEXTWEAPON", "weapnext" - Control "$CNTRLMNU_PREVIOUSWEAPON", "weapprev" - Control "$CNTRLMNU_SLOT1", "slot 1" - Control "$CNTRLMNU_SLOT2", "slot 2" - Control "$CNTRLMNU_SLOT3", "slot 3" - Control "$CNTRLMNU_SLOT4", "slot 4" - Control "$CNTRLMNU_SLOT5", "slot 5" - Control "$CNTRLMNU_SLOT6", "slot 6" - Control "$CNTRLMNU_SLOT7", "slot 7" - Control "$CNTRLMNU_SLOT8", "slot 8" - Control "$CNTRLMNU_SLOT9", "slot 9" - Control "$CNTRLMNU_SLOT0", "slot 0" - StaticText "" - StaticText "$CNTRLMNU_INVENTORY", 1 - Control "$CNTRLMNU_USEITEM", "invuse" - Control "$CNTRLMNU_USEALLITEMS", "invuseall" - Control "$CNTRLMNU_NEXTITEM", "invnext" - Control "$CNTRLMNU_PREVIOUSITEM", "invprev" - Control "$CNTRLMNU_DROPITEM", "invdrop" - Control "$CNTRLMNU_QUERYITEM", "invquery" - Control "$CNTRLMNU_DROPWEAPON", "weapdrop" - StaticText "" - StaticText "$CNTRLMNU_OTHER", 1 - Control "$CNTRLMNU_AUTOMAP", "togglemap" - Control "$CNTRLMNU_CHASECAM", "chase" - Control "$CNTRLMNU_COOPSPY", "spynext" - Control "$CNTRLMNU_SCREENSHOT", "screenshot" - Control "$CNTRLMNU_CONSOLE", "toggleconsole" - StaticText "" - StaticText "$CNTRLMNU_POPUPS", 1 - Control "$CNTRLMNU_MISSION", "showpop 1" - Control "$CNTRLMNU_KEYS", "showpop 2" - Control "$CNTRLMNU_STATS", "showpop 3" + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_ATTACK" , "+attack" + Control "$CNTRLMNU_ALTATTACK" , "+altattack" + Control "$CNTRLMNU_RELOAD" , "+reload" + Control "$CNTRLMNU_ZOOM" , "+zoom" + + StaticText "" + Control "$CNTRLMNU_USE" , "+use" + + StaticText "" + Control "$CNTRLMNU_FORWARD" , "+forward" + Control "$CNTRLMNU_BACK" , "+back" + Control "$CNTRLMNU_MOVELEFT" , "+moveleft" + Control "$CNTRLMNU_MOVERIGHT" , "+moveright" + + StaticText "" + Control "$CNTRLMNU_TURNLEFT" , "+left" + Control "$CNTRLMNU_TURNRIGHT" , "+right" + Control "$CNTRLMNU_TURN180" , "turn180" + + StaticText "" + Control "$CNTRLMNU_JUMP" , "+jump" + Control "$CNTRLMNU_CROUCH" , "+crouch" + Control "$CNTRLMNU_TOGGLECROUCH" , "crouch" + + StaticText "" + Control "$CNTRLMNU_MOVEUP" , "+moveup" + Control "$CNTRLMNU_MOVEDOWN" , "+movedown" + Control "$CNTRLMNU_LAND" , "land" + + StaticText "" + Control "$CNTRLMNU_MOUSELOOK" , "+mlook" + Control "$CNTRLMNU_KEYBOARDLOOK" , "+klook" + Control "$CNTRLMNU_LOOKUP" , "+lookup" + Control "$CNTRLMNU_LOOKDOWN" , "+lookdown" + Control "$CNTRLMNU_CENTERVIEW" , "centerview" + + StaticText "" + Control "$CNTRLMNU_RUN" , "+speed" + Control "$CNTRLMNU_TOGGLERUN" , "toggle cl_run" + Control "$CNTRLMNU_STRAFE" , "+strafe" + + StaticText "" + Control "$CNTRLMNU_SCOREBOARD" , "+showscores" + Control "$CNTRLMNU_TOGGLESCOREBOARD" , "togglescoreboard" + + StaticText "" + Control "$CNTRLMNU_USER1" , "+user1" + Control "$CNTRLMNU_USER2" , "+user2" + Control "$CNTRLMNU_USER3" , "+user3" + Control "$CNTRLMNU_USER4" , "+user4" +} + +OptionMenu "ChatControlsMenu" protected +{ + Title "$CNTRLMNU_CHAT_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_SAY" , "messagemode" + Control "$CNTRLMNU_TEAMSAY" , "messagemode2" +} + +OptionMenu "WeaponsControlMenu" protected +{ + Title "$CNTRLMNU_WEAPONS_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_NEXTWEAPON" , "weapnext" + Control "$CNTRLMNU_PREVIOUSWEAPON" , "weapprev" + + StaticText "" + Control "$CNTRLMNU_SLOT1" , "slot 1" + Control "$CNTRLMNU_SLOT2" , "slot 2" + Control "$CNTRLMNU_SLOT3" , "slot 3" + Control "$CNTRLMNU_SLOT4" , "slot 4" + Control "$CNTRLMNU_SLOT5" , "slot 5" + Control "$CNTRLMNU_SLOT6" , "slot 6" + Control "$CNTRLMNU_SLOT7" , "slot 7" + Control "$CNTRLMNU_SLOT8" , "slot 8" + Control "$CNTRLMNU_SLOT9" , "slot 9" + Control "$CNTRLMNU_SLOT0" , "slot 0" +} + +OptionMenu "InventoryControlsMenu" protected +{ + Title "$CNTRLMNU_INVENTORY_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_USEITEM" , "invuse" + Control "$CNTRLMNU_USEALLITEMS" , "invuseall" + + StaticText "" + Control "$CNTRLMNU_NEXTITEM" , "invnext" + Control "$CNTRLMNU_PREVIOUSITEM" , "invprev" + + StaticText "" + Control "$CNTRLMNU_DROPITEM" , "invdrop" + Control "$CNTRLMNU_QUERYITEM" , "invquery" + + StaticText "" + Control "$CNTRLMNU_DROPWEAPON" , "weapdrop" +} + +OptionMenu "OtherControlsMenu" protected +{ + Title "$CNTRLMNU_OTHER_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_AUTOMAP" , "togglemap" + + StaticText "" + Control "$CNTRLMNU_CHASECAM" , "chase" + Control "$CNTRLMNU_COOPSPY" , "spynext" + + StaticText "" + Control "$CNTRLMNU_SCREENSHOT" , "screenshot" + Control "$CNTRLMNU_CONSOLE" , "toggleconsole" + Control "$CNTRLMNU_PAUSE" , "pause" + + StaticText "" + Control "$CNTRLMNU_DISPLAY_INC" , "sizeup" + Control "$CNTRLMNU_DISPLAY_DEC" , "sizedown" + Control "$CNTRLMNU_TOGGLE_MESSAGES" , "togglemessages" + Control "$CNTRLMNU_ADJUST_GAMMA" , "bumpgamma" + + StaticText "" + Control "$CNTRLMNU_OPEN_HELP" , "menu_help" + Control "$CNTRLMNU_OPEN_SAVE" , "menu_save" + Control "$CNTRLMNU_OPEN_LOAD" , "menu_load" + Control "$CNTRLMNU_OPEN_OPTIONS" , "menu_options" + Control "$CNTRLMNU_OPEN_DISPLAY" , "menu_display" + Control "$CNTRLMNU_EXIT_TO_MAIN" , "menu_endgame" + Control "$CNTRLMNU_MENU_QUIT" , "menu_quit" + + StaticText "" + Control "$CNTRLMNU_QUICKSAVE" , "quicksave" + Control "$CNTRLMNU_QUICKLOAD" , "quickload" +} + +OptionMenu "StrifeControlsMenu" protected +{ + Title "$CNTRLMNU_POPUPS_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_MISSION" , "showpop 1" + Control "$CNTRLMNU_KEYS" , "showpop 2" + Control "$CNTRLMNU_STATS" , "showpop 3" } //-------------------------------------------------------------------------------------------