made it possible to change the skin ingame. closes #2063

This commit is contained in:
oy 2019-03-22 20:04:57 +01:00
parent d436fdb426
commit 975baecb3d
11 changed files with 154 additions and 8 deletions

View file

@ -334,6 +334,13 @@ Messages = [
NetBool("m_Silent"),
]),
NetMessage("Sv_SkinChange", [
NetIntRange("m_ClientID", 0, 'MAX_CLIENTS-1'),
NetArray(NetStringStrict("m_apSkinPartNames"), 6),
NetArray(NetBool("m_aUseCustomColors"), 6),
NetArray(NetIntAny("m_aSkinPartColors"), 6),
]),
NetMessage("Sv_GameInfo", [
NetFlag("m_GameFlags", GameFlags),
@ -390,6 +397,12 @@ Messages = [
NetArray(NetIntAny("m_aSkinPartColors"), 6),
]),
NetMessage("Cl_SkinChange", [
NetArray(NetStringStrict("m_apSkinPartNames"), 6),
NetArray(NetBool("m_aUseCustomColors"), 6),
NetArray(NetIntAny("m_aSkinPartColors"), 6),
]),
NetMessage("Cl_Kill", []),
NetMessage("Cl_ReadyChange", []),

View file

@ -32,6 +32,7 @@ public:
virtual bool ClientIngame(int ClientID) const = 0;
virtual int GetClientInfo(int ClientID, CClientInfo *pInfo) const = 0;
virtual void GetClientAddr(int ClientID, char *pAddrStr, int Size) const = 0;
virtual int GetClientVersion(int ClientID) const = 0;
virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) = 0;

View file

@ -414,6 +414,12 @@ void CServer::GetClientAddr(int ClientID, char *pAddrStr, int Size) const
net_addr_str(m_NetServer.ClientAddr(ClientID), pAddrStr, Size, false);
}
int CServer::GetClientVersion(int ClientID) const
{
if(ClientID >= 0 && ClientID < MAX_CLIENTS && m_aClients[ClientID].m_State == CClient::STATE_INGAME)
return m_aClients[ClientID].m_Version;
return 0;
}
const char *CServer::ClientName(int ClientID) const
{

View file

@ -218,6 +218,7 @@ public:
bool IsBanned(int ClientID);
int GetClientInfo(int ClientID, CClientInfo *pInfo) const;
void GetClientAddr(int ClientID, char *pAddrStr, int Size) const;
int GetClientVersion(int ClientID) const;
const char *ClientName(int ClientID) const;
const char *ClientClan(int ClientID) const;
int ClientCountry(int ClientID) const;

View file

@ -52,7 +52,6 @@ CMenus::CMenus()
m_NeedRestartGraphics = false;
m_NeedRestartSound = false;
m_NeedRestartPlayer = false;
m_NeedRestartTee = false;
m_TeePartSelected = SKINPART_BODY;
m_aSaveSkinName[0] = 0;
m_RefreshSkinSelector = true;
@ -61,6 +60,7 @@ CMenus::CMenus()
m_SeekBarActivatedTime = 0;
m_SeekBarActive = true;
m_UseMouseButtons = true;
m_SkinModified = false;
SetMenuPage(PAGE_START);
m_MenuPageOld = PAGE_START;
@ -2429,11 +2429,20 @@ void CMenus::SetActive(bool Active)
if(Client()->State() == IClient::STATE_ONLINE)
{
m_pClient->OnRelease();
if(Client()->State() == IClient::STATE_ONLINE && m_SkinModified)
{
m_SkinModified = false;
m_pClient->SendSkinChange();
}
}
}
else if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
else
{
m_pClient->OnRelease();
m_SkinModified = false;
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
{
m_pClient->OnRelease();
}
}
}

View file

@ -297,6 +297,7 @@ private:
vec2 m_PrevMousePos;
bool m_PopupActive;
int m_ActiveListBox;
bool m_SkinModified;
// images
struct CMenuImage
@ -371,7 +372,6 @@ private:
// for settings
bool m_NeedRestartPlayer;
bool m_NeedRestartTee;
bool m_NeedRestartGraphics;
bool m_NeedRestartSound;
int m_TeePartSelected;

View file

@ -170,7 +170,10 @@ void CMenus::RenderHSLPicker(CUIRect MainView)
MainView.HSplitTop(ButtonHeight, &Button, &MainView);
static int s_CustomColors = 0;
if(DoButton_CheckBox(&s_CustomColors, Localize("Custom colors"), *CSkins::ms_apUCCVariables[m_TeePartSelected], &Button))
{
*CSkins::ms_apUCCVariables[m_TeePartSelected] ^= 1;
m_SkinModified = true;
}
if(!(*CSkins::ms_apUCCVariables[m_TeePartSelected]))
return;
@ -404,6 +407,7 @@ void CMenus::RenderHSLPicker(CUIRect MainView)
}
if(UseAlpha)
g_Config.m_PlayerColorMarking = (Alp << 24) + NewVal;
m_SkinModified = true;
}
}
@ -477,6 +481,7 @@ void CMenus::RenderSkinSelection(CUIRect MainView)
*CSkins::ms_apUCCVariables[p] = m_pSelectedSkin->m_aUseCustomColors[p];
*CSkins::ms_apColorVariables[p] = m_pSelectedSkin->m_aPartColors[p];
}
m_SkinModified = true;
}
}
OldSelected = NewSelected;
@ -560,6 +565,7 @@ void CMenus::RenderSkinPartSelection(CUIRect MainView)
const CSkins::CSkinPart *s = s_paList[m_TeePartSelected][NewSelected];
mem_copy(CSkins::ms_apSkinVariables[m_TeePartSelected], s->m_aName, 24);
g_Config.m_PlayerSkin[0] = 0;
m_SkinModified = true;
}
}
OldSelected = NewSelected;
@ -1409,7 +1415,6 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
else
s_CustomSkinMenu = true;
}
m_NeedRestartTee = str_comp(g_Config.m_PlayerSkin, s_aPlayerSkin);
}
//typedef void (*pfnAssignFuncCallback)(CConfiguration *pConfig, int Value);
@ -1990,7 +1995,7 @@ void CMenus::RenderSettings(CUIRect MainView)
MainView.HSplitBottom(32.0f, 0, &MainView);
// reset warning
bool NeedReconnect = (m_NeedRestartPlayer || m_NeedRestartTee) && this->Client()->State() == IClient::STATE_ONLINE;
bool NeedReconnect = (m_NeedRestartPlayer || (m_SkinModified && m_pClient->m_LastSkinChangeTime + 6.0f > Client()->LocalTime())) && this->Client()->State() == IClient::STATE_ONLINE;
if(m_NeedRestartGraphics || m_NeedRestartSound || NeedReconnect)
{
// background
@ -2004,8 +2009,17 @@ void CMenus::RenderSettings(CUIRect MainView)
RestartWarning.y += 2.0f;
if(m_NeedRestartGraphics || m_NeedRestartSound)
UI()->DoLabel(&RestartWarning, Localize("You must restart the game for all settings to take effect."), RestartWarning.h*ms_FontmodHeight*0.75f, CUI::ALIGN_CENTER);
else if(NeedReconnect)
UI()->DoLabel(&RestartWarning, Localize("You must reconnect to change identity."), RestartWarning.h*ms_FontmodHeight*0.75f, CUI::ALIGN_CENTER);
else if(Client()->State() == IClient::STATE_ONLINE)
{
if(m_NeedRestartPlayer)
UI()->DoLabel(&RestartWarning, Localize("You must reconnect to change identity."), RestartWarning.h*ms_FontmodHeight*0.75f, CUI::ALIGN_CENTER);
else if(m_SkinModified)
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), Localize("You have to wait %1.f seconds to change identity."), m_pClient->m_LastSkinChangeTime+6.5f - Client()->LocalTime());
UI()->DoLabel(&RestartWarning, aBuf, RestartWarning.h*ms_FontmodHeight*0.75f, CUI::ALIGN_CENTER);
}
}
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
}

View file

