mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-16 17:31:50 +00:00
595 lines
14 KiB
Text
595 lines
14 KiB
Text
/*
|
|
** 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
|
|
{
|
|
int mRotation;
|
|
int PlayerClassIndex;
|
|
PlayerClass mPlayerClass;
|
|
Array<int> PlayerColorSets;
|
|
Array<int> mPlayerSkins;
|
|
|
|
// 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 SkinChanged (int val);
|
|
protected native void ClassChanged(int sel, PlayerClass cls);
|
|
|
|
//=============================================================================
|
|
//
|
|
//
|
|
//
|
|
//=============================================================================
|
|
|
|
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 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<Teams.Size(); i++)
|
|
{
|
|
li.SetString(i+1, Teams[i].mName);
|
|
}
|
|
int myteam = players[consoleplayer].GetTeam();
|
|
li.SetValue(0, myteam == Team.NoTeam? 0 : myteam + 1);
|
|
}
|
|
|
|
int mycolorset = p.GetColorSet();
|
|
Color colr = p.GetColor();
|
|
|
|
UpdateColorsets();
|
|
|
|
li = GetItem('Red');
|
|
if (li != NULL)
|
|
{
|
|
li.Enable(mycolorset == -1);
|
|
li.SetValue(0, colr.r);
|
|
}
|
|
|
|
li = GetItem('Green');
|
|
if (li != NULL)
|
|
{
|
|
li.Enable(mycolorset == -1);
|
|
li.SetValue(0, colr.g);
|
|
}
|
|
|
|
li = GetItem('Blue');
|
|
if (li != NULL)
|
|
{
|
|
li.Enable(mycolorset == -1);
|
|
li.SetValue(0, colr.b);
|
|
}
|
|
|
|
li = GetItem('Class');
|
|
if (li != NULL)
|
|
{
|
|
if (PlayerClasses.Size() == 1)
|
|
{
|
|
li.SetString(0, PlayerPawn.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(int i=0; i< PlayerClasses.Size(); i++)
|
|
{
|
|
let cls = PlayerPawn.GetPrintableDisplayName(PlayerClasses[i].Type);
|
|
li.SetString(gameinfo.norandomplayerclass ? i : i+1, cls);
|
|
}
|
|
int pclass = p.GetPlayerClassNum();
|
|
li.SetValue(0, gameinfo.norandomplayerclass && pclass >= 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;
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
//
|
|
//
|
|
//
|
|
//=============================================================================
|
|
|
|
protected void PickPlayerClass(int pick = -100)
|
|
{
|
|
int pclass = 0;
|
|
// [GRB] Pick a class from player class list
|
|
if (PlayerClasses.Size () > 1)
|
|
{
|
|
pclass = pick == -100? players[consoleplayer].GetPlayerClassNum() : pick;
|
|
|
|
if (pclass < 0)
|
|
{
|
|
pclass = (MenuTime() >> 7) % PlayerClasses.Size ();
|
|
}
|
|
}
|
|
PlayerClassIndex = pclass;
|
|
mPlayerClass = PlayerClasses[PlayerClassIndex];
|
|
UpdateTranslation();
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//
|
|
//
|
|
//=============================================================================
|
|
|
|
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;
|
|
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();
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//
|
|
//
|
|
//=============================================================================
|
|
|
|
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)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool res;
|
|
int sel;
|
|
|
|
[res, sel] = li.GetValue(0);
|
|
if (res)
|
|
{
|
|
sel = mPlayerSkins[sel];
|
|
SkinChanged(sel);
|
|
UpdateTranslation();
|
|
|
|
li = GetItem('Playerdisplay');
|
|
if (li != NULL)
|
|
{
|
|
li.SetValue(ListMenuItemPlayerDisplay.PDF_SKIN, sel);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
//
|
|
//
|
|
//
|
|
//=============================================================================
|
|
|
|
override bool OnUIEvent(UIEvent ev)
|
|
{
|
|
if (ev.Type == UIEvent.Type_Char && ev.KeyChar == 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.OnUIEvent(ev);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//
|
|
//
|
|
//=============================================================================
|
|
|
|
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)
|
|
{
|
|
ChangeClass(li);
|
|
}
|
|
break;
|
|
|
|
case 'Skin':
|
|
ChangeSkin(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;
|
|
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;
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
//
|
|
//
|
|
//
|
|
//=============================================================================
|
|
|
|
override void Drawer ()
|
|
{
|
|
Super.Drawer();
|
|
String str = Stringtable.Localize("$PLYRMNU_PRESSSPACE");
|
|
screen.DrawText (SmallFont, Font.CR_GOLD, 320 - 32 - 32 - SmallFont.StringWidth (str)/2, 130, str, DTA_Clean, true);
|
|
str = Stringtable.Localize(mRotation ? "$PLYRMNU_SEEFRONT" : "$PLYRMNU_SEEBACK");
|
|
screen.DrawText (SmallFont, Font.CR_GOLD, 320 - 32 - 32 - SmallFont.StringWidth (str)/2, 130 + SmallFont.GetHeight (), str, DTA_Clean, true);
|
|
|
|
}
|
|
|
|
}
|