From 74c474859324623fc1859125f8937e536c4b5d84 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 12:10:10 +0100 Subject: [PATCH 01/12] - fixed the message switch for the controls menu. --- wadsrc/static/zscript/menu/optionmenuitems.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/menu/optionmenuitems.txt b/wadsrc/static/zscript/menu/optionmenuitems.txt index 8efe0cfb9..4d61edcd0 100644 --- a/wadsrc/static/zscript/menu/optionmenuitems.txt +++ b/wadsrc/static/zscript/menu/optionmenuitems.txt @@ -388,7 +388,7 @@ class EnterKey : Menu let parent = OptionMenu(mParentMenu); if (parent != null) { - let it = parent.GetItem('Controlmessage'); + let it = parent.mDesc.GetItem('Controlmessage'); if (it != null) { it.SetValue(0, which); From 416911587ee5d77c73ccc44c7b20bdb615ac408b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 16:53:36 +0100 Subject: [PATCH 02/12] - scriptified PlayerMenu.Drawer --- src/menu/playermenu.cpp | 38 ++--------------------- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/menu/playermenu.txt | 25 +++++++++++++++ 3 files changed, 28 insertions(+), 36 deletions(-) create mode 100644 wadsrc/static/zscript/menu/playermenu.txt diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 3a1376052..ce657feae 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -65,6 +65,7 @@ class DPlayerMenu : public DListMenu { DECLARE_CLASS(DPlayerMenu, DListMenu) +public: int PlayerClassIndex; FPlayerClass *PlayerClass; TArray PlayerColorSets; @@ -91,8 +92,6 @@ public: bool Responder (event_t *ev); bool MenuEvent (int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); - void Ticker (); - void Drawer (); }; IMPLEMENT_CLASS(DPlayerMenu, false, false) @@ -693,38 +692,5 @@ bool DPlayerMenu::MouseEvent(int type, int x, int y) return res; } -//============================================================================= -// -// -// -//============================================================================= -void DPlayerMenu::Ticker () -{ - - Super::Ticker(); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DPlayerMenu::Drawer () -{ - - Super::Drawer(); - - const char *str = "PRESS " TEXTCOLOR_WHITE "SPACE"; - screen->DrawText (SmallFont, CR_GOLD, 320 - 32 - 32 - - SmallFont->StringWidth (str)/2, - 50 + 48 + 70, str, - DTA_Clean, true, TAG_DONE); - str = mRotation ? "TO SEE FRONT" : "TO SEE BACK"; - screen->DrawText (SmallFont, CR_GOLD, 320 - 32 - 32 - - SmallFont->StringWidth (str)/2, - 50 + 48 + 70 + SmallFont->GetHeight (), str, - DTA_Clean, true, TAG_DONE); - -} +DEFINE_FIELD(DPlayerMenu, mRotation) diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index d755c85b9..ae582e058 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -15,6 +15,7 @@ #include "zscript/menu/optionmenuitems.txt" #include "zscript/menu/colorpickermenu.txt" #include "zscript/menu/joystickmenu.txt" +#include "zscript/menu/playermenu.txt" #include "zscript/menu/playerdisplay.txt" #include "zscript/menu/playercontrols.txt" #include "zscript/menu/textentermenu.txt" diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt new file mode 100644 index 000000000..c8f537340 --- /dev/null +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -0,0 +1,25 @@ + + +class PlayerMenu : ListMenu native +{ + native int mRotation; + + //============================================================================= + // + // + // + //============================================================================= + + override void Drawer () + { + + Super.Drawer(); + + String str = "PRESS " .. TEXTCOLOR_WHITE .. "SPACE"; + screen.DrawText (SmallFont, Font.CR_GOLD, 320 - 32 - 32 - SmallFont.StringWidth (str)/2, 50 + 48 + 70, str, DTA_Clean, true); + str = mRotation ? "TO SEE FRONT" : "TO SEE BACK"; + screen.DrawText (SmallFont, Font.CR_GOLD, 320 - 32 - 32 - SmallFont.StringWidth (str)/2, 50 + 48 + 70 + SmallFont.GetHeight (), str, DTA_Clean, true); + + } + +} \ No newline at end of file From f4e9cd000999cb55f8fe474d32d350cb2e22e045 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 18:21:59 +0100 Subject: [PATCH 03/12] - scriptified DPlayerMenu::MouseEvent. --- src/menu/playermenu.cpp | 108 +++++++--------------- src/p_user.cpp | 14 +++ wadsrc/static/zscript/menu/playermenu.txt | 70 +++++++++++++- wadsrc/static/zscript/shared/player.txt | 3 + 4 files changed, 119 insertions(+), 76 deletions(-) diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index ce657feae..8049349d9 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -91,7 +91,6 @@ public: void Init(DMenu *parent, DListMenuDescriptor *desc); bool Responder (event_t *ev); bool MenuEvent (int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); }; IMPLEMENT_CLASS(DPlayerMenu, false, false) @@ -278,30 +277,18 @@ void DPlayerMenu::UpdateTranslation() void DPlayerMenu::PickPlayerClass() { + int pclass = 0; + // [GRB] Pick a class from player class list + if (PlayerClasses.Size () > 1) + { + pclass = players[consoleplayer].userinfo.GetPlayerClassNum(); - /* - // What's the point of this? Aren't we supposed to edit the - // userinfo? - if (players[consoleplayer].mo != NULL) - { - PlayerClassIndex = players[consoleplayer].CurrentPlayerClass; - } - else - */ - { - int pclass = 0; - // [GRB] Pick a class from player class list - if (PlayerClasses.Size () > 1) + if (pclass < 0) { - pclass = players[consoleplayer].userinfo.GetPlayerClassNum(); - - if (pclass < 0) - { - pclass = (MenuTime>>7) % PlayerClasses.Size (); - } + pclass = (MenuTime>>7) % PlayerClasses.Size (); } - PlayerClassIndex = pclass; } + PlayerClassIndex = pclass; PlayerClass = &PlayerClasses[PlayerClassIndex]; UpdateTranslation(); } @@ -314,14 +301,25 @@ void DPlayerMenu::PickPlayerClass() void DPlayerMenu::SendNewColor (int red, int green, int blue) { - char command[24]; - players[consoleplayer].userinfo.ColorChanged(MAKERGB(red,green,blue)); - mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue); - C_DoCommand (command); UpdateTranslation(); } +DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) +{ + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_INT(r); + PARAM_INT(g); + PARAM_INT(b); + // only allow if the menu is active to prevent abuse. + if (self == DMenu::CurrentMenu) + { + players[consoleplayer].userinfo.ColorChanged(MAKERGB(r, g, b)); + } + return 0; +} + + //============================================================================= // // @@ -456,10 +454,7 @@ void DPlayerMenu::ColorSetChanged (DMenuItemBase *li) if (green != NULL) green->Enable(mycolorset == -1); if (blue != NULL) blue->Enable(mycolorset == -1); - char command[24]; players[consoleplayer].userinfo.ColorSetChanged(mycolorset); - mysnprintf(command, countof(command), "colorset %d", mycolorset); - C_DoCommand(command); UpdateTranslation(); } } @@ -545,6 +540,17 @@ void DPlayerMenu::AutoaimChanged (DMenuItemBase *li) } } +DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) +{ + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_FLOAT(val); + // only allow if the menu is active to prevent abuse. + if (self == DMenu::CurrentMenu) + { + autoaim = float(val); + } + return 0; +} //============================================================================= // // @@ -648,49 +654,5 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller) return Super::MenuEvent(mkey, fromcontroller); } - -bool DPlayerMenu::MouseEvent(int type, int x, int y) -{ - int v; - DMenuItemBase *li = mFocusControl; - bool res = Super::MouseEvent(type, x, y); - if (li == NULL) li = mFocusControl; - if (li != NULL) - { - // Check if the colors have changed - FName current = li->GetAction(NULL); - switch(current) - { - case NAME_Red: - if (li->GetValue(0, &v)) - { - uint32 color = players[consoleplayer].userinfo.GetColor(); - SendNewColor (v, GPART(color), BPART(color)); - } - break; - - case NAME_Green: - if (li->GetValue(0, &v)) - { - uint32 color = players[consoleplayer].userinfo.GetColor(); - SendNewColor (RPART(color), v, BPART(color)); - } - break; - - case NAME_Blue: - if (li->GetValue(0, &v)) - { - uint32 color = players[consoleplayer].userinfo.GetColor(); - SendNewColor (RPART(color), GPART(color), v); - } - break; - case NAME_Autoaim: - AutoaimChanged(li); - break; - } - } - return res; -} - - DEFINE_FIELD(DPlayerMenu, mRotation) +DEFINE_FIELD_NAMED(DPlayerMenu, PlayerClass, mPlayerClass) diff --git a/src/p_user.cpp b/src/p_user.cpp index eea26cc4b..8fc334d70 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -163,6 +163,13 @@ FString GetPrintableDisplayName(PClassActor *cls) return cls->DisplayName; } +DEFINE_ACTION_FUNCTION(APlayerPawn, GetPrintableDisplayName) +{ + PARAM_PROLOGUE; + PARAM_CLASS(type, AActor); + ACTION_RETURN_STRING(type->DisplayName); +} + bool ValidatePlayerClass(PClassActor *ti, const char *name) { if (ti == NULL) @@ -654,6 +661,13 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetNeverSwitch) ACTION_RETURN_BOOL(self->userinfo.GetNeverSwitch()); } +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetColor) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_INT(self->userinfo.GetColor()); +} + + //=========================================================================== // // APlayerPawn diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index c8f537340..0226b5849 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -1,8 +1,74 @@ - class PlayerMenu : ListMenu native { native int mRotation; + native PlayerClass mPlayerClass; + + protected native void AutoaimChanged(float val); + protected native void ColorChanged(int red, int green, int blue); + + protected void UpdateTranslation() + { + Translation.SetPlayerTranslation(TRANSLATION_Players, MAXPLAYERS, consoleplayer, mPlayerClass); + } + + protected void SendNewColor (int red, int green, int blue) + { + ColorChanged(red, green, blue); + UpdateTranslation(); + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MouseEvent(int type, int x, int y) + { + let li = mFocusControl; + bool res = Super.MouseEvent(type, x, y); + if (li == NULL) li = mFocusControl; + if (li != NULL) + { + // Check if the colors have changed + Name ctrl = li.GetAction(); + bool resv; + int v; + [resv, v]= li.GetValue(0); + switch(ctrl) + { + case 'Red': + if (resv) + { + Color colr = players[consoleplayer].GetColor(); + SendNewColor (v, colr.g, colr.b); + } + break; + + case 'Green': + if (resv) + { + Color colr = players[consoleplayer].GetColor(); + SendNewColor (colr.r, v, colr.b); + } + break; + + case 'Blue': + if (resv) + { + Color colr = players[consoleplayer].GetColor(); + SendNewColor (colr.r, colr.g, v); + } + break; + case 'Autoaim': + AutoaimChanged(v); + break; + } + } + return res; + } + //============================================================================= // @@ -12,9 +78,7 @@ class PlayerMenu : ListMenu native override void Drawer () { - Super.Drawer(); - String str = "PRESS " .. TEXTCOLOR_WHITE .. "SPACE"; screen.DrawText (SmallFont, Font.CR_GOLD, 320 - 32 - 32 - SmallFont.StringWidth (str)/2, 50 + 48 + 70, str, DTA_Clean, true); str = mRotation ? "TO SEE FRONT" : "TO SEE BACK"; diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 9039b37b6..28ed4826b 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -136,6 +136,8 @@ class PlayerPawn : Actor native native int GetMaxHealth(); native bool ResetAirSupply (bool playgasp = false); native void CheckWeaponSwitch(class item); + native static String GetPrintableDisplayName(Class cls); + } class PlayerChunk : PlayerPawn @@ -308,6 +310,7 @@ userinfo_t userinfo; native void SetLogNumber (int text); native void SetLogText (String text); native String GetUserName(); + native Color GetColor(); native bool GetNeverSwitch(); native void DropWeapon(); native void BringUpWeapon(); From 51493cde8cc8aca702df2dd7d797d7646a73f27d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 20:02:26 +0100 Subject: [PATCH 04/12] - scriptified DPlayerMenu::MenuEvent. --- src/menu/playermenu.cpp | 241 ++++++++++------------ wadsrc/static/zscript/menu/playermenu.txt | 147 +++++++++++++ 2 files changed, 254 insertions(+), 134 deletions(-) diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 8049349d9..21498ec2c 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -81,7 +81,6 @@ public: void PlayerNameChanged(DMenuItemBase *li); void ColorSetChanged (DMenuItemBase *li); void ClassChanged (DMenuItemBase *li); - void AutoaimChanged (DMenuItemBase *li); void SkinChanged (DMenuItemBase *li); @@ -90,7 +89,6 @@ public: DPlayerMenu() {} void Init(DMenu *parent, DListMenuDescriptor *desc); bool Responder (event_t *ev); - bool MenuEvent (int mkey, bool fromcontroller); }; IMPLEMENT_CLASS(DPlayerMenu, false, false) @@ -403,20 +401,22 @@ void DPlayerMenu::UpdateSkins() //============================================================================= // -// +// access to the player config is done natively, so that broader access +// functions do not need to be exported. // //============================================================================= -void DPlayerMenu::PlayerNameChanged(DMenuItemBase *li) +DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) { - char pp[MAXPLAYERNAME+1]; - const char *p; - if (li->GetString(0, pp, MAXPLAYERNAME)) - { - FString command("name \""); + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_STRING(s); + const char *pp = s; + FString command("name \""); + if (self == DMenu::CurrentMenu) + { // Escape any backslashes or quotation marks before sending the name to the console. - for (p = pp; *p != '\0'; ++p) + for (auto p = pp; *p != '\0'; ++p) { if (*p == '"' || *p == '\\') { @@ -425,8 +425,9 @@ void DPlayerMenu::PlayerNameChanged(DMenuItemBase *li) command << *p; } command << '"'; - C_DoCommand (command); + C_DoCommand(command); } + return 0; } //============================================================================= @@ -435,28 +436,15 @@ void DPlayerMenu::PlayerNameChanged(DMenuItemBase *li) // //============================================================================= -void DPlayerMenu::ColorSetChanged (DMenuItemBase *li) +DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) { - int sel; - - if (li->GetValue(0, &sel)) + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_INT(sel); + if (self == DMenu::CurrentMenu) { - int mycolorset = -1; - - if (sel > 0) mycolorset = PlayerColorSets[sel-1]; - - DMenuItemBase *red = GetItem(NAME_Red); - DMenuItemBase *green = GetItem(NAME_Green); - DMenuItemBase *blue = GetItem(NAME_Blue); - - // disable the sliders if a valid colorset is selected - if (red != NULL) red->Enable(mycolorset == -1); - if (green != NULL) green->Enable(mycolorset == -1); - if (blue != NULL) blue->Enable(mycolorset == -1); - - players[consoleplayer].userinfo.ColorSetChanged(mycolorset); - UpdateTranslation(); + players[consoleplayer].userinfo.ColorSetChanged(sel); } + return 0; } //============================================================================= @@ -493,6 +481,18 @@ void DPlayerMenu::ClassChanged (DMenuItemBase *li) } } +DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) +{ + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_OBJECT(sel, DMenuItemBase); + if (self == DMenu::CurrentMenu) + { + self->ClassChanged(sel); + } + return 0; +} + + //============================================================================= // // @@ -514,7 +514,6 @@ void DPlayerMenu::SkinChanged (DMenuItemBase *li) sel = PlayerSkins[sel]; players[consoleplayer].userinfo.SkinNumChanged(sel); UpdateTranslation(); - cvar_set ("skin", skins[sel].name); li = GetItem(NAME_Playerdisplay); if (li != NULL) @@ -524,22 +523,24 @@ void DPlayerMenu::SkinChanged (DMenuItemBase *li) } } -//============================================================================= -// -// -// -//============================================================================= - -void DPlayerMenu::AutoaimChanged (DMenuItemBase *li) +DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) { - int sel; - - if (li->GetValue(0, &sel)) + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_OBJECT(sel, DMenuItemBase); + if (self == DMenu::CurrentMenu) { - autoaim = (float)sel; + self->SkinChanged(sel); } + return 0; } + +//============================================================================= +// +// +// +//============================================================================= + DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) { PARAM_SELF_PROLOGUE(DPlayerMenu); @@ -551,108 +552,80 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) } return 0; } + //============================================================================= // // // //============================================================================= -bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller) +DEFINE_ACTION_FUNCTION(DPlayerMenu, TeamChanged) { - int v; - if (mDesc->mSelectedItem >= 0) + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_INT(val); + // only allow if the menu is active to prevent abuse. + if (self == DMenu::CurrentMenu) { - DMenuItemBase *li = mDesc->mItems[mDesc->mSelectedItem]; - if (li->MenuEvent(mkey, fromcontroller)) - { - FName current = li->GetAction(NULL); - switch(current) - { - // item specific handling comes here - - case NAME_Playerbox: - if (mkey == MKEY_Input) - { - PlayerNameChanged(li); - } - break; - - case NAME_Team: - if (li->GetValue(0, &v)) - { - team = v==0? TEAM_NONE : v-1; - } - break; - - case NAME_Color: - ColorSetChanged(li); - break; - - case NAME_Red: - if (li->GetValue(0, &v)) - { - uint32 color = players[consoleplayer].userinfo.GetColor(); - SendNewColor (v, GPART(color), BPART(color)); - } - break; - - case NAME_Green: - if (li->GetValue(0, &v)) - { - uint32 color = players[consoleplayer].userinfo.GetColor(); - SendNewColor (RPART(color), v, BPART(color)); - } - break; - - case NAME_Blue: - if (li->GetValue(0, &v)) - { - uint32 color = players[consoleplayer].userinfo.GetColor(); - SendNewColor (RPART(color), GPART(color), v); - } - break; - - case NAME_Class: - ClassChanged(li); - break; - - case NAME_Skin: - SkinChanged(li); - break; - - case NAME_Gender: - if (li->GetValue(0, &v)) - { - cvar_set ("gender", v==0? "male" : v==1? "female" : "other"); - } - break; - - case NAME_Autoaim: - AutoaimChanged(li); - break; - - case NAME_Switch: - if (li->GetValue(0, &v)) - { - neverswitchonpickup = !!v; - } - break; - - case NAME_AlwaysRun: - if (li->GetValue(0, &v)) - { - cl_run = !!v; - } - break; - - default: - break; - } - return true; - } + team = val == 0 ? TEAM_NONE : val - 1; } - return Super::MenuEvent(mkey, fromcontroller); + return 0; } +//============================================================================= +// +// +// +//============================================================================= + +DEFINE_ACTION_FUNCTION(DPlayerMenu, GenderChanged) +{ + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_INT(v); + // only allow if the menu is active to prevent abuse. + if (self == DMenu::CurrentMenu) + { + cvar_set("gender", v == 0 ? "male" : v == 1 ? "female" : "other"); + } + return 0; +} + +//============================================================================= +// +// +// +//============================================================================= + +DEFINE_ACTION_FUNCTION(DPlayerMenu, SwitchOnPickupChanged) +{ + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_INT(v); + // only allow if the menu is active to prevent abuse. + if (self == DMenu::CurrentMenu) + { + neverswitchonpickup = !!v; + } + return 0; +} + +//============================================================================= +// +// +// +//============================================================================= + +DEFINE_ACTION_FUNCTION(DPlayerMenu, AlwaysRunChanged) +{ + PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_INT(v); + // only allow if the menu is active to prevent abuse. + if (self == DMenu::CurrentMenu) + { + cl_run = !!v; + } + return 0; +} + + DEFINE_FIELD(DPlayerMenu, mRotation) DEFINE_FIELD_NAMED(DPlayerMenu, PlayerClass, mPlayerClass) +DEFINE_FIELD(DPlayerMenu, PlayerColorSets) diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index 0226b5849..3b0848080 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -3,9 +3,20 @@ class PlayerMenu : ListMenu native { native int mRotation; native PlayerClass mPlayerClass; + native Array PlayerColorSets; + // All write function for the player config are native to prevent abuse. protected native void AutoaimChanged(float val); + protected native void TeamChanged(int val); + protected native void AlwaysRunChanged(int val); + protected native void GenderChanged(int val); + protected native void SwitchOnPickupChanged(int val); protected native void ColorChanged(int red, int green, int blue); + protected native void ColorSetChanged(int red); + protected native void PlayerNameChanged(String name); + + protected native void ClassChanged(ListMenuItem it); + protected native void SkinChanged (ListMenuItem li); protected void UpdateTranslation() { @@ -24,6 +35,142 @@ class PlayerMenu : ListMenu native // //============================================================================= + override bool MenuEvent (int mkey, bool fromcontroller) + { + int v; + bool res; + String s; + if (mDesc.mSelectedItem >= 0) + { + let li = mDesc.mItems[mDesc.mSelectedItem]; + if (li.MenuEvent(mkey, fromcontroller)) + { + Name ctrl = li.GetAction(); + switch(ctrl) + { + // item specific handling comes here + + case 'Playerbox': + if (mkey == MKEY_Input) + { + [res, s] = li.GetString(0); + if (res) PlayerNameChanged(s); + } + break; + + case 'Team': + [res, v] = li.GetValue(0); + if (res) TeamChanged(v); + break; + + case 'Color': + [res, v] = li.GetValue(0); + if (res) + { + int mycolorset = -1; + + if (v > 0) mycolorset = PlayerColorSets[v - 1]; + + let red = GetItem('Red'); + let green = GetItem('Green'); + let blue = GetItem('Blue'); + + // disable the sliders if a valid colorset is selected + if (red != NULL) red.Enable(mycolorset == -1); + if (green != NULL) green.Enable(mycolorset == -1); + if (blue != NULL) blue.Enable(mycolorset == -1); + + ColorSetChanged(v - 1); + UpdateTranslation(); + } + break; + + case 'Red': + [res, v] = li.GetValue(0); + if (res) + { + Color colr = players[consoleplayer].GetColor(); + SendNewColor (v, colr.g, colr.b); + } + break; + + case 'Green': + [res, v] = li.GetValue(0); + if (res) + { + Color colr = players[consoleplayer].GetColor(); + SendNewColor (colr.r, v, colr.b); + } + break; + + case 'Blue': + [res, v] = li.GetValue(0); + if (res) + { + Color colr = players[consoleplayer].GetColor(); + SendNewColor (colr.r, colr.g, v); + } + break; + + case 'Class': + [res, v] = li.GetValue(0); + if (res) + { + ClassChanged(li); + } + break; + + case 'Skin': + SkinChanged(li); + break; + + case 'Gender': + [res, v] = li.GetValue(0); + if (res) + { + GenderChanged(v); + } + break; + + case 'Autoaim': + [res, v] = li.GetValue(0); + if (res) + { + AutoaimChanged(v); + } + break; + + case 'Switch': + [res, v] = li.GetValue(0); + if (res) + { + SwitchOnPickupChanged(v); + } + break; + + case 'AlwaysRun': + [res, v] = li.GetValue(0); + if (res) + { + AlwaysRunChanged(v); + } + break; + + default: + break; + } + return true; + } + } + return Super.MenuEvent(mkey, fromcontroller); + } + + //============================================================================= + // + // + // + //============================================================================= + override bool MouseEvent(int type, int x, int y) { let li = mFocusControl; From b375657509f9f7f6a2d50fc3cc2aa126507e69e1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 20:49:04 +0100 Subject: [PATCH 05/12] - scriptified DPlayerMenu::SkinChanged. --- src/menu/playermenu.cpp | 30 ++---------------- src/p_user.cpp | 6 ++++ wadsrc/static/zscript/menu/playermenu.txt | 38 +++++++++++++++++++++-- wadsrc/static/zscript/shared/player.txt | 1 + 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 21498ec2c..03e84ecbf 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -499,42 +499,17 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) // //============================================================================= -void DPlayerMenu::SkinChanged (DMenuItemBase *li) -{ - if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || - players[consoleplayer].userinfo.GetPlayerClassNum() == -1) - { - return; - } - - int sel; - - if (li->GetValue(0, &sel)) - { - sel = PlayerSkins[sel]; - players[consoleplayer].userinfo.SkinNumChanged(sel); - UpdateTranslation(); - - li = GetItem(NAME_Playerdisplay); - if (li != NULL) - { - li->SetValue(ListMenuItemPlayerDisplay_PDF_SKIN, sel); - } - } -} - DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) { PARAM_SELF_PROLOGUE(DPlayerMenu); - PARAM_OBJECT(sel, DMenuItemBase); + PARAM_INT(sel); if (self == DMenu::CurrentMenu) { - self->SkinChanged(sel); + players[consoleplayer].userinfo.SkinNumChanged(sel); } return 0; } - //============================================================================= // // @@ -629,3 +604,4 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AlwaysRunChanged) DEFINE_FIELD(DPlayerMenu, mRotation) DEFINE_FIELD_NAMED(DPlayerMenu, PlayerClass, mPlayerClass) DEFINE_FIELD(DPlayerMenu, PlayerColorSets) +DEFINE_FIELD(DPlayerMenu, PlayerSkins) diff --git a/src/p_user.cpp b/src/p_user.cpp index 8fc334d70..5816a9689 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -667,6 +667,12 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetColor) ACTION_RETURN_INT(self->userinfo.GetColor()); } +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetPlayerClassNum) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_INT(self->userinfo.GetPlayerClassNum()); +} + //=========================================================================== // diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index 3b0848080..4463bcea2 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -4,6 +4,7 @@ class PlayerMenu : ListMenu native native int mRotation; native PlayerClass mPlayerClass; native Array PlayerColorSets; + native Array PlayerSkins; // All write function for the player config are native to prevent abuse. protected native void AutoaimChanged(float val); @@ -14,9 +15,9 @@ class PlayerMenu : ListMenu native protected native void ColorChanged(int red, int green, int blue); protected native void ColorSetChanged(int red); protected native void PlayerNameChanged(String name); + protected native void SkinChanged (int val); protected native void ClassChanged(ListMenuItem it); - protected native void SkinChanged (ListMenuItem li); protected void UpdateTranslation() { @@ -29,6 +30,39 @@ class PlayerMenu : ListMenu native UpdateTranslation(); } + + //============================================================================= + // + // + // + //============================================================================= + + protected void ChangeSkin (MenuItemBase li) + { + if (GetDefaultByType (mPlayerClass.Type).bNoSkin || players[consoleplayer].GetPlayerClassNum() == -1) + { + return; + } + + bool res; + int sel; + + [res, sel] = li.GetValue(0); + if (res) + { + sel = PlayerSkins[sel]; + SkinChanged(sel); + UpdateTranslation(); + + li = GetItem('Playerdisplay'); + if (li != NULL) + { + li.SetValue(ListMenuItemPlayerDisplay.PDF_SKIN, sel); + } + } + } + + //============================================================================= // // @@ -121,7 +155,7 @@ class PlayerMenu : ListMenu native break; case 'Skin': - SkinChanged(li); + ChangeSkin(li); break; case 'Gender': diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 28ed4826b..24bfa51c6 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -311,6 +311,7 @@ userinfo_t userinfo; native void SetLogText (String text); native String GetUserName(); native Color GetColor(); + native int GetPlayerClassNum(); native bool GetNeverSwitch(); native void DropWeapon(); native void BringUpWeapon(); From 6a2525b737fb4ea4d0a1d0e36eb93ce65a04d65a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 20:58:11 +0100 Subject: [PATCH 06/12] - scriptified PickPlayerClass. --- src/menu/playermenu.cpp | 8 +------ wadsrc/static/zscript/menu/playermenu.txt | 26 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 03e84ecbf..daa18d57b 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -76,7 +76,6 @@ public: void UpdateColorsets(); void UpdateSkins(); void UpdateTranslation(); - void SendNewColor (int red, int green, int blue); void PlayerNameChanged(DMenuItemBase *li); void ColorSetChanged (DMenuItemBase *li); @@ -297,12 +296,6 @@ void DPlayerMenu::PickPlayerClass() // //============================================================================= -void DPlayerMenu::SendNewColor (int red, int green, int blue) -{ - players[consoleplayer].userinfo.ColorChanged(MAKERGB(red,green,blue)); - UpdateTranslation(); -} - DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) { PARAM_SELF_PROLOGUE(DPlayerMenu); @@ -605,3 +598,4 @@ DEFINE_FIELD(DPlayerMenu, mRotation) DEFINE_FIELD_NAMED(DPlayerMenu, PlayerClass, mPlayerClass) DEFINE_FIELD(DPlayerMenu, PlayerColorSets) DEFINE_FIELD(DPlayerMenu, PlayerSkins) +DEFINE_FIELD(DPlayerMenu, PlayerClassIndex) diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index 4463bcea2..0ac5328a0 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -2,6 +2,7 @@ class PlayerMenu : ListMenu native { native int mRotation; + native int PlayerClassIndex; native PlayerClass mPlayerClass; native Array PlayerColorSets; native Array PlayerSkins; @@ -30,7 +31,30 @@ class PlayerMenu : ListMenu native UpdateTranslation(); } - + //============================================================================= + // + // + // + //============================================================================= + + protected void PickPlayerClass() + { + int pclass = 0; + // [GRB] Pick a class from player class list + if (PlayerClasses.Size () > 1) + { + pclass = players[consoleplayer].GetPlayerClassNum(); + + if (pclass < 0) + { + pclass = (MenuTime() >> 7) % PlayerClasses.Size (); + } + } + PlayerClassIndex = pclass; + mPlayerClass = PlayerClasses[PlayerClassIndex]; + UpdateTranslation(); + } + //============================================================================= // // From 498da825a514ea2ba2b9916d8305ba874ad46ce2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 21:51:23 +0100 Subject: [PATCH 07/12] - made the Skins array scripting friendly and exported it. --- src/d_netinfo.cpp | 8 +- src/g_game.cpp | 2 +- src/g_shared/a_morph.cpp | 2 +- src/g_statusbar/sbar_mugshot.cpp | 2 +- src/intermission/intermission.cpp | 4 +- src/menu/playermenu.cpp | 8 +- src/p_actionfunctions.cpp | 2 +- src/p_mobj.cpp | 10 +- src/p_saveg.cpp | 2 +- src/p_setup.cpp | 1 - src/p_states.cpp | 6 +- src/p_user.cpp | 14 +-- src/r_data/r_translate.cpp | 6 +- src/r_data/sprites.cpp | 140 ++++++++++++------------ src/r_data/sprites.h | 24 ++-- src/scripting/thingdef_data.cpp | 9 ++ wadsrc/static/zscript/shared/player.txt | 14 +++ 17 files changed, 136 insertions(+), 118 deletions(-) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 62beb5460..8a856b44b 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -729,7 +729,7 @@ void D_WriteUserInfoStrings (int pnum, BYTE **stream, bool compact) break; case NAME_Skin: - *stream += sprintf(*((char **)stream), "\\%s", D_EscapeUserInfo(skins[info->GetSkin()].name).GetChars()); + *stream += sprintf(*((char **)stream), "\\%s", D_EscapeUserInfo(Skins[info->GetSkin()].Name).GetChars()); break; default: @@ -828,7 +828,7 @@ void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update) players[pnum].mo->state->sprite == GetDefaultByType (players[pnum].cls)->SpawnState->sprite) { // Only change the sprite if the player is using a standard one - players[pnum].mo->sprite = skins[info->GetSkin()].sprite; + players[pnum].mo->sprite = Skins[info->GetSkin()].sprite; } } // Rebuild translation in case the new skin uses a different range @@ -898,7 +898,7 @@ void WriteUserInfo(FSerializer &arc, userinfo_t &info) switch (pair->Key.GetIndex()) { case NAME_Skin: - string = skins[info.GetSkin()].name; + string = Skins[info.GetSkin()].Name; break; case NAME_PlayerClass: @@ -986,7 +986,7 @@ CCMD (playerinfo) // Print special info Printf("%20s: %s\n", "Name", ui->GetName()); Printf("%20s: %s (%d)\n", "Team", ui->GetTeam() == TEAM_NONE ? "None" : Teams[ui->GetTeam()].GetName(), ui->GetTeam()); - Printf("%20s: %s (%d)\n", "Skin", skins[ui->GetSkin()].name, ui->GetSkin()); + Printf("%20s: %s (%d)\n", "Skin", Skins[ui->GetSkin()].Name.GetChars(), ui->GetSkin()); Printf("%20s: %s (%d)\n", "Gender", GenderNames[ui->GetGender()], ui->GetGender()); Printf("%20s: %s (%d)\n", "PlayerClass", ui->GetPlayerClassNum() == -1 ? "Random" : ui->GetPlayerClassType()->DisplayName.GetChars(), diff --git a/src/g_game.cpp b/src/g_game.cpp index 627d51f04..dcd36b041 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1695,7 +1695,7 @@ static void G_QueueBody (AActor *body) { // Apply skin's scale to actor's scale, it will be lost otherwise const AActor *const defaultActor = body->GetDefault(); - const FPlayerSkin &skin = skins[skinidx]; + const FPlayerSkin &skin = Skins[skinidx]; body->Scale.X *= skin.Scale.X / defaultActor->Scale.X; body->Scale.Y *= skin.Scale.Y / defaultActor->Scale.Y; diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 359e8a174..1ae3c4b5e 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -298,7 +298,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, // If a custom skin was in use, then reload it // or else the base skin for the player class. if ((unsigned int)player->userinfo.GetSkin() >= PlayerClasses.Size () && - (size_t)player->userinfo.GetSkin() < numskins) + (unsigned)player->userinfo.GetSkin() < Skins.Size()) { skinindex = player->userinfo.GetSkin(); diff --git a/src/g_statusbar/sbar_mugshot.cpp b/src/g_statusbar/sbar_mugshot.cpp index d24298b94..18e0fec42 100644 --- a/src/g_statusbar/sbar_mugshot.cpp +++ b/src/g_statusbar/sbar_mugshot.cpp @@ -489,7 +489,7 @@ FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accu if (CurrentState != NULL) { int skin = player->userinfo.GetSkin(); - const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? ((APlayerPawn*)GetDefaultByType(player->MorphedPlayerClass))->Face.GetChars() : skins[skin].face); + const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? ((APlayerPawn*)GetDefaultByType(player->MorphedPlayerClass))->Face.GetChars() : Skins[skin].Face.GetChars()); return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle); } return NULL; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 8310914be..27532e7e9 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -593,7 +593,7 @@ void DIntermissionScreenCast::Drawer () if (!(mDefaults->flags4 & MF4_NOSKIN) && mDefaults->SpawnState != NULL && caststate->sprite == mDefaults->SpawnState->sprite && mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)) && - skins != NULL) + Skins.Size() > 0) { // Only use the skin sprite if this class has not been removed from the // PlayerClasses list. @@ -601,7 +601,7 @@ void DIntermissionScreenCast::Drawer () { if (PlayerClasses[i].Type == mClass) { - FPlayerSkin *skin = &skins[players[consoleplayer].userinfo.GetSkin()]; + FPlayerSkin *skin = &Skins[players[consoleplayer].userinfo.GetSkin()]; castsprite = skin->sprite; if (!(mDefaults->flags4 & MF4_NOSKIN)) diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index daa18d57b..ec2d76a5c 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -260,9 +260,9 @@ void DPlayerMenu::UpdateTranslation() if (PlayerClass != NULL) { - PlayerSkin = R_FindSkin (skins[PlayerSkin].name, int(PlayerClass - &PlayerClasses[0])); + PlayerSkin = R_FindSkin (Skins[PlayerSkin].Name, int(PlayerClass - &PlayerClasses[0])); R_GetPlayerTranslation(PlayerColor, GetColorSet(PlayerClass->Type, PlayerColorset), - &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); + &Skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); } } @@ -368,12 +368,12 @@ void DPlayerMenu::UpdateSkins() else { PlayerSkins.Clear(); - for(int i=0;i<(int)numskins; i++) + for (unsigned i = 0; i < Skins.Size(); i++) { if (PlayerClass->CheckSkin(i)) { int j = PlayerSkins.Push(i); - li->SetString(j, skins[i].name); + li->SetString(j, Skins[i].Name); if (players[consoleplayer].userinfo.GetSkin() == i) { sel = j; diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 15e82a56c..8a062cd18 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -3919,7 +3919,7 @@ DEFINE_ACTION_FUNCTION(AActor, PlayerSkinCheck) PARAM_SELF_PROLOGUE(AActor); ACTION_RETURN_BOOL(self->player != NULL && - skins[self->player->userinfo.GetSkin()].othergame); + Skins[self->player->userinfo.GetSkin()].othergame); } // [KS] *** Start of my modifications *** diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 5bf611800..2508f50f2 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -522,7 +522,7 @@ void AActor::PostSerialize() !(flags4 & MF4_NOSKIN) && state->sprite == GetDefaultByType(player->cls)->SpawnState->sprite) { // Give player back the skin - sprite = skins[player->userinfo.GetSkin()].sprite; + sprite = Skins[player->userinfo.GetSkin()].sprite; } if (Speed == 0) { @@ -666,9 +666,9 @@ bool AActor::SetState (FState *newstate, bool nofunction) // for Dehacked, I would move sprite changing out of the states // altogether, since actors rarely change their sprites after // spawning. - if (player != NULL && skins != NULL) + if (player != NULL && Skins.Size() > 0) { - sprite = skins[player->userinfo.GetSkin()].sprite; + sprite = Skins[player->userinfo.GetSkin()].sprite; } else if (newsprite != prevsprite) { @@ -5398,7 +5398,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) } // [GRB] Reset skin - p->userinfo.SkinNumChanged(R_FindSkin (skins[p->userinfo.GetSkin()].name, p->CurrentPlayerClass)); + p->userinfo.SkinNumChanged(R_FindSkin (Skins[p->userinfo.GetSkin()].Name, p->CurrentPlayerClass)); if (!(mobj->flags2 & MF2_DONTTRANSLATE)) { @@ -5416,7 +5416,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) // [RH] Set player sprite based on skin if (!(mobj->flags4 & MF4_NOSKIN)) { - mobj->sprite = skins[p->userinfo.GetSkin()].sprite; + mobj->sprite = Skins[p->userinfo.GetSkin()].sprite; } p->DesiredFOV = p->FOV = 90.f; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index a3208598d..8f06b7809 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -837,7 +837,7 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name) } // Validate the skin - dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass)); + dst->userinfo.SkinNumChanged(R_FindSkin(Skins[dst->userinfo.GetSkin()].Name, dst->CurrentPlayerClass)); // Make sure the player pawn points to the proper player struct. if (dst->mo != nullptr) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 875d3fbc0..ac7faea76 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4203,7 +4203,6 @@ static void P_Shutdown () { // [ZZ] delete global event handlers E_Shutdown(false); - R_DeinitSpriteData (); P_DeinitKeyMessages (); P_FreeLevelData (); P_FreeExtraLevelData (); diff --git a/src/p_states.cpp b/src/p_states.cpp index 3602cfc81..d6f43aabe 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -74,9 +74,9 @@ DEFINE_ACTION_FUNCTION(FState, GetSpriteTexture) } else { - sprframe = &SpriteFrames[sprites[skins[skin].sprite].spriteframes + self->GetFrame()]; - scalex = skins[skin].Scale.X; - scaley = skins[skin].Scale.Y; + sprframe = &SpriteFrames[sprites[Skins[skin].sprite].spriteframes + self->GetFrame()]; + scalex = Skins[skin].Scale.X; + scaley = Skins[skin].Scale.Y; } if (numret > 0) ret[0].SetInt(sprframe->Texture[rotation].GetIndex()); if (numret > 1) ret[1].SetInt(!!(sprframe->Flip & (1 << rotation))); diff --git a/src/p_user.cpp b/src/p_user.cpp index 5816a9689..bd6b2be4e 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1247,9 +1247,9 @@ const char *APlayerPawn::GetSoundClass() const if (player != NULL && (player->mo == NULL || !(player->mo->flags4 &MF4_NOSKIN)) && (unsigned int)player->userinfo.GetSkin() >= PlayerClasses.Size () && - (size_t)player->userinfo.GetSkin() < numskins) + (unsigned)player->userinfo.GetSkin() < Skins.Size()) { - return skins[player->userinfo.GetSkin()].name; + return Skins[player->userinfo.GetSkin()].Name.GetChars(); } return SoundClass != NAME_None? SoundClass.GetChars() : "player"; @@ -1801,8 +1801,8 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, DVector2 &scale) { // Convert from default scale to skin scale. DVector2 defscale = actor->GetDefault()->Scale; - scale.X *= skins[player->userinfo.GetSkin()].Scale.X / defscale.X; - scale.Y *= skins[player->userinfo.GetSkin()].Scale.Y / defscale.Y; + scale.X *= Skins[player->userinfo.GetSkin()].Scale.X / defscale.X; + scale.Y *= Skins[player->userinfo.GetSkin()].Scale.Y / defscale.Y; } // Set the crouch sprite? @@ -1813,10 +1813,10 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, DVector2 &scale) crouchspriteno = player->mo->crouchsprite; } else if (!(actor->flags4 & MF4_NOSKIN) && - (spritenum == skins[player->userinfo.GetSkin()].sprite || - spritenum == skins[player->userinfo.GetSkin()].crouchsprite)) + (spritenum == Skins[player->userinfo.GetSkin()].sprite || + spritenum == Skins[player->userinfo.GetSkin()].crouchsprite)) { - crouchspriteno = skins[player->userinfo.GetSkin()].crouchsprite; + crouchspriteno = Skins[player->userinfo.GetSkin()].crouchsprite; } else { // no sprite -> squash the existing one diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 0f4d58e6d..fd1bf5d21 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -1171,7 +1171,7 @@ void R_BuildPlayerTranslation (int player) D_GetPlayerColor (player, &h, &s, &v, &colorset); R_CreatePlayerTranslation (h, s, v, colorset, - &skins[players[player].userinfo.GetSkin()], + &Skins[players[player].userinfo.GetSkin()], translationtables[TRANSLATION_Players][player], translationtables[TRANSLATION_PlayersExtra][player], translationtables[TRANSLATION_RainPillar][player] @@ -1218,9 +1218,9 @@ DEFINE_ACTION_FUNCTION(_Translation, SetPlayerTranslation) if (cls != nullptr) { - PlayerSkin = R_FindSkin(skins[PlayerSkin].name, int(cls - &PlayerClasses[0])); + PlayerSkin = R_FindSkin(Skins[PlayerSkin].Name, int(cls - &PlayerClasses[0])); R_GetPlayerTranslation(PlayerColor, GetColorSet(cls->Type, PlayerColorset), - &skins[PlayerSkin], translationtables[tgroup][tnum]); + &Skins[PlayerSkin], translationtables[tgroup][tnum]); } ACTION_RETURN_BOOL(true); } diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index c3f73760d..72199cece 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -30,8 +30,7 @@ struct spriteframewithrotate : public spriteframe_t // [RH] skin globals -FPlayerSkin *skins; -size_t numskins; +TArray Skins; BYTE OtherGameSkinRemap[256]; PalEntry OtherGameSkinPalette[256]; @@ -512,7 +511,7 @@ void R_InitSkins (void) int sndlumps[NUMSKINSOUNDS]; char key[65]; DWORD intname, crouchname; - size_t i; + unsigned i; int j, k, base; int lastlump; int aliasid; @@ -538,7 +537,7 @@ void R_InitSkins (void) i++; for (j = 0; j < NUMSKINSOUNDS; j++) sndlumps[j] = -1; - skins[i].namespc = Wads.GetLumpNamespace (base); + Skins[i].namespc = Wads.GetLumpNamespace (base); FScanner sc(base); intname = 0; @@ -560,14 +559,13 @@ void R_InitSkins (void) sc.GetString (); if (0 == stricmp (key, "name")) { - strncpy (skins[i].name, sc.String, 16); - for (j = 0; (size_t)j < i; j++) + Skins[i].Name = sc.String; + for (j = 0; (unsigned)j < i; j++) { - if (stricmp (skins[i].name, skins[j].name) == 0) + if (Skins[i].Name.CompareNoCase(Skins[j].Name) == 0) { - mysnprintf (skins[i].name, countof(skins[i].name), "skin%d", (int)i); - Printf (PRINT_BOLD, "Skin %s duplicated as %s\n", - skins[j].name, skins[i].name); + Skins[i].Name.Format("skin%u", i); + Printf (PRINT_BOLD, "Skin %s duplicated as %s\n", Skins[j].Name.GetChars(), Skins[i].Name.GetChars()); break; } } @@ -586,18 +584,16 @@ void R_InitSkins (void) } else if (0 == stricmp (key, "face")) { - for (j = 2; j >= 0; j--) - skins[i].face[j] = toupper (sc.String[j]); - skins[i].face[3] = '\0'; + Skins[i].Face = FString(sc.String, 3); } else if (0 == stricmp (key, "gender")) { - skins[i].gender = D_GenderToInt (sc.String); + Skins[i].gender = D_GenderToInt (sc.String); } else if (0 == stricmp (key, "scale")) { - skins[i].Scale.X = clamp(atof (sc.String), 1./65536, 256.); - skins[i].Scale.Y = skins[i].Scale.X; + Skins[i].Scale.X = clamp(atof (sc.String), 1./65536, 256.); + Skins[i].Scale.Y = Skins[i].Scale.X; } else if (0 == stricmp (key, "game")) { @@ -615,7 +611,7 @@ void R_InitSkins (void) if (gameinfo.gametype & GAME_DoomChex) { transtype = PClass::FindActor(NAME_HereticPlayer); - skins[i].othergame = true; + Skins[i].othergame = true; } else if (gameinfo.gametype != GAME_Heretic) { @@ -634,7 +630,7 @@ void R_InitSkins (void) if (gameinfo.gametype == GAME_Heretic) { transtype = PClass::FindActor(NAME_DoomPlayer); - skins[i].othergame = true; + Skins[i].othergame = true; } else if (!(gameinfo.gametype & GAME_DoomChex)) { @@ -659,7 +655,7 @@ void R_InitSkins (void) } else if (key[0] == '*') { // Player sound replacment (ZDoom extension) - int lump = Wads.CheckNumForName (sc.String, skins[i].namespc); + int lump = Wads.CheckNumForName (sc.String, Skins[i].namespc); if (lump == -1) { lump = Wads.CheckNumForFullName (sc.String, true, ns_sounds); @@ -668,11 +664,11 @@ void R_InitSkins (void) { if (stricmp (key, "*pain") == 0) { // Replace all pain sounds in one go - aliasid = S_AddPlayerSound (skins[i].name, skins[i].gender, + aliasid = S_AddPlayerSound (Skins[i].Name, Skins[i].gender, playersoundrefs[0], lump, true); for (int l = 3; l > 0; --l) { - S_AddPlayerSoundExisting (skins[i].name, skins[i].gender, + S_AddPlayerSoundExisting (Skins[i].Name, Skins[i].gender, playersoundrefs[l], aliasid, true); } } @@ -681,7 +677,7 @@ void R_InitSkins (void) int sndref = S_FindSoundNoHash (key); if (sndref != 0) { - S_AddPlayerSound (skins[i].name, skins[i].gender, sndref, lump, true); + S_AddPlayerSound (Skins[i].Name, Skins[i].gender, sndref, lump, true); } } } @@ -692,7 +688,7 @@ void R_InitSkins (void) { if (stricmp (key, skinsoundnames[j][0]) == 0) { - sndlumps[j] = Wads.CheckNumForName (sc.String, skins[i].namespc); + sndlumps[j] = Wads.CheckNumForName (sc.String, Skins[i].namespc); if (sndlumps[j] == -1) { // Replacement not found, try finding it in the global namespace sndlumps[j] = Wads.CheckNumForFullName (sc.String, true, ns_sounds); @@ -715,7 +711,7 @@ void R_InitSkins (void) { basetype = PClass::FindActor(NAME_HereticPlayer); transtype = PClass::FindActor(NAME_DoomPlayer); - skins[i].othergame = true; + Skins[i].othergame = true; } else { @@ -728,8 +724,8 @@ void R_InitSkins (void) auto transdef = ((APlayerPawn*)GetDefaultByType(transtype)); auto basedef = ((APlayerPawn*)GetDefaultByType(basetype)); - skins[i].range0start = transdef->ColorRangeStart; - skins[i].range0end = transdef->ColorRangeEnd; + Skins[i].range0start = transdef->ColorRangeStart; + Skins[i].range0end = transdef->ColorRangeEnd; remove = true; for (j = 0; j < (int)PlayerClasses.Size (); j++) @@ -750,8 +746,8 @@ void R_InitSkins (void) if (!remove) { - if (skins[i].name[0] == 0) - mysnprintf (skins[i].name, countof(skins[i].name), "skin%d", (int)i); + if (Skins[i].Name.IsEmpty()) + Skins[i].Name.Format("skin%u", i); // Now collect the sprite frames for this skin. If the sprite name was not // specified, use whatever immediately follows the specifier lump. @@ -783,7 +779,7 @@ void R_InitSkins (void) } else { - skins[i].crouchsprite = -1; + Skins[i].crouchsprite = -1; break; } } @@ -806,7 +802,7 @@ void R_InitSkins (void) if (spr == 0 && maxframe <= 0) { - Printf (PRINT_BOLD, "Skin %s (#%d) has no frames. Removing.\n", skins[i].name, (int)i); + Printf (PRINT_BOLD, "Skin %s (#%u) has no frames. Removing.\n", Skins[i].Name, i); remove = true; break; } @@ -814,16 +810,18 @@ void R_InitSkins (void) Wads.GetLumpName (temp.name, base+1); temp.name[4] = 0; int sprno = (int)sprites.Push (temp); - if (spr==0) skins[i].sprite = sprno; - else skins[i].crouchsprite = sprno; + if (spr==0) Skins[i].sprite = sprno; + else Skins[i].crouchsprite = sprno; R_InstallSprite (sprno, sprtemp, maxframe); } } if (remove) { - if (i < numskins-1) - memmove (&skins[i], &skins[i+1], sizeof(skins[0])*(numskins-i-1)); + if (i < Skins.Size() - 1) + { + Skins.Delete(i); + } i--; continue; } @@ -836,25 +834,25 @@ void R_InitSkins (void) { if (j == 0 || sndlumps[j] != sndlumps[j-1]) { - aliasid = S_AddPlayerSound (skins[i].name, skins[i].gender, + aliasid = S_AddPlayerSound (Skins[i].Name, Skins[i].gender, playersoundrefs[j], sndlumps[j], true); } else { - S_AddPlayerSoundExisting (skins[i].name, skins[i].gender, + S_AddPlayerSoundExisting (Skins[i].Name, Skins[i].gender, playersoundrefs[j], aliasid, true); } } } // Make sure face prefix is a full 3 chars - if (skins[i].face[1] == 0 || skins[i].face[2] == 0) + if (Skins[i].Face.Len() < 3) { - skins[i].face[0] = 0; + Skins[i].Face = ""; } } - if (numskins > PlayerClasses.Size ()) + if (Skins.Size() > PlayerClasses.Size ()) { // The sound table may have changed, so rehash it. S_HashSounds (); S_ShrinkPlayerSoundLists (); @@ -869,9 +867,9 @@ int R_FindSkin (const char *name, int pclass) return pclass; } - for (unsigned i = PlayerClasses.Size(); i < numskins; i++) + for (unsigned i = PlayerClasses.Size(); i < Skins.Size(); i++) { - if (strnicmp (skins[i].name, name, 16) == 0) + if (Skins[i].Name.CompareNoCase(name) == 0) { if (PlayerClasses[pclass].CheckSkin (i)) return i; @@ -887,8 +885,8 @@ CCMD (skins) { int i; - for (i = PlayerClasses.Size ()-1; i < (int)numskins; i++) - Printf ("% 3d %s\n", i-PlayerClasses.Size ()+1, skins[i].name); + for (i = PlayerClasses.Size() - 1; i < (int)Skins.Size(); i++) + Printf("% 3d %s\n", i - PlayerClasses.Size() + 1, Skins[i].Name.GetChars()); } @@ -914,6 +912,7 @@ void R_InitSprites () { int lump, lastlump; unsigned int i, j; + unsigned numskins; // [RH] Create a standard translation to map skins between Heretic and Doom if (gameinfo.gametype == GAME_DoomChex) @@ -934,15 +933,15 @@ void R_InitSprites () } // [RH] Do some preliminary setup - if (skins != NULL) delete [] skins; - skins = new FPlayerSkin[numskins]; - memset (skins, 0, sizeof(*skins) * numskins); + Skins.Clear(); + Skins.Resize(numskins); + for (i = 0; i < numskins; i++) { // Assume Doom skin by default auto type = ((APlayerPawn*)GetDefaultByType(PlayerClasses[0].Type)); - skins[i].range0start = type->ColorRangeStart; - skins[i].range0end = type->ColorRangeEnd; - skins[i].Scale = type->Scale; + Skins[i].range0start = type->ColorRangeStart; + Skins[i].range0end = type->ColorRangeEnd; + Skins[i].Scale = type->Scale; } R_InitSpriteDefs (); @@ -956,33 +955,30 @@ void R_InitSprites () { auto basetype = ((APlayerPawn*)GetDefaultByType(PlayerClasses[i].Type)); - strcpy (skins[i].name, "Base"); + Skins[i].Name = "Base"; if (basetype->Face == NAME_None) { - skins[i].face[0] = 'S'; - skins[i].face[1] = 'T'; - skins[i].face[2] = 'F'; - skins[i].face[3] = '\0'; + Skins[i].Face = "STF"; } else { - strcpy(skins[i].face, basetype->Face); + Skins[i].Face = basetype->Face; } - skins[i].range0start = basetype->ColorRangeStart; - skins[i].range0end = basetype->ColorRangeEnd; - skins[i].Scale = basetype->Scale; - skins[i].sprite = basetype->SpawnState->sprite; - skins[i].namespc = ns_global; + Skins[i].range0start = basetype->ColorRangeStart; + Skins[i].range0end = basetype->ColorRangeEnd; + Skins[i].Scale = basetype->Scale; + Skins[i].sprite = basetype->SpawnState->sprite; + Skins[i].namespc = ns_global; PlayerClasses[i].Skins.Push (i); - if (memcmp (sprites[skins[i].sprite].name, "PLAY", 4) == 0) + if (memcmp (sprites[Skins[i].sprite].name, "PLAY", 4) == 0) { for (j = 0; j < sprites.Size (); j++) { if (memcmp (sprites[j].name, deh.PlayerSprite, 4) == 0) { - skins[i].sprite = (int)j; + Skins[i].sprite = (int)j; break; } } @@ -995,12 +991,14 @@ void R_InitSprites () gl_InitModels(); } -void R_DeinitSpriteData() -{ - // Free skins - if (skins != NULL) - { - delete[] skins; - skins = NULL; - } -} + +DEFINE_FIELD(FPlayerSkin, Name); +DEFINE_FIELD(FPlayerSkin, Face); +DEFINE_FIELD(FPlayerSkin, gender); +DEFINE_FIELD(FPlayerSkin, range0start); +DEFINE_FIELD(FPlayerSkin, range0end); +DEFINE_FIELD(FPlayerSkin, othergame); +DEFINE_FIELD(FPlayerSkin, Scale); +DEFINE_FIELD(FPlayerSkin, sprite); +DEFINE_FIELD(FPlayerSkin, crouchsprite); +DEFINE_FIELD(FPlayerSkin, namespc); diff --git a/src/r_data/sprites.h b/src/r_data/sprites.h index d882ee981..9e7d9392e 100644 --- a/src/r_data/sprites.h +++ b/src/r_data/sprites.h @@ -47,25 +47,23 @@ extern TArray SpriteFrames; class FPlayerSkin { public: - char name[17]; // 16 chars + NULL - char face[4]; // 3 chars ([MH] + NULL so can use as a C string) - BYTE gender; // This skin's gender (not really used) - BYTE range0start; - BYTE range0end; - bool othergame; // [GRB] - DVector2 Scale; - int sprite; - int crouchsprite; - int namespc; // namespace for this skin + FString Name; + FString Face; + BYTE gender = 0; // This skin's gender (not really used) + BYTE range0start = 0; + BYTE range0end = 0; + bool othergame = 0; // [GRB] + DVector2 Scale = { 1, 1 }; + int sprite = 0; + int crouchsprite = 0; + int namespc = 0; // namespace for this skin }; -extern size_t numskins; // [RH] -extern FPlayerSkin * skins; // [RH] +extern TArray Skins; extern BYTE OtherGameSkinRemap[256]; extern PalEntry OtherGameSkinPalette[256]; void R_InitSprites (); -void R_DeinitSpriteData (); #endif diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index f257c7c2d..c9679c4b2 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -57,6 +57,7 @@ #include "v_video.h" #include "c_bind.h" #include "menu/menu.h" +#include "r_data/sprites.h" static TArray properties; static TArray AFTable; @@ -759,6 +760,10 @@ void InitThingdef() playerclassstruct->Size = sizeof(FPlayerClass); playerclassstruct->Align = alignof(FPlayerClass); + auto playerskinstruct = NewNativeStruct("PlayerSkin", nullptr); + playerskinstruct->Size = sizeof(FPlayerSkin); + playerskinstruct->Align = alignof(FPlayerSkin); + // set up the lines array in the sector struct. This is a bit messy because the type system is not prepared to handle a pointer to an array of pointers to a native struct even remotely well... // As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up. sectorstruct->AddNativeField("lines", NewPointer(NewResizableArray(NewPointer(linestruct, false)), false), myoffsetof(sector_t, Lines), VARF_Native); @@ -798,6 +803,10 @@ void InitThingdef() PField *plrclsf = new PField("PlayerClasses", plrcls, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&PlayerClasses); Namespaces.GlobalNamespace->Symbols.AddSymbol(plrclsf); + auto plrskn = NewPointer(NewResizableArray(playerskinstruct), false); + PField *plrsknf = new PField("PlayerSkins", plrcls, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Skins); + Namespaces.GlobalNamespace->Symbols.AddSymbol(plrsknf); + auto bindcls = NewNativeStruct("KeyBindings", nullptr); PField *binding = new PField("Bindings", bindcls, VARF_Native | VARF_Static, (intptr_t)&Bindings); Namespaces.GlobalNamespace->Symbols.AddSymbol(binding); diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 24bfa51c6..ab3019dcd 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -326,3 +326,17 @@ struct PlayerClass native native bool CheckSkin(int skin); } + +struct PlayerSkin native +{ + native readonly String Name; + native readonly String Face; + native readonly uint8 gender; + native readonly uint8 range0start; + native readonly uint8 range0end; + native readonly bool othergame; + native readonly Vector2 Scale; + native readonly int sprite; + native readonly int crouchsprite; + native readonly int namespc; +}; From 97eed1e6df0fcda6ee559f9af302c415d404b021 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 22:12:56 +0100 Subject: [PATCH 08/12] - scriptified UpdateSkins. --- src/menu/playermenu.cpp | 2 +- src/p_user.cpp | 5 +++ src/r_data/sprites.cpp | 2 +- src/scripting/thingdef_data.cpp | 2 +- wadsrc/static/zscript/menu/playermenu.txt | 50 ++++++++++++++++++++++- wadsrc/static/zscript/shared/player.txt | 13 +++--- 6 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index ec2d76a5c..ac4732329 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -597,5 +597,5 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AlwaysRunChanged) DEFINE_FIELD(DPlayerMenu, mRotation) DEFINE_FIELD_NAMED(DPlayerMenu, PlayerClass, mPlayerClass) DEFINE_FIELD(DPlayerMenu, PlayerColorSets) -DEFINE_FIELD(DPlayerMenu, PlayerSkins) +DEFINE_FIELD_NAMED(DPlayerMenu, PlayerSkins, mPlayerSkins) DEFINE_FIELD(DPlayerMenu, PlayerClassIndex) diff --git a/src/p_user.cpp b/src/p_user.cpp index bd6b2be4e..79f691ec0 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -673,6 +673,11 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetPlayerClassNum) ACTION_RETURN_INT(self->userinfo.GetPlayerClassNum()); } +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetSkin) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_INT(self->userinfo.GetSkin()); +} //=========================================================================== // diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 72199cece..45167580f 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -992,7 +992,7 @@ void R_InitSprites () } -DEFINE_FIELD(FPlayerSkin, Name); +DEFINE_FIELD_NAMED(FPlayerSkin, Name, SkinName); DEFINE_FIELD(FPlayerSkin, Face); DEFINE_FIELD(FPlayerSkin, gender); DEFINE_FIELD(FPlayerSkin, range0start); diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index c9679c4b2..3550a78c9 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -804,7 +804,7 @@ void InitThingdef() Namespaces.GlobalNamespace->Symbols.AddSymbol(plrclsf); auto plrskn = NewPointer(NewResizableArray(playerskinstruct), false); - PField *plrsknf = new PField("PlayerSkins", plrcls, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Skins); + PField *plrsknf = new PField("PlayerSkins", plrskn, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Skins); Namespaces.GlobalNamespace->Symbols.AddSymbol(plrsknf); auto bindcls = NewNativeStruct("KeyBindings", nullptr); diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index 0ac5328a0..4a6a94b2d 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -5,7 +5,7 @@ class PlayerMenu : ListMenu native native int PlayerClassIndex; native PlayerClass mPlayerClass; native Array PlayerColorSets; - native Array PlayerSkins; + native Array mPlayerSkins; // All write function for the player config are native to prevent abuse. protected native void AutoaimChanged(float val); @@ -61,6 +61,52 @@ class PlayerMenu : ListMenu native // //============================================================================= + protected void UpdateSkins() + { + int sel = 0; + int skin; + let li = GetItem('Skin'); + if (li != NULL) + { + if (GetDefaultByType (mPlayerClass.Type).bNoSkin || players[consoleplayer].GetPlayerClassNum() == -1) + { + li.SetString(0, "Base"); + li.SetValue(0, 0); + skin = 0; + } + else + { + mPlayerSkins.Clear(); + for (int i = 0; i < PlayerSkins.Size(); i++) + { + if (mPlayerClass.CheckSkin(i)) + { + int j = mPlayerSkins.Push(i); + li.SetString(j, PlayerSkins[i].SkinName); + if (players[consoleplayer].GetSkin() == i) + { + sel = j; + } + } + } + li.SetValue(0, sel); + skin = mPlayerSkins[sel]; + } + li = GetItem('Playerdisplay'); + if (li != NULL) + { + li.SetValue(ListMenuItemPlayerDisplay.PDF_SKIN, skin); + } + } + UpdateTranslation(); + } + +//============================================================================= + // + // + // + //============================================================================= + protected void ChangeSkin (MenuItemBase li) { if (GetDefaultByType (mPlayerClass.Type).bNoSkin || players[consoleplayer].GetPlayerClassNum() == -1) @@ -74,7 +120,7 @@ class PlayerMenu : ListMenu native [res, sel] = li.GetValue(0); if (res) { - sel = PlayerSkins[sel]; + sel = mPlayerSkins[sel]; SkinChanged(sel); UpdateTranslation(); diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index ab3019dcd..9203dee0e 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -295,7 +295,6 @@ struct PlayerInfo native // this is what internally is known as player_t /* these are not doable yet ticcmd_t cmd; usercmd_t original_cmd; -userinfo_t userinfo; */ @@ -309,13 +308,15 @@ userinfo_t userinfo; native PSprite FindPSprite(int id); native void SetLogNumber (int text); native void SetLogText (String text); - native String GetUserName(); - native Color GetColor(); - native int GetPlayerClassNum(); - native bool GetNeverSwitch(); native void DropWeapon(); native void BringUpWeapon(); + native String GetUserName(); + native Color GetColor(); + native int GetPlayerClassNum(); + native int GetSkin(); + native bool GetNeverSwitch(); + } struct PlayerClass native @@ -329,7 +330,7 @@ struct PlayerClass native struct PlayerSkin native { - native readonly String Name; + native readonly String SkinName; native readonly String Face; native readonly uint8 gender; native readonly uint8 range0start; From 50d2846e40457fd6715d498404ad97063b766d59 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 23:16:07 +0100 Subject: [PATCH 09/12] - scriptified UpdateColorsets. --- src/p_user.cpp | 22 ++++++++++++++ src/scripting/zscript/zcc_compile.cpp | 25 +++++++--------- wadsrc/static/zscript/menu/playermenu.txt | 36 ++++++++++++++++++++++- wadsrc/static/zscript/shared/player.txt | 4 ++- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index 79f691ec0..0d69810d9 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -584,6 +584,14 @@ void EnumColorSets(PClassActor *cls, TArray *out) qsort(&(*out)[0], out->Size(), sizeof(int), intcmp); } +DEFINE_ACTION_FUNCTION(FPlayerClass, EnumColorSets) +{ + PARAM_SELF_STRUCT_PROLOGUE(FPlayerClass); + PARAM_POINTER(out, TArray); + EnumColorSets(self->Type, out); + return 0; +} + //========================================================================== // // @@ -603,6 +611,14 @@ FPlayerColorSet *GetColorSet(PClassActor *cls, int setnum) return nullptr; } +DEFINE_ACTION_FUNCTION(FPlayerClass, GetColorSetName) +{ + PARAM_SELF_STRUCT_PROLOGUE(FPlayerClass); + PARAM_INT(setnum); + auto p = GetColorSet(self->Type, setnum); + ACTION_RETURN_INT(p ? p->Name.GetIndex() : 0); +} + //========================================================================== // // @@ -667,6 +683,12 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetColor) ACTION_RETURN_INT(self->userinfo.GetColor()); } +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetColorSet) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_INT(self->userinfo.GetColorSet()); +} + DEFINE_ACTION_FUNCTION(_PlayerInfo, GetPlayerClassNum) { PARAM_SELF_STRUCT_PROLOGUE(player_t); diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index a240c1973..c802dda36 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1361,22 +1361,19 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n break; case AST_DynArrayType: - if (allowarraytypes) + { + auto atype = static_cast(ztype); + auto ftype = DetermineType(outertype, field, name, atype->ElementType, false, true); + if (ftype->GetRegType() == REGT_NIL || ftype->GetRegCount() > 1) { - auto atype = static_cast(ztype); - auto ftype = DetermineType(outertype, field, name, atype->ElementType, false, true); - if (ftype->GetRegType() == REGT_NIL || ftype->GetRegCount() > 1) - { - Error(field, "%s: Base type for dynamic array types nust be integral, but got %s", name.GetChars(), ftype->DescriptiveName()); - } - else - { - retval = NewDynArray(ftype); - } - break; + Error(field, "%s: Base type for dynamic array types nust be integral, but got %s", name.GetChars(), ftype->DescriptiveName()); + } + else + { + retval = NewDynArray(ftype); } break; - + } case AST_ClassType: { auto ctype = static_cast(ztype); @@ -2135,7 +2132,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool { auto type = DetermineType(c->Type(), p, f->Name, p->Type, false, false); int flags = 0; - if (type->IsA(RUNTIME_CLASS(PStruct)) && type != TypeVector2 && type != TypeVector3) + if ((type->IsA(RUNTIME_CLASS(PStruct)) && type != TypeVector2 && type != TypeVector3) || type->IsA(RUNTIME_CLASS(PDynArray))) { // Structs are being passed by pointer, but unless marked 'out' that pointer must be readonly. type = NewPointer(type /*, !(p->Flags & ZCC_Out)*/); diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index 4a6a94b2d..8c4c66f56 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -61,6 +61,40 @@ class PlayerMenu : ListMenu native // //============================================================================= + protected void UpdateColorsets() + { + let li = GetItem('Color'); + if (li != NULL) + { + int sel = 0; + mPlayerClass.EnumColorSets(PlayerColorSets); + li.SetString(0, "Custom"); + for(int i = 0; i < PlayerColorSets.Size(); i++) + { + let cname = mPlayerClass.GetColorSetName(PlayerColorSets[i]); + li.SetString(i+1, cname); + } + int mycolorset = players[consoleplayer].GetColorSet(); + if (mycolorset != -1) + { + for(int i = 0; i < PlayerColorSets.Size(); i++) + { + if (PlayerColorSets[i] == mycolorset) + { + sel = i + 1; + } + } + } + li.SetValue(0, sel); + } + } + + //============================================================================= + // + // + // + //============================================================================= + protected void UpdateSkins() { int sel = 0; @@ -101,7 +135,7 @@ class PlayerMenu : ListMenu native UpdateTranslation(); } -//============================================================================= + //============================================================================= // // // diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 9203dee0e..f7333220b 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -313,10 +313,10 @@ usercmd_t original_cmd; native String GetUserName(); native Color GetColor(); + native int GetColorSet(); native int GetPlayerClassNum(); native int GetSkin(); native bool GetNeverSwitch(); - } struct PlayerClass native @@ -326,6 +326,8 @@ struct PlayerClass native native Array Skins; native bool CheckSkin(int skin); + native void EnumColorsets(out Array data); + native Name GetColorsetName(int setnum); } struct PlayerSkin native From 49a07180c07c6b74cf1edd9d45555b179fb0ec53 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Feb 2017 23:56:22 +0100 Subject: [PATCH 10/12] - scriptified ClassChanged. --- src/gi.cpp | 1 + src/menu/playermenu.cpp | 55 +++++++---------------- wadsrc/static/zscript/base.txt | 1 + wadsrc/static/zscript/menu/playermenu.txt | 42 ++++++++++++++--- 4 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/gi.cpp b/src/gi.cpp index 9f6827ab4..b05000d01 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -50,6 +50,7 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, Armor2Percent) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, ArmorIcon1) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, ArmorIcon2) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, gametype) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, norandomplayerclass) const char *GameNames[17] = diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index ac4732329..93db2040c 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -77,12 +77,6 @@ public: void UpdateSkins(); void UpdateTranslation(); - void PlayerNameChanged(DMenuItemBase *li); - void ColorSetChanged (DMenuItemBase *li); - void ClassChanged (DMenuItemBase *li); - void SkinChanged (DMenuItemBase *li); - - public: DPlayerMenu() {} @@ -248,7 +242,7 @@ bool DPlayerMenu::Responder (event_t *ev) //============================================================================= // -// +// done // //============================================================================= @@ -268,7 +262,7 @@ void DPlayerMenu::UpdateTranslation() //============================================================================= // -// +// done // //============================================================================= @@ -305,7 +299,10 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) { + char command[24]; players[consoleplayer].userinfo.ColorChanged(MAKERGB(r, g, b)); + mysnprintf(command, countof(command), "color \"%02x %02x %02x\"", r, g, b); + C_DoCommand(command); } return 0; } @@ -313,7 +310,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) //============================================================================= // -// +// done // //============================================================================= @@ -347,7 +344,7 @@ void DPlayerMenu::UpdateColorsets() //============================================================================= // -// +// done // //============================================================================= @@ -436,6 +433,9 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) if (self == DMenu::CurrentMenu) { players[consoleplayer].userinfo.ColorSetChanged(sel); + char command[24]; + mysnprintf(command, countof(command), "colorset %d", sel); + C_DoCommand(command); } return 0; } @@ -446,41 +446,15 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) // //============================================================================= -void DPlayerMenu::ClassChanged (DMenuItemBase *li) -{ - if (PlayerClasses.Size () == 1) - { - return; - } - - int sel; - - if (li->GetValue(0, &sel)) - { - players[consoleplayer].userinfo.PlayerClassNumChanged(gameinfo.norandomplayerclass ? sel : sel-1); - PickPlayerClass(); - - cvar_set ("playerclass", sel == 0 && !gameinfo.norandomplayerclass ? "Random" : GetPrintableDisplayName(PlayerClass->Type).GetChars()); - - UpdateSkins(); - UpdateColorsets(); - UpdateTranslation(); - - li = GetItem(NAME_Playerdisplay); - if (li != NULL) - { - li->SetValue(ListMenuItemPlayerDisplay_PDF_CLASS, players[consoleplayer].userinfo.GetPlayerClassNum()); - } - } -} - DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) { PARAM_SELF_PROLOGUE(DPlayerMenu); - PARAM_OBJECT(sel, DMenuItemBase); + PARAM_INT(sel); + PARAM_POINTER(cls, FPlayerClass); if (self == DMenu::CurrentMenu) { - self->ClassChanged(sel); + players[consoleplayer].userinfo.PlayerClassNumChanged(gameinfo.norandomplayerclass ? sel : sel - 1); + cvar_set("playerclass", sel == 0 && !gameinfo.norandomplayerclass ? "Random" : GetPrintableDisplayName(cls->Type).GetChars()); } return 0; } @@ -499,6 +473,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) if (self == DMenu::CurrentMenu) { players[consoleplayer].userinfo.SkinNumChanged(sel); + cvar_set("skin", Skins[sel].Name); } return 0; } diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 7b872f472..57bdc7b01 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -309,6 +309,7 @@ struct GameInfoStruct native native String ArmorIcon1; native String ArmorIcon2; native int gametype; + native bool norandomplayerclass; } class Object native diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index 8c4c66f56..4fbc91620 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -17,8 +17,7 @@ class PlayerMenu : ListMenu native protected native void ColorSetChanged(int red); protected native void PlayerNameChanged(String name); protected native void SkinChanged (int val); - - protected native void ClassChanged(ListMenuItem it); + protected native void ClassChanged(int sel, PlayerClass cls); protected void UpdateTranslation() { @@ -37,13 +36,13 @@ class PlayerMenu : ListMenu native // //============================================================================= - protected void PickPlayerClass() + protected void PickPlayerClass(int pick = -100) { int pclass = 0; // [GRB] Pick a class from player class list if (PlayerClasses.Size () > 1) { - pclass = players[consoleplayer].GetPlayerClassNum(); + pclass = pick == -100? players[consoleplayer].GetPlayerClassNum() : pick; if (pclass < 0) { @@ -141,6 +140,39 @@ class PlayerMenu : ListMenu native // //============================================================================= + void ChangeClass (MenuItemBase li) + { + if (PlayerClasses.Size () == 1) + { + return; + } + + bool res; + int sel; + + [res, sel] = li.GetValue(0); + if (res) + { + PickPlayerClass(gameinfo.norandomplayerclass ? sel : sel-1); + ClassChanged(sel, mPlayerClass); + UpdateSkins(); + UpdateColorsets(); + UpdateTranslation(); + + li = GetItem('Playerdisplay'); + if (li != NULL) + { + li.SetValue(ListMenuItemPlayerDisplay.PDF_CLASS, players[consoleplayer].GetPlayerClassNum()); + } + } + } + + //============================================================================= + // + // + // + //============================================================================= + protected void ChangeSkin (MenuItemBase li) { if (GetDefaultByType (mPlayerClass.Type).bNoSkin || players[consoleplayer].GetPlayerClassNum() == -1) @@ -254,7 +286,7 @@ class PlayerMenu : ListMenu native [res, v] = li.GetValue(0); if (res) { - ClassChanged(li); + ChangeClass(li); } break; From 5f1241a55c73986aa36d32363a1196128a44af8b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 01:20:07 +0100 Subject: [PATCH 11/12] - scriptified the rest of the player menu. This compiles and runs but doesn't work yet, it will be fixed in the next commit. --- src/d_player.h | 5 + src/menu/playermenu.cpp | 345 +--------------------- src/p_user.cpp | 19 ++ src/scripting/thingdef_data.cpp | 9 + src/teaminfo.cpp | 3 + src/teaminfo.h | 2 + wadsrc/static/zscript/menu/playermenu.txt | 201 ++++++++++++- wadsrc/static/zscript/shared/player.txt | 10 + 8 files changed, 256 insertions(+), 338 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 7fa0d45b2..b16af3611 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -297,6 +297,11 @@ struct userinfo_t : TMap return aim; } } + // Same but unfiltered. + double GetAutoaim() const + { + return *static_cast(*CheckKey(NAME_Autoaim)); + } const char *GetName() const { return *static_cast(*CheckKey(NAME_Name)); diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 93db2040c..519af0a9d 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -48,241 +48,10 @@ #include "r_data/r_translate.h" #include "v_text.h" -EXTERN_CVAR (String, playerclass) -EXTERN_CVAR (String, name) -EXTERN_CVAR (Int, team) -EXTERN_CVAR (Float, autoaim) +EXTERN_CVAR(Int, team) +EXTERN_CVAR(Float, autoaim) EXTERN_CVAR(Bool, neverswitchonpickup) -EXTERN_CVAR (Bool, cl_run) - -//============================================================================= -// -// -// -//============================================================================= - -class DPlayerMenu : public DListMenu -{ - DECLARE_CLASS(DPlayerMenu, DListMenu) - -public: - int PlayerClassIndex; - FPlayerClass *PlayerClass; - TArray PlayerColorSets; - TArray PlayerSkins; - int mRotation; - - void PickPlayerClass (); - void UpdateColorsets(); - void UpdateSkins(); - void UpdateTranslation(); - -public: - - DPlayerMenu() {} - void Init(DMenu *parent, DListMenuDescriptor *desc); - bool Responder (event_t *ev); -}; - -IMPLEMENT_CLASS(DPlayerMenu, false, false) - -//============================================================================= -// -// -// -//============================================================================= -enum EPDFlags -{ - ListMenuItemPlayerDisplay_PDF_ROTATION = 0x10001, - ListMenuItemPlayerDisplay_PDF_SKIN = 0x10002, - ListMenuItemPlayerDisplay_PDF_CLASS = 0x10003, - ListMenuItemPlayerDisplay_PDF_MODE = 0x10004, - ListMenuItemPlayerDisplay_PDF_TRANSLATE = 0x10005, -}; - -void DPlayerMenu::Init(DMenu *parent, DListMenuDescriptor *desc) -{ - DMenuItemBase *li; - - Super::Init(parent, desc); - PickPlayerClass(); - mRotation = 0; - - li = GetItem(NAME_Playerdisplay); - if (li != NULL) - { - li->SetValue(ListMenuItemPlayerDisplay_PDF_ROTATION, 0); - li->SetValue(ListMenuItemPlayerDisplay_PDF_MODE, 1); - li->SetValue(ListMenuItemPlayerDisplay_PDF_TRANSLATE, 1); - li->SetValue(ListMenuItemPlayerDisplay_PDF_CLASS, players[consoleplayer].userinfo.GetPlayerClassNum()); - if (PlayerClass != NULL && !(GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN) && - players[consoleplayer].userinfo.GetPlayerClassNum() != -1) - { - li->SetValue(ListMenuItemPlayerDisplay_PDF_SKIN, players[consoleplayer].userinfo.GetSkin()); - } - } - - li = GetItem(NAME_Playerbox); - if (li != NULL) - { - li->SetString(0, name); - } - - li = GetItem(NAME_Team); - if (li != NULL) - { - li->SetString(0, "None"); - for(unsigned i=0;iSetString(i+1, Teams[i].GetName()); - } - li->SetValue(0, team == TEAM_NONE? 0 : team + 1); - } - - int mycolorset = players[consoleplayer].userinfo.GetColorSet(); - int color = players[consoleplayer].userinfo.GetColor(); - - UpdateColorsets(); - - li = GetItem(NAME_Red); - if (li != NULL) - { - li->Enable(mycolorset == -1); - li->SetValue(0, RPART(color)); - } - - li = GetItem(NAME_Green); - if (li != NULL) - { - li->Enable(mycolorset == -1); - li->SetValue(0, GPART(color)); - } - - li = GetItem(NAME_Blue); - if (li != NULL) - { - li->Enable(mycolorset == -1); - li->SetValue(0, BPART(color)); - } - - li = GetItem(NAME_Class); - if (li != NULL) - { - if (PlayerClasses.Size() == 1) - { - li->SetString(0, GetPrintableDisplayName(PlayerClasses[0].Type)); - li->SetValue(0, 0); - } - else - { - // [XA] Remove the "Random" option if the relevant gameinfo flag is set. - if(!gameinfo.norandomplayerclass) - li->SetString(0, "Random"); - for(unsigned i=0; i< PlayerClasses.Size(); i++) - { - const char *cls = GetPrintableDisplayName(PlayerClasses[i].Type); - li->SetString(gameinfo.norandomplayerclass ? i : i+1, cls); - } - int pclass = players[consoleplayer].userinfo.GetPlayerClassNum(); - li->SetValue(0, gameinfo.norandomplayerclass && pclass >= 0 ? pclass : pclass + 1); - } - } - - UpdateSkins(); - - li = GetItem(NAME_Gender); - if (li != NULL) - { - li->SetValue(0, players[consoleplayer].userinfo.GetGender()); - } - - li = GetItem(NAME_Autoaim); - if (li != NULL) - { - li->SetValue(0, (int)autoaim); - } - - li = GetItem(NAME_Switch); - if (li != NULL) - { - li->SetValue(0, neverswitchonpickup); - } - - li = GetItem(NAME_AlwaysRun); - if (li != NULL) - { - li->SetValue(0, cl_run); - } - - if (mDesc->mSelectedItem < 0) mDesc->mSelectedItem = 1; - -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DPlayerMenu::Responder (event_t *ev) -{ - if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_Char && ev->data1 == ' ') - { - // turn the player sprite around - mRotation = 8 - mRotation; - DMenuItemBase *li = GetItem(NAME_Playerdisplay); - if (li != NULL) - { - li->SetValue(ListMenuItemPlayerDisplay_PDF_ROTATION, mRotation); - } - return true; - } - return Super::Responder(ev); -} - -//============================================================================= -// -// done -// -//============================================================================= - -void DPlayerMenu::UpdateTranslation() -{ - int PlayerColor = players[consoleplayer].userinfo.GetColor(); - int PlayerSkin = players[consoleplayer].userinfo.GetSkin(); - int PlayerColorset = players[consoleplayer].userinfo.GetColorSet(); - - if (PlayerClass != NULL) - { - PlayerSkin = R_FindSkin (Skins[PlayerSkin].Name, int(PlayerClass - &PlayerClasses[0])); - R_GetPlayerTranslation(PlayerColor, GetColorSet(PlayerClass->Type, PlayerColorset), - &Skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); - } -} - -//============================================================================= -// -// done -// -//============================================================================= - -void DPlayerMenu::PickPlayerClass() -{ - int pclass = 0; - // [GRB] Pick a class from player class list - if (PlayerClasses.Size () > 1) - { - pclass = players[consoleplayer].userinfo.GetPlayerClassNum(); - - if (pclass < 0) - { - pclass = (MenuTime>>7) % PlayerClasses.Size (); - } - } - PlayerClassIndex = pclass; - PlayerClass = &PlayerClasses[PlayerClassIndex]; - UpdateTranslation(); -} +EXTERN_CVAR(Bool, cl_run) //============================================================================= // @@ -292,7 +61,7 @@ void DPlayerMenu::PickPlayerClass() DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(r); PARAM_INT(g); PARAM_INT(b); @@ -308,87 +77,6 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) } -//============================================================================= -// -// done -// -//============================================================================= - -void DPlayerMenu::UpdateColorsets() -{ - DMenuItemBase *li = GetItem(NAME_Color); - if (li != NULL) - { - int sel = 0; - EnumColorSets(PlayerClass->Type, &PlayerColorSets); - li->SetString(0, "Custom"); - for(unsigned i=0;iType, PlayerColorSets[i]); - li->SetString(i+1, colorset->Name); - } - int mycolorset = players[consoleplayer].userinfo.GetColorSet(); - if (mycolorset != -1) - { - for(unsigned i=0;iSetValue(0, sel); - } -} - -//============================================================================= -// -// done -// -//============================================================================= - -void DPlayerMenu::UpdateSkins() -{ - int sel = 0; - int skin; - DMenuItemBase *li = GetItem(NAME_Skin); - if (li != NULL) - { - if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || - players[consoleplayer].userinfo.GetPlayerClassNum() == -1) - { - li->SetString(0, "Base"); - li->SetValue(0, 0); - skin = 0; - } - else - { - PlayerSkins.Clear(); - for (unsigned i = 0; i < Skins.Size(); i++) - { - if (PlayerClass->CheckSkin(i)) - { - int j = PlayerSkins.Push(i); - li->SetString(j, Skins[i].Name); - if (players[consoleplayer].userinfo.GetSkin() == i) - { - sel = j; - } - } - } - li->SetValue(0, sel); - skin = PlayerSkins[sel]; - } - li = GetItem(NAME_Playerdisplay); - if (li != NULL) - { - li->SetValue(ListMenuItemPlayerDisplay_PDF_SKIN, skin); - } - } - UpdateTranslation(); -} - //============================================================================= // // access to the player config is done natively, so that broader access @@ -398,7 +86,7 @@ void DPlayerMenu::UpdateSkins() DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_STRING(s); const char *pp = s; FString command("name \""); @@ -428,7 +116,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(sel); if (self == DMenu::CurrentMenu) { @@ -448,7 +136,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(sel); PARAM_POINTER(cls, FPlayerClass); if (self == DMenu::CurrentMenu) @@ -468,7 +156,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(sel); if (self == DMenu::CurrentMenu) { @@ -486,7 +174,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_FLOAT(val); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -504,7 +192,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, TeamChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(val); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -522,7 +210,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, TeamChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, GenderChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -540,7 +228,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, GenderChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, SwitchOnPickupChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -558,7 +246,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SwitchOnPickupChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, AlwaysRunChanged) { - PARAM_SELF_PROLOGUE(DPlayerMenu); + PARAM_SELF_PROLOGUE(DListMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -567,10 +255,3 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AlwaysRunChanged) } return 0; } - - -DEFINE_FIELD(DPlayerMenu, mRotation) -DEFINE_FIELD_NAMED(DPlayerMenu, PlayerClass, mPlayerClass) -DEFINE_FIELD(DPlayerMenu, PlayerColorSets) -DEFINE_FIELD_NAMED(DPlayerMenu, PlayerSkins, mPlayerSkins) -DEFINE_FIELD(DPlayerMenu, PlayerClassIndex) diff --git a/src/p_user.cpp b/src/p_user.cpp index 0d69810d9..53e27c0f5 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -701,6 +701,25 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetSkin) ACTION_RETURN_INT(self->userinfo.GetSkin()); } +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetGender) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_INT(self->userinfo.GetGender()); +} + +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetAutoaim) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_FLOAT(self->userinfo.GetAutoaim()); +} + +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetTeam) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_INT(self->userinfo.GetTeam()); +} + + //=========================================================================== // // APlayerPawn diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 3550a78c9..4fb167f56 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -57,6 +57,7 @@ #include "v_video.h" #include "c_bind.h" #include "menu/menu.h" +#include "teaminfo.h" #include "r_data/sprites.h" static TArray properties; @@ -764,6 +765,10 @@ void InitThingdef() playerskinstruct->Size = sizeof(FPlayerSkin); playerskinstruct->Align = alignof(FPlayerSkin); + auto teamstruct = NewNativeStruct("Team", nullptr); + teamstruct->Size = sizeof(FTeam); + teamstruct->Align = alignof(FTeam); + // set up the lines array in the sector struct. This is a bit messy because the type system is not prepared to handle a pointer to an array of pointers to a native struct even remotely well... // As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up. sectorstruct->AddNativeField("lines", NewPointer(NewResizableArray(NewPointer(linestruct, false)), false), myoffsetof(sector_t, Lines), VARF_Native); @@ -807,6 +812,10 @@ void InitThingdef() PField *plrsknf = new PField("PlayerSkins", plrskn, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Skins); Namespaces.GlobalNamespace->Symbols.AddSymbol(plrsknf); + auto teamst = NewPointer(NewResizableArray(teamstruct), false); + PField *teamf = new PField("Teams", teamst, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Teams); + Namespaces.GlobalNamespace->Symbols.AddSymbol(teamf); + auto bindcls = NewNativeStruct("KeyBindings", nullptr); PField *binding = new PField("Bindings", bindcls, VARF_Native | VARF_Static, (intptr_t)&Bindings); Namespaces.GlobalNamespace->Symbols.AddSymbol(binding); diff --git a/src/teaminfo.cpp b/src/teaminfo.cpp index 38ba56f4c..18a2580e2 100644 --- a/src/teaminfo.cpp +++ b/src/teaminfo.cpp @@ -333,3 +333,6 @@ CCMD (teamlist) Printf ("End of team list.\n"); } + + +DEFINE_FIELD_NAMED(FTeam, m_Name, mName) \ No newline at end of file diff --git a/src/teaminfo.h b/src/teaminfo.h index 41408b546..1c84d9b9b 100644 --- a/src/teaminfo.h +++ b/src/teaminfo.h @@ -63,7 +63,9 @@ private: void ParseTeamDefinition (FScanner &Scan); void ClearTeams (); +public: // needed for script access. FString m_Name; +private: int m_iPlayerColor; FString m_TextColor; FString m_Logo; diff --git a/wadsrc/static/zscript/menu/playermenu.txt b/wadsrc/static/zscript/menu/playermenu.txt index 4fbc91620..4502cc9fa 100644 --- a/wadsrc/static/zscript/menu/playermenu.txt +++ b/wadsrc/static/zscript/menu/playermenu.txt @@ -1,11 +1,45 @@ +/* +** 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 PlayerMenu : ListMenu native +class PlayerMenu : ListMenu { - native int mRotation; - native int PlayerClassIndex; - native PlayerClass mPlayerClass; - native Array PlayerColorSets; - native Array mPlayerSkins; + int mRotation; + int PlayerClassIndex; + PlayerClass mPlayerClass; + Array PlayerColorSets; + Array mPlayerSkins; // All write function for the player config are native to prevent abuse. protected native void AutoaimChanged(float val); @@ -19,6 +53,12 @@ class PlayerMenu : ListMenu native protected native void SkinChanged (int val); protected native void ClassChanged(int sel, PlayerClass cls); + //============================================================================= + // + // + // + //============================================================================= + protected void UpdateTranslation() { Translation.SetPlayerTranslation(TRANSLATION_Players, MAXPLAYERS, consoleplayer, mPlayerClass); @@ -30,6 +70,133 @@ class PlayerMenu : ListMenu native UpdateTranslation(); } + //============================================================================= + // + // + // + //============================================================================= + + override void Init(Menu parent, ListMenuDescriptor desc) + { + MenuItemBase li; + PlayerInfo p = players[consoleplayer]; + + Super.Init(parent, desc); + PickPlayerClass(); + mRotation = 0; + + li = GetItem('Playerdisplay'); + if (li != NULL) + { + li.SetValue(ListMenuItemPlayerDisplay.PDF_ROTATION, 0); + li.SetValue(ListMenuItemPlayerDisplay.PDF_MODE, 1); + li.SetValue(ListMenuItemPlayerDisplay.PDF_TRANSLATE, 1); + li.SetValue(ListMenuItemPlayerDisplay.PDF_CLASS, p.GetPlayerClassNum()); + if (mPlayerClass != NULL && !(GetDefaultByType (mPlayerClass.Type).bNoSkin) && + p.GetPlayerClassNum() != -1) + { + li.SetValue(ListMenuItemPlayerDisplay.PDF_SKIN, p.GetSkin()); + } + } + + li = GetItem('Playerbox'); + if (li != NULL) + { + li.SetString(0, p.GetUserName()); + } + + li = GetItem('Team'); + if (li != NULL) + { + li.SetString(0, "None"); + for(int i=0;i= 0 ? pclass : pclass + 1); + } + } + + UpdateSkins(); + + li = GetItem('Gender'); + if (li != NULL) + { + li.SetValue(0, p.GetGender()); + } + + li = GetItem('Autoaim'); + if (li != NULL) + { + li.SetValue(0, int(p.GetAutoaim())); + } + + li = GetItem('Switch'); + if (li != NULL) + { + li.SetValue(0, p.GetNeverSwitch()); + } + + li = GetItem('AlwaysRun'); + if (li != NULL) + { + li.SetValue(0, cl_run); + } + + if (mDesc.mSelectedItem < 0) mDesc.mSelectedItem = 1; + + } + + //============================================================================= // // @@ -199,6 +366,28 @@ class PlayerMenu : ListMenu native } + //============================================================================= + // + // + // + //============================================================================= + + override bool Responder (InputEventData ev) + { + if (ev.type == InputEventData.GUI_Event && ev.subtype == InputEventData.GUI_Char && ev.data1 == 32) + { + // turn the player sprite around + mRotation = 8 - mRotation; + MenuItemBase li = GetItem('Playerdisplay'); + if (li != NULL) + { + li.SetValue(ListMenuItemPlayerDisplay.PDF_ROTATION, mRotation); + } + return true; + } + return Super.Responder(ev); + } + //============================================================================= // // diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index f7333220b..8886e6744 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -317,6 +317,9 @@ usercmd_t original_cmd; native int GetPlayerClassNum(); native int GetSkin(); native bool GetNeverSwitch(); + native int GetGender(); + native int GetTeam(); + native float GetAutoaim(); } struct PlayerClass native @@ -343,3 +346,10 @@ struct PlayerSkin native native readonly int crouchsprite; native readonly int namespc; }; + +struct Team native +{ + const NoTeam = 255; + const Max = 16; + native String mName; +} From 013e52fabdac535bf17dbb64a1d2e8db1726313d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 01:31:01 +0100 Subject: [PATCH 12/12] - fixed: newly created list menus did not call their scripted virtual Init method. --- src/menu/menu.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index c5b1b4071..f32c20373 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -630,7 +630,11 @@ void M_SetMenu(FName menu, int param) if (cls == nullptr) cls = PClass::FindClass("ListMenu"); DListMenu *newmenu = (DListMenu *)cls->CreateNew(); - newmenu->Init(DMenu::CurrentMenu, ld); + IFVIRTUALPTRNAME(newmenu, "OptionMenu", Init) + { + VMValue params[3] = { newmenu, DMenu::CurrentMenu, ld }; + GlobalVMStack.Call(func, params, 3, nullptr, 0); + } M_ActivateMenu(newmenu); } }