@ -246,6 +246,25 @@ void CGameClient::OnConsoleInit()
Console()->Chain("add_friend", ConchainFriendUpdate, this);
Console()->Chain("remove_friend", ConchainFriendUpdate, this);
Console()->Chain("cl_show_xmas_hats", ConchainXmasHatUpdate, this);
Console()->Chain("player_color_body", ConchainSkinChange, this);
Console()->Chain("player_color_marking", ConchainSkinChange, this);
Console()->Chain("player_color_decoration", ConchainSkinChange, this);
Console()->Chain("player_color_hands", ConchainSkinChange, this);
Console()->Chain("player_color_feet", ConchainSkinChange, this);
Console()->Chain("player_color_eyes", ConchainSkinChange, this);
Console()->Chain("player_use_custom_color_body", ConchainSkinChange, this);
Console()->Chain("player_use_custom_color_marking", ConchainSkinChange, this);
Console()->Chain("player_use_custom_color_decoration", ConchainSkinChange, this);
Console()->Chain("player_use_custom_color_hands", ConchainSkinChange, this);
Console()->Chain("player_use_custom_color_feet", ConchainSkinChange, this);
Console()->Chain("player_use_custom_color_eyes", ConchainSkinChange, this);
Console()->Chain("player_skin", ConchainSkinChange, this);
Console()->Chain("player_skin_body", ConchainSkinChange, this);
Console()->Chain("player_skin_marking", ConchainSkinChange, this);
Console()->Chain("player_skin_decoration", ConchainSkinChange, this);
Console()->Chain("player_skin_hands", ConchainSkinChange, this);
Console()->Chain("player_skin_feet", ConchainSkinChange, this);
Console()->Chain("player_skin_eyes", ConchainSkinChange, this);
for(int i = 0; i < m_All.m_Num; i++)
m_All.m_paComponents[i]->m_pClient = this;
@ -384,6 +403,7 @@ void CGameClient::OnReset()
m_LocalClientID = -1;
m_TeamCooldownTick = 0;
m_TeamChangeTime = 0.0f;
m_LastSkinChangeTime = Client()->LocalTime();
mem_zero(&m_GameInfo, sizeof(m_GameInfo));
m_DemoSpecMode = SPEC_FREEVIEW;
m_DemoSpecID = -1;
@ -716,6 +736,26 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker)
m_aClients[pMsg->m_ClientID].Reset(this, pMsg->m_ClientID);
}
else if(MsgId == NETMSGTYPE_SV_SKINCHANGE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
{
Client()->RecordGameMessage(false);
CNetMsg_Sv_SkinChange *pMsg = (CNetMsg_Sv_SkinChange *)pRawMsg;
if(!m_aClients[pMsg->m_ClientID].m_Active)
{
if(g_Config.m_Debug)
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", "invalid skin info");
return;
}
for(int i = 0; i < 6; i++)
{
str_copy(m_aClients[pMsg->m_ClientID].m_aaSkinPartNames[i], pMsg->m_apSkinPartNames[i], 24);
m_aClients[pMsg->m_ClientID].m_aUseCustomColors[i] = pMsg->m_aUseCustomColors[i];
m_aClients[pMsg->m_ClientID].m_aSkinPartColors[i] = pMsg->m_aSkinPartColors[i];
}
m_aClients[pMsg->m_ClientID].UpdateRenderInfo(this, pMsg->m_ClientID, true);
}
else if(MsgId == NETMSGTYPE_SV_GAMEINFO && Client()->State() != IClient::STATE_DEMOPLAYBACK)
{
Client()->RecordGameMessage(false);
@ -1493,6 +1533,19 @@ void CGameClient::SendReadyChange()
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
}
void CGameClient::SendSkinChange()
{
CNetMsg_Cl_SkinChange Msg;
for(int p = 0; p < NUM_SKINPARTS; p++)
{
Msg.m_apSkinPartNames[p] = CSkins::ms_apSkinVariables[p];
Msg.m_aUseCustomColors[p] = *CSkins::ms_apUCCVariables[p];
Msg.m_aSkinPartColors[p] = *CSkins::ms_apColorVariables[p];
}
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_NORECORD|MSGFLAG_FLUSH);
m_LastSkinChangeTime = Client()->LocalTime();
}
void CGameClient::ConTeam(IConsole::IResult *pResult, void *pUserData)
{
CGameClient *pClient = static_cast<CGameClient *>(pUserData);
@ -1523,6 +1576,13 @@ void CGameClient::ConReadyChange(IConsole::IResult *pResult, void *pUserData)
if(pClient->Client()->State() == IClient::STATE_ONLINE)
pClient->SendReadyChange();
}
void CGameClient::ConchainSkinChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
{
pfnCallback(pResult, pCallbackUserData);
CGameClient *pClient = static_cast<CGameClient *>(pUserData);
if(pClient->Client()->State() == IClient::STATE_ONLINE && pResult->NumArguments())
pClient->SendSkinChange();
}
void CGameClient::ConchainFriendUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)

