From c45c7cdb4bc89ca8a0b070e2de2f8a6ebf8e76a7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Apr 2019 14:02:53 +0200 Subject: [PATCH] - reimplemented as an OptionsMenu. This is both for consistency and better localizability. The old code is retained to ensure that mods inheriting from the old menu continue to work. --- src/d_netinfo.cpp | 6 - src/d_player.h | 3 +- src/menu/menu.cpp | 5 +- src/menu/menudef.cpp | 91 +++ src/menu/playermenu.cpp | 5 +- src/utility/namedef.h | 4 + wadsrc/static/menudef.txt | 54 +- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/ui/menu/menu.zs | 2 + .../static/zscript/ui/menu/newplayermenu.zs | 556 ++++++++++++++++++ wadsrc/static/zscript/ui/menu/optionmenu.zs | 9 +- .../static/zscript/ui/menu/playerdisplay.zs | 67 ++- wadsrc/static/zscript/ui/menu/playermenu.zs | 20 +- 13 files changed, 798 insertions(+), 25 deletions(-) create mode 100644 wadsrc/static/zscript/ui/menu/newplayermenu.zs diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 0aedc48b25..e631c4e994 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -489,12 +489,6 @@ int userinfo_t::PlayerClassChanged(const char *classname) return classnum; } -int userinfo_t::PlayerClassNumChanged(int classnum) -{ - *static_cast((*this)[NAME_PlayerClass]) = classnum; - return classnum; -} - int userinfo_t::ColorSetChanged(int setnum) { *static_cast((*this)[NAME_ColorSet]) = setnum; diff --git a/src/d_player.h b/src/d_player.h index d52e35979a..fc338b32f9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -264,8 +264,7 @@ struct userinfo_t : TMap int SkinNumChanged(int skinnum); int GenderChanged(const char *gendername); int PlayerClassChanged(const char *classname); - int PlayerClassNumChanged(int classnum); - uint32_t ColorChanged(const char *colorname); + uint32_t ColorChanged(const char *colorname); uint32_t ColorChanged(uint32_t colorval); int ColorSetChanged(int setnum); }; diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index d50b56b67e..4f179155f6 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -66,7 +66,6 @@ CVAR (Bool, show_obituaries, true, CVAR_ARCHIVE) CVAR (Int, m_showinputgrid, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, m_blockcontrollers, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) - CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) CVAR(Int, m_use_mouse, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -518,6 +517,10 @@ void M_SetMenu(FName menu, int param) void ActivateEndGameMenu(); ActivateEndGameMenu(); return; + + case NAME_Playermenu: + menu = NAME_NewPlayerMenu; // redirect the old player menu to the new one. + break; } // End of special checks diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 9932b9d1dc..5eca78b010 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -48,6 +48,8 @@ #include "i_system.h" #include "v_video.h" #include "gstrings.h" +#include "teaminfo.h" +#include "r_data/sprites.h" void ClearSaveGames(); @@ -1543,6 +1545,95 @@ void M_CreateMenus() { I_BuildALResamplersList(*opt); } + opt = OptionValues.CheckKey(NAME_PlayerTeam); + if (opt != nullptr) + { + auto op = *opt; + op->mValues.Resize(Teams.Size() + 1); + op->mValues[0].Value = 0; + op->mValues[0].Text = "$OPTVAL_NONE"; + for (unsigned i = 0; i < Teams.Size(); i++) + { + op->mValues[i+1].Value = i+1; + op->mValues[i+1].Text = Teams[i].GetName(); + } + } + opt = OptionValues.CheckKey(NAME_PlayerClass); + if (opt != nullptr) + { + auto op = *opt; + int o = 0; + if (!gameinfo.norandomplayerclass && PlayerClasses.Size() > 1) + { + op->mValues.Resize(PlayerClasses.Size()+1); + op->mValues[0].Value = -1; + op->mValues[0].Text = "$MNU_RANDOM"; + o = 1; + } + else op->mValues.Resize(PlayerClasses.Size()); + for (unsigned i = 0; i < PlayerClasses.Size(); i++) + { + op->mValues[i+o].Value = i; + op->mValues[i+o].Text = GetPrintableDisplayName(PlayerClasses[i].Type); + } + } +} + + +DEFINE_ACTION_FUNCTION(DMenu, UpdateColorsets) +{ + PARAM_PROLOGUE; + PARAM_POINTER(playerClass, FPlayerClass); + + TArray PlayerColorSets; + + EnumColorSets(playerClass->Type, &PlayerColorSets); + + auto opt = OptionValues.CheckKey(NAME_PlayerColors); + if (opt != nullptr) + { + auto op = *opt; + op->mValues.Resize(PlayerColorSets.Size() + 1); + op->mValues[0].Value = -1; + op->mValues[0].Text = "$OPTVAL_CUSTOM"; + for (unsigned i = 0; i < PlayerColorSets.Size(); i++) + { + auto cset = GetColorSet(playerClass->Type, PlayerColorSets[i]); + op->mValues[i + 1].Value = PlayerColorSets[i]; + op->mValues[i + 1].Text = cset? cset->Name.GetChars() : "?"; // The null case should never happen here. + } + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DMenu, UpdateSkinOptions) +{ + PARAM_PROLOGUE; + PARAM_POINTER(playerClass, FPlayerClass); + + auto opt = OptionValues.CheckKey(NAME_PlayerSkin); + if (opt != nullptr) + { + auto op = *opt; + + if ((GetDefaultByType(playerClass->Type)->flags4 & MF4_NOSKIN) || players[consoleplayer].userinfo.GetPlayerClassNum() == -1) + { + op->mValues.Resize(1); + op->mValues[0].Value = -1; + op->mValues[0].Text = "$OPTVAL_DEFAULT"; + } + else + { + op->mValues.Clear(); + for (unsigned i = 0; i < Skins.Size(); i++) + { + op->mValues.Reserve(1); + op->mValues.Last().Value = i; + op->mValues.Last().Text = Skins[i].Name; + } + } + } + return 0; } //============================================================================= diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index add7ed3635..84ed9fc1a3 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -133,8 +133,9 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) PARAM_POINTER(cls, FPlayerClass); if (DMenu::InMenu) { - players[consoleplayer].userinfo.PlayerClassNumChanged(gameinfo.norandomplayerclass ? sel : sel - 1); - cvar_set("playerclass", sel == 0 && !gameinfo.norandomplayerclass ? "Random" : GetPrintableDisplayName(cls->Type).GetChars()); + const char *pclass = sel == -1 ? "Random" : GetPrintableDisplayName(cls->Type).GetChars(); + players[consoleplayer].userinfo.PlayerClassChanged(pclass); + cvar_set("playerclass", pclass); } return 0; } diff --git a/src/utility/namedef.h b/src/utility/namedef.h index 4d54aadfc7..0191bd4178 100644 --- a/src/utility/namedef.h +++ b/src/utility/namedef.h @@ -1083,3 +1083,7 @@ xx(MapMarker) xx(Spawn2) xx(LevelLocals) xx(Level) +xx(PlayerTeam) +xx(PlayerColors) +xx(PlayerSkin) +xx(NewPlayerMenu) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 330f52783d..19347e9d1f 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -369,7 +369,7 @@ OptionMenu "OptionsMenu" protected Submenu "$OPTMNU_MOUSE", "MouseOptions" Submenu "$OPTMNU_JOYSTICK", "JoystickOptions" StaticText " " - Submenu "$OPTMNU_PLAYER", "PlayerMenu" + Submenu "$OPTMNU_PLAYER", "NewPlayerMenu" Submenu "$OPTMNU_GAMEPLAY", "GameplayOptions" Submenu "$OPTMNU_COMPATIBILITY", "CompatibilityOptions" Submenu "$OPTMNU_AUTOMAP", "AutomapOptions" @@ -401,6 +401,58 @@ OptionValue "Gender" 3, "$OPTVAL_OTHER" } +OptionValue "PlayerTeam" +{ + // Filled in programmatically +} + +OptionValue "PlayerColors" +{ + // Filled in programmatically +} + +OptionValue "PlayerClass" +{ + // Filled in programmatically +} + +OptionValue "PlayerSkin" +{ + // Filled in programmatically +} + +/* + IfGame(Doom, Heretic, Strife, Chex) + { + MouseWindow 0, 220 + PlayerDisplay 220, 48, "20 00 00", "80 00 40", 1, "PlayerDisplay" + } + IfGame(Hexen) + { + MouseWindow 0, 220 + PlayerDisplay 220, 48, "00 07 00", "40 53 40", 1, "PlayerDisplay" + } +*/ + +OptionMenu "NewPlayerMenu" +{ + Title "$MNU_PLAYERSETUP" + PlayerNameField "$PLYRMNU_NAME" + PlayerTeamItem "$PLYRMNU_TEAM", "PlayerTeam" + PlayerColorItem "$PLYRMNU_PLAYERCOLOR", "PlayerColors" + PlayerColorSlider "$PLYRMNU_RED", 0 + PlayerColorSlider "$PLYRMNU_GREEN", 1 + PlayerColorSlider "$PLYRMNU_BLUE", 2 + PlayerClassItem "$PLYRMNU_PLAYERCLASS", "PlayerClass" + PlayerSkinItem "$PLYRMNU_PLAYERSKIN", "PlayerSkin" + PlayerGenderItem "$PLYRMNU_PLAYERGENDER", "Gender" + AutoaimSlider "$PLYRMNU_AUTOAIM" + PlayerSwitchOnPickupItem "$PLYRMNU_SWITCHONPICKUP", "OffOn" + Option "$PLYRMNU_ALWAYSRUN", cl_run, "OnOff" + Class "NewPlayerMenu" +} + +// The old player menu is kept for mods that redefine it. ListMenu "PlayerMenu" { StaticTextCentered 160, 6, "$MNU_PLAYERSETUP" diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 510adc8f5e..ecfedb7c0c 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -246,6 +246,7 @@ version "3.8" #include "zscript/ui/menu/messagebox.zs" #include "zscript/ui/menu/optionmenu.zs" #include "zscript/ui/menu/optionmenuitems.zs" +#include "zscript/ui/menu/newplayermenu.zs" #include "zscript/ui/menu/playercontrols.zs" #include "zscript/ui/menu/playerdisplay.zs" #include "zscript/ui/menu/playermenu.zs" diff --git a/wadsrc/static/zscript/ui/menu/menu.zs b/wadsrc/static/zscript/ui/menu/menu.zs index 4c4db13746..da1fbe81be 100644 --- a/wadsrc/static/zscript/ui/menu/menu.zs +++ b/wadsrc/static/zscript/ui/menu/menu.zs @@ -98,6 +98,8 @@ class Menu : Object native ui version("2.4") native static void SetMouseCapture(bool on); native void Close(); native void ActivateMenu(); + native static void UpdateColorsets(PlayerClass cls); + native static void UpdateSkinOptions(PlayerClass cls); //============================================================================= // diff --git a/wadsrc/static/zscript/ui/menu/newplayermenu.zs b/wadsrc/static/zscript/ui/menu/newplayermenu.zs new file mode 100644 index 0000000000..ec6c65c734 --- /dev/null +++ b/wadsrc/static/zscript/ui/menu/newplayermenu.zs @@ -0,0 +1,556 @@ +/* +** playermenu.cpp +** The player setup menu +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010-2017 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerNameField : OptionMenuItemTextField +{ + OptionMenuItemTextField Init(String label) + { + Super.Init(label, "", null); + mEnter = null; + return self; + } + + override bool, String GetString (int i) + { + if (i == 0) + { + return true, players[consoleplayer].GetUserName(); +; + } + return false, ""; + } + + override bool SetString (int i, String s) + { + if (i == 0) + { + PlayerMenu.PlayerNameChanged(s); + return true; + } + return false; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerTeamItem : OptionMenuItemOptionBase +{ + OptionMenuItemPlayerTeamItem Init(String label, Name values) + { + Super.Init(label, 'none', values, null , false); + return self; + } + + //============================================================================= + override int GetSelection() + { + int Selection = -1; + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0) + { + int myteam = players[consoleplayer].GetTeam(); + let f = double(myteam == Team.NoTeam? 0 : myteam + 1); + for(int i = 0; i < cnt; i++) + { + if (f ~== OptionValues.GetValue(mValues, i)) + { + Selection = i; + break; + } + } + } + return Selection; + } + + override void SetSelection(int Selection) + { + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0) + { + PlayerMenu.TeamChanged(Selection); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerColorItem : OptionMenuItemOptionBase +{ + OptionMenuItemPlayerColorItem Init(String label, Name values) + { + Super.Init(label, 'none', values, null , false); + return self; + } + + //============================================================================= + override int GetSelection() + { + int Selection = -1; + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0) + { + int mycolorset = players[consoleplayer].GetColorSet(); + let f = double(mycolorset); + for(int i = 0; i < cnt; i++) + { + if (f ~== OptionValues.GetValue(mValues, i)) + { + Selection = i; + break; + } + } + } + return Selection; + } + + override void SetSelection(int Selection) + { + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0) + { + let val = int(OptionValues.GetValue(mValues, Selection)); + PlayerMenu.ColorSetChanged(val); + let menu = NewPlayerMenu(Menu.GetCurrentMenu()); + if (menu) menu.UpdateTranslation(); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerColorSlider : OptionMenuSliderBase +{ + int mChannel; + + OptionMenuItemPlayerColorSlider Init(String label, int channel) + { + Super.Init(label, 0, 255, 16, false, 'none'); + mChannel = channel; + return self; + } + + override double GetSliderValue() + { + Color colr = players[consoleplayer].GetColor(); + if (mChannel == 0) return colr.r; + else if (mChannel == 1) return colr.g; + else return colr.b; + } + + override void SetSliderValue(double val) + { + Color colr = players[consoleplayer].GetColor(); + int r = colr.r; + int g = colr.g; + int b = colr.b; + if (mChannel == 0) r = int(val); + else if (mChannel == 1) g = int(val); + else b = int(val); + PlayerMenu.ColorChanged(r, g, b); + let menu = NewPlayerMenu(Menu.GetCurrentMenu()); + if (menu) menu.UpdateTranslation(); + } + + override int Draw(OptionMenuDescriptor desc, int y, int indent, bool selected) + { + int mycolorset = players[consoleplayer].GetColorSet(); + if (mycolorset == -1) + { + return super.Draw(desc, y, indent, selected); + } + return indent; + } + + +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerClassItem : OptionMenuItemOptionBase +{ + OptionMenuItemPlayerClassItem Init(String label, Name values) + { + Super.Init(label, 'none', values, null , false); + return self; + } + + //============================================================================= + override int GetSelection() + { + int Selection = -1; + int cnt = OptionValues.GetCount(mValues); + if (cnt > 0) + { + double f = players[consoleplayer].GetPlayerClassNum(); + for(int i = 0; i < cnt; i++) + { + if (f ~== OptionValues.GetValue(mValues, i)) + { + Selection = i; + break; + } + } + } + return Selection; + } + + override void SetSelection(int Selection) + { + + int cnt = OptionValues.GetCount(mValues); + if (cnt > 1) + { + let val = int(OptionValues.GetValue(mValues, Selection)); + let menu = NewPlayerMenu(Menu.GetCurrentMenu()); + if (menu) + { + menu.PickPlayerClass(val); + PlayerMenu.ClassChanged(val, menu.mPlayerClass); + menu.mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_CLASS, players[consoleplayer].GetPlayerClassNum()); + menu.UpdateSkins(); + } + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerSkinItem : OptionMenuItemOptionBase +{ + OptionMenuItemPlayerSkinItem Init(String label, Name values) + { + Super.Init(label, 'none', values, null , false); + return self; + } + + //============================================================================= + override int GetSelection() + { + int Selection = 0; + int cnt = OptionValues.GetCount(mValues); + if (cnt > 1) + { + double f = players[consoleplayer].GetSkin(); + for(int i = 0; i < cnt; i++) + { + if (f ~== OptionValues.GetValue(mValues, i)) + { + Selection = i; + break; + } + } + } + return Selection; + } + + override void SetSelection(int Selection) + { + + int cnt = OptionValues.GetCount(mValues); + if (cnt > 1) + { + let val = int(OptionValues.GetValue(mValues, Selection)); + let menu = NewPlayerMenu(Menu.GetCurrentMenu()); + PlayerMenu.SkinChanged(val); + if (menu) + { + menu.mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_SKIN, val); + menu.UpdateTranslation(); + } + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerGenderItem : OptionMenuItemOptionBase +{ + OptionMenuItemPlayerGenderItem Init(String label, Name values) + { + Super.Init(label, 'none', values, null , false); + return self; + } + + //============================================================================= + override int GetSelection() + { + return players[consoleplayer].GetGender(); + } + + override void SetSelection(int Selection) + { + PlayerMenu.GenderChanged(Selection); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemAutoaimSlider : OptionMenuSliderBase +{ + OptionMenuItemAutoaimSlider Init(String label) + { + Super.Init(label, 0, 35, 1, false, 'none'); + return self; + } + + override double GetSliderValue() + { + return players[consoleplayer].GetAutoaim(); + } + + override void SetSliderValue(double val) + { + PlayerMenu.AutoaimChanged(val); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class OptionMenuItemPlayerSwitchOnPickupItem : OptionMenuItemOptionBase +{ + OptionMenuItemPlayerSwitchOnPickupItem Init(String label, Name values) + { + Super.Init(label, 'none', values, null , false); + return self; + } + + //============================================================================= + override int GetSelection() + { + return players[consoleplayer].GetNeverSwitch()? 1:0; + } + + override void SetSelection(int Selection) + { + PlayerMenu.SwitchOnPickupChanged(Selection); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +class NewPlayerMenu : OptionMenu +{ + PlayerClass mPlayerClass; + int mRotation; + PlayerMenuPlayerDisplay mPlayerDisplay; + + const PLAYERDISPLAY_X = 220; + const PLAYERDISPLAY_Y = 60; + const PLAYERDISPLAY_W = 144; + const PLAYERDISPLAY_H = 160; + const PLAYERDISPLAY_SPACE = 180; + + override void Init(Menu parent, OptionMenuDescriptor desc) + { + Super.Init(parent, desc); + let BaseColor = gameinfo.gametype == GAME_Hexen? 0x200000 : 0x000700; + let AddColor = gameinfo.gametype == GAME_Hexen? 0x800040 : 0x405340; + mPlayerDisplay = new("PlayerMenuPlayerDisplay"); + mPlayerDisplay.init(BaseColor, AddColor); + PickPlayerClass(); + + PlayerInfo p = players[consoleplayer]; + mRotation = 0; + + mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_ROTATION, 0); + mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_MODE, 1); + mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_TRANSLATE, 1); + mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_CLASS, p.GetPlayerClassNum()); + UpdateSkins(); + } + + override int GetIndent() + { + return Super.GetIndent() - 45*CleanXfac_1; + } + + + //============================================================================= + // + // + // + //============================================================================= + + void UpdateTranslation() + { + Translation.SetPlayerTranslation(TRANSLATION_Players, MAXPLAYERS, consoleplayer, mPlayerClass); + } + + //============================================================================= + // + // + // + //============================================================================= + + static int GetPlayerClassIndex(int pick = -100) + { + int pclass = 0; + // [GRB] Pick a class from player class list + if (PlayerClasses.Size () > 1) + { + pclass = pick == -100? players[consoleplayer].GetPlayerClassNum() : pick; + + if (pclass < 0) + { + pclass = (MenuTime() >> 7) % PlayerClasses.Size (); + } + } + return pclass; + } + + //============================================================================= + // + // + // + //============================================================================= + + void PickPlayerClass(int pick = -100) + { + let PlayerClassIndex = GetPlayerClassIndex(pick); + mPlayerClass = PlayerClasses[PlayerClassIndex]; + UpdateColorsets(mPlayerClass); + UpdateSkinOptions(mPlayerClass); + UpdateTranslation(); + } + + + //============================================================================= + // + // + // + //============================================================================= + + void UpdateSkins() + { + PlayerInfo p = players[consoleplayer]; + if (mPlayerClass != NULL && !(GetDefaultByType (mPlayerClass.Type).bNoSkin) && p.GetPlayerClassNum() != -1) + { + mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_SKIN, p.GetSkin()); + } + UpdateTranslation(); + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool OnUIEvent(UIEvent ev) + { + if (ev.Type == UIEvent.Type_Char && ev.KeyChar == 32) + { + // turn the player sprite around + mRotation = 8 - mRotation; + mPlayerDisplay.SetValue(ListMenuItemPlayerDisplay.PDF_ROTATION, mRotation); + return true; + } + return Super.OnUIEvent(ev); + } + + //============================================================================= + // + // + // + //============================================================================= + + override void Ticker() + { + mPlayerDisplay.Ticker(); + } + + //============================================================================= + // + // + // + //============================================================================= + + override void Drawer() + { + Super.Drawer(); + mPlayerDisplay.Drawer(false); + + int x = screen.GetWidth()/(CleanXfac_1*2) + PLAYERDISPLAY_X + PLAYERDISPLAY_W/2; + int y = PLAYERDISPLAY_Y + PLAYERDISPLAY_H + 5; + String str = Stringtable.Localize("$PLYRMNU_PRESSSPACE"); + screen.DrawText (NewSmallFont, Font.CR_GOLD, x - NewSmallFont.StringWidth(str)/2, y, str, DTA_VirtualWidth, CleanWidth_1, DTA_VirtualHeight, CleanHeight_1, DTA_KeepRatio, true); + str = Stringtable.Localize(mRotation ? "$PLYRMNU_SEEFRONT" : "$PLYRMNU_SEEBACK"); + y += NewSmallFont.GetHeight(); + screen.DrawText (NewSmallFont, Font.CR_GOLD,x - NewSmallFont.StringWidth(str)/2, y, str, DTA_VirtualWidth, CleanWidth_1, DTA_VirtualHeight, CleanHeight_1, DTA_KeepRatio, true); + + } +} diff --git a/wadsrc/static/zscript/ui/menu/optionmenu.zs b/wadsrc/static/zscript/ui/menu/optionmenu.zs index ea4a7f07ab..a6d8216c27 100644 --- a/wadsrc/static/zscript/ui/menu/optionmenu.zs +++ b/wadsrc/static/zscript/ui/menu/optionmenu.zs @@ -410,6 +410,12 @@ class OptionMenu : Menu // //============================================================================= + virtual int GetIndent() + { + int indent = max(0, (mDesc.mIndent + 40) - CleanWidth_1 / 2); + return screen.GetWidth() / 2 + indent * CleanXfac_1; + } + override void Drawer () { int y = mDesc.mPosition; @@ -433,8 +439,7 @@ class OptionMenu : Menu int fontheight = OptionMenuSettings.mLinespacing * CleanYfac_1; y *= CleanYfac_1; - int indent = max(0, (mDesc.mIndent + 40) - CleanWidth_1 / 2); - indent = screen.GetWidth() / 2 + indent * CleanXfac_1; + int indent = GetIndent(); int ytop = y + mDesc.mScrollTop * 8 * CleanYfac_1; int lastrow = screen.GetHeight() - OptionHeight() * CleanYfac_1; diff --git a/wadsrc/static/zscript/ui/menu/playerdisplay.zs b/wadsrc/static/zscript/ui/menu/playerdisplay.zs index f27ee3288d..63b6de4202 100644 --- a/wadsrc/static/zscript/ui/menu/playerdisplay.zs +++ b/wadsrc/static/zscript/ui/menu/playerdisplay.zs @@ -132,6 +132,7 @@ class ListMenuItemPlayerDisplay : ListMenuItem { if (classnum < 0 || classnum >= PlayerClasses.Size ()) { + Console.Printf("Setting random class for %d, size = %d", classnum, PlayerClasses.Size ()); if (mClassNum != -1) { mClassNum = -1; @@ -141,6 +142,7 @@ class ListMenuItemPlayerDisplay : ListMenuItem } else if (mPlayerClass != PlayerClasses[classnum] || force) { + Console.Printf("Setting class for %d", classnum); UpdatePlayer(classnum); mClassNum = classnum; } @@ -154,7 +156,7 @@ class ListMenuItemPlayerDisplay : ListMenuItem bool UpdatePlayerClass() { - if (mOwner.mSelectedItem >= 0) + if (mOwner && mOwner.mSelectedItem >= 0) { int classnum; Name seltype; @@ -289,4 +291,67 @@ class ListMenuItemPlayerDisplay : ListMenuItem } } } +} + +//============================================================================= +// +// +// +//============================================================================= + +class PlayerMenuPlayerDisplay : ListMenuItemPlayerDisplay +{ + void Init(Color c1, Color c2) + { + Super.Init(null, 0, 0, c1, c2, true, 'none'); + } + + override void Drawer(bool selected) + { + int x = screen.GetWidth()/2 + NewPlayerMenu.PLAYERDISPLAY_X * CleanXfac_1; + int y = NewPlayerMenu.PLAYERDISPLAY_Y * CleanYfac_1; + + int r = mBaseColor.r + mAddColor.r; + int g = mBaseColor.g + mAddColor.g; + int b = mBaseColor.b + mAddColor.b; + int m = max(r, g, b); + r = r * 255 / m; + g = g * 255 / m; + b = b * 255 / m; + Color c = Color(255, r, g, b); + + screen.DrawTexture(mBackdrop, false, x, y - 1, + DTA_DestWidth, NewPlayerMenu.PLAYERDISPLAY_W * CleanXfac_1, + DTA_DestHeight, NewPlayerMenu.PLAYERDISPLAY_H * CleanYfac_1, + DTA_Color, c, + DTA_KeepRatio, mNoPortrait, + DTA_Masked, true); + + Screen.DrawFrame (x, y, NewPlayerMenu.PLAYERDISPLAY_W*CleanXfac_1, NewPlayerMenu.PLAYERDISPLAY_H*CleanYfac_1-1); + + if (mPlayerState != NULL) + { + Vector2 Scale; + TextureID sprite; + bool flip; + + let playdef = GetDefaultByType((class)(mPlayerClass.Type)); + [sprite, flip, Scale] = mPlayerState.GetSpriteTexture(mRotation, mSkin, playdef.Scale); + + if (sprite.IsValid()) + { + int trans = mTranslate? Translation.MakeID(TRANSLATION_Players, MAXPLAYERS) : 0; + let tscale = TexMan.GetScaledSize(sprite); + Scale.X *= CleanXfac_1 * tscale.X * 2; + Scale.Y *= CleanYfac_1 * tscale.Y * 2; + + screen.DrawTexture (sprite, false, + x + (NewPlayerMenu.PLAYERDISPLAY_W/2) * CleanXfac_1, y + (NewPlayerMenu.PLAYERDISPLAY_H-16) * CleanYfac_1, + DTA_DestWidthF, Scale.X, DTA_DestHeightF, Scale.Y, + DTA_TranslationIndex, trans, + DTA_KeepRatio, mNoPortrait, + DTA_FlipX, flip); + } + } + } } \ No newline at end of file diff --git a/wadsrc/static/zscript/ui/menu/playermenu.zs b/wadsrc/static/zscript/ui/menu/playermenu.zs index 1aefb0ba0c..6404ac7133 100644 --- a/wadsrc/static/zscript/ui/menu/playermenu.zs +++ b/wadsrc/static/zscript/ui/menu/playermenu.zs @@ -42,16 +42,16 @@ class PlayerMenu : ListMenu Array mPlayerSkins; // All write function for the player config are native to prevent abuse. - protected static native void AutoaimChanged(float val); - protected static native void TeamChanged(int val); - protected static native void AlwaysRunChanged(int val); - protected static native void GenderChanged(int val); - protected static native void SwitchOnPickupChanged(int val); - protected static native void ColorChanged(int red, int green, int blue); - protected static native void ColorSetChanged(int red); - protected static native void PlayerNameChanged(String name); - protected static native void SkinChanged (int val); - protected static native void ClassChanged(int sel, PlayerClass cls); + static native void AutoaimChanged(float val); + static native void TeamChanged(int val); + static native void AlwaysRunChanged(int val); + static native void GenderChanged(int val); + static native void SwitchOnPickupChanged(int val); + static native void ColorChanged(int red, int green, int blue); + static native void ColorSetChanged(int red); + static native void PlayerNameChanged(String name); + static native void SkinChanged (int val); + static native void ClassChanged(int sel, PlayerClass cls); //============================================================================= //