View file

@ -59,6 +59,7 @@ class CGameClient : public IGameClient
static void ConTeam(IConsole::IResult *pResult, void *pUserData);
static void ConKill(IConsole::IResult *pResult, void *pUserData);
static void ConReadyChange(IConsole::IResult *pResult, void *pUserData);
static void ConchainSkinChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainFriendUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainXmasHatUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
@ -197,6 +198,7 @@ public:
bool m_MuteServerBroadcast;
float m_TeamChangeTime;
bool m_IsXmasDay;
float m_LastSkinChangeTime;
struct CGameInfo
{
@ -265,6 +267,7 @@ public:
void SendStartInfo();
void SendKill();
void SendReadyChange();
void SendSkinChange();
// pointers to all systems
class CGameConsole *m_pGameConsole;

View file

@ -279,6 +279,18 @@ void CGameContext::SendSettings(int ClientID)
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID);
}
void CGameContext::SendSkinChange(int ClientID)
{
CNetMsg_Sv_SkinChange Msg;
Msg.m_ClientID = ClientID;
for(int p = 0; p < 6; p++)
{
Msg.m_apSkinPartNames[p] = m_apPlayers[ClientID]->m_TeeInfos.m_aaSkinPartNames[p];
Msg.m_aUseCustomColors[p] = m_apPlayers[ClientID]->m_TeeInfos.m_aUseCustomColors[p];
Msg.m_aSkinPartColors[p] = m_apPlayers[ClientID]->m_TeeInfos.m_aSkinPartColors[p];
}
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_NORECORD, ClientID);
}
void CGameContext::SendGameMsg(int GameMsgID, int ClientID)
{
@ -980,6 +992,30 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
pPlayer->m_LastReadyChange = Server()->Tick();
m_pController->OnPlayerReadyChange(pPlayer);
}
else if(MsgID == NETMSGTYPE_CL_SKINCHANGE)
{
if(pPlayer->m_LastChangeInfo && pPlayer->m_LastChangeInfo+Server()->TickSpeed()*5 > Server()->Tick())
return;
pPlayer->m_LastChangeInfo = Server()->Tick();
CNetMsg_Cl_SkinChange *pMsg = (CNetMsg_Cl_SkinChange *)pRawMsg;
for(int p = 0; p < 6; p++)
{
str_copy(pPlayer->m_TeeInfos.m_aaSkinPartNames[p], pMsg->m_apSkinPartNames[p], 24);
pPlayer->m_TeeInfos.m_aUseCustomColors[p] = pMsg->m_aUseCustomColors[p];
pPlayer->m_TeeInfos.m_aSkinPartColors[p] = pMsg->m_aSkinPartColors[p];
}
// update all clients
for(int i = 0; i < MAX_CLIENTS; ++i)
{
if(!m_apPlayers[i] || (!Server()->ClientIngame(i) && !m_apPlayers[i]->IsDummy()) || Server()->GetClientVersion(i) < MIN_SKINCHANGE_CLIENTVERSION)
continue;
SendSkinChange(i);
}
}
}
else
{

View file

@ -119,6 +119,8 @@ public:
VOTE_TIME=25,
VOTE_CANCEL_TIME = 10,
MIN_SKINCHANGE_CLIENTVERSION = 0x0703,
};
class CHeap *m_pVoteOptionHeap;
CVoteOptionServer *m_pVoteOptionFirst;
@ -139,6 +141,7 @@ public:
void SendWeaponPickup(int ClientID, int Weapon);
void SendMotd(int ClientID);
void SendSettings(int ClientID);
void SendSkinChange(int ClientID);
void SendGameMsg(int GameMsgID, int ClientID);
void SendGameMsg(int GameMsgID, int ParaI1, int ClientID);