From 5b1c866b357e913ce8960f1e1203abee0016c566 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 10 May 2014 14:31:00 +0200 Subject: [PATCH] Feature: Separate inputs for dummy and player --- src/engine/client/client.cpp | 35 +++-- src/engine/client/client.h | 4 +- src/game/client/components/camera.cpp | 8 +- src/game/client/components/controls.cpp | 183 ++++++++++++---------- src/game/client/components/controls.h | 14 +- src/game/client/components/hud.cpp | 2 +- src/game/client/components/nameplates.cpp | 2 +- src/game/client/components/players.cpp | 6 +- 8 files changed, 137 insertions(+), 117 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index e11a3c454..e4ae3cc99 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -305,7 +305,8 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta), m_DemoRecorder(&m_SnapshotD m_CurrentServerInfoRequestTime = -1; - m_CurrentInput = 0; + m_CurrentInput[0] = 0; + m_CurrentInput[1] = 0; m_LastDummy = 0; m_LastDummy2 = 0; m_LocalIDs[0] = 0; @@ -440,7 +441,7 @@ void CClient::SendInput() return; // fetch input - int Size = GameClient()->OnSnapInput(m_aInputs[m_CurrentInput].m_aData); + int Size = GameClient()->OnSnapInput(m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_aData); if(Size) { @@ -450,22 +451,22 @@ void CClient::SendInput() Msg.AddInt(m_PredTick[g_Config.m_ClDummy]); Msg.AddInt(Size); - m_aInputs[m_CurrentInput].m_Tick = m_PredTick[g_Config.m_ClDummy]; - m_aInputs[m_CurrentInput].m_PredictedTime = m_PredictedTime.Get(Now); - m_aInputs[m_CurrentInput].m_Time = Now; + m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_Tick = m_PredTick[g_Config.m_ClDummy]; + m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_PredictedTime = m_PredictedTime.Get(Now); + m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_Time = Now; // pack it for(int i = 0; i < Size/4; i++) - Msg.AddInt(m_aInputs[m_CurrentInput].m_aData[i]); + Msg.AddInt(m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_aData[i]); - m_CurrentInput++; - m_CurrentInput%=200; + m_CurrentInput[g_Config.m_ClDummy]++; + m_CurrentInput[g_Config.m_ClDummy]%=200; SendMsgEx(&Msg, MSGFLAG_FLUSH); if(m_LastDummy != g_Config.m_ClDummy) { - mem_copy(&DummyInput, &m_aInputs[(m_CurrentInput+200-2)%200], sizeof(DummyInput)); + mem_copy(&DummyInput, &m_aInputs[!g_Config.m_ClDummy][(m_CurrentInput[!g_Config.m_ClDummy]+200-2)%200], sizeof(DummyInput)); m_LastDummy = g_Config.m_ClDummy; } } @@ -544,12 +545,12 @@ int *CClient::GetInput(int Tick) int Best = -1; for(int i = 0; i < 200; i++) { - if(m_aInputs[i].m_Tick <= Tick && (Best == -1 || m_aInputs[Best].m_Tick < m_aInputs[i].m_Tick)) + if(m_aInputs[g_Config.m_ClDummy][i].m_Tick <= Tick && (Best == -1 || m_aInputs[g_Config.m_ClDummy][Best].m_Tick < m_aInputs[g_Config.m_ClDummy][i].m_Tick)) Best = i; } if(Best != -1) - return (int *)m_aInputs[Best].m_aData; + return (int *)m_aInputs[g_Config.m_ClDummy][Best].m_aData; return 0; } @@ -577,8 +578,12 @@ void CClient::OnEnterGame() // reset input int i; for(i = 0; i < 200; i++) - m_aInputs[i].m_Tick = -1; - m_CurrentInput = 0; + { + m_aInputs[0][i].m_Tick = -1; + m_aInputs[1][i].m_Tick = -1; + } + m_CurrentInput[0] = 0; + m_CurrentInput[1] = 0; // reset snapshots m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = 0; @@ -1508,9 +1513,9 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) int64 Target = 0; for(int k = 0; k < 200; k++) { - if(m_aInputs[k].m_Tick == InputPredTick) + if(m_aInputs[g_Config.m_ClDummy][k].m_Tick == InputPredTick) { - Target = m_aInputs[k].m_PredictedTime + (Now - m_aInputs[k].m_Time); + Target = m_aInputs[g_Config.m_ClDummy][k].m_PredictedTime + (Now - m_aInputs[g_Config.m_ClDummy][k].m_Time); Target = Target - (int64)(((TimeLeft-PREDICTION_MARGIN)/1000.0f)*time_freq()); break; } diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 2f7c11f72..dcb474f69 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -142,9 +142,9 @@ class CClient : public IClient, public CDemoPlayer::IListner int m_Tick; // the tick that the input is for int64 m_PredictedTime; // prediction latency when we sent this input int64 m_Time; - } m_aInputs[200]; + } m_aInputs[2][200]; - int m_CurrentInput; + int m_CurrentInput[2]; bool m_LastDummy; bool m_LastDummy2; CNetObj_PlayerInput DummyInput; diff --git a/src/game/client/components/camera.cpp b/src/game/client/components/camera.cpp index dc6e8a4ef..b4b86d14e 100644 --- a/src/game/client/components/camera.cpp +++ b/src/game/client/components/camera.cpp @@ -31,11 +31,11 @@ void CCamera::OnRender() { if(m_CamType != CAMTYPE_SPEC) { - m_pClient->m_pControls->m_MousePos = m_PrevCenter; + m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy] = m_PrevCenter; m_pClient->m_pControls->ClampMousePos(); m_CamType = CAMTYPE_SPEC; } - m_Center = m_pClient->m_pControls->m_MousePos; + m_Center = m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy]; } else { @@ -47,14 +47,14 @@ void CCamera::OnRender() vec2 CameraOffset(0, 0); - float l = length(m_pClient->m_pControls->m_MousePos); + float l = length(m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy]); if(l > 0.0001f) // make sure that this isn't 0 { float DeadZone = g_Config.m_ClMouseDeadzone; float FollowFactor = g_Config.m_ClMouseFollowfactor/100.0f; float OffsetAmount = max(l-DeadZone, 0.0f) * FollowFactor; - CameraOffset = normalize(m_pClient->m_pControls->m_MousePos)*OffsetAmount; + CameraOffset = normalize(m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy])*OffsetAmount; } if(m_pClient->m_Snap.m_SpecInfo.m_Active) diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp index 66a1e0641..c5379b923 100644 --- a/src/game/client/components/controls.cpp +++ b/src/game/client/components/controls.cpp @@ -25,17 +25,17 @@ CControls::CControls() void CControls::OnReset() { - m_LastData.m_Direction = 0; + m_LastData[g_Config.m_ClDummy].m_Direction = 0; //m_LastData.m_Hook = 0; // simulate releasing the fire button - if((m_LastData.m_Fire&1) != 0) - m_LastData.m_Fire++; - m_LastData.m_Fire &= INPUT_STATE_MASK; - m_LastData.m_Jump = 0; - m_InputData = m_LastData; + if((m_LastData[g_Config.m_ClDummy].m_Fire&1) != 0) + m_LastData[g_Config.m_ClDummy].m_Fire++; + m_LastData[g_Config.m_ClDummy].m_Fire &= INPUT_STATE_MASK; + m_LastData[g_Config.m_ClDummy].m_Jump = 0; + m_InputData[g_Config.m_ClDummy] = m_LastData[g_Config.m_ClDummy]; - m_InputDirectionLeft = 0; - m_InputDirectionRight = 0; + m_InputDirectionLeft[g_Config.m_ClDummy] = 0; + m_InputDirectionRight[g_Config.m_ClDummy] = 0; } void CControls::OnRelease() @@ -45,17 +45,34 @@ void CControls::OnRelease() void CControls::OnPlayerDeath() { - m_LastData.m_WantedWeapon = m_InputData.m_WantedWeapon = 0; + m_LastData[g_Config.m_ClDummy].m_WantedWeapon = m_InputData[g_Config.m_ClDummy].m_WantedWeapon = 0; } +struct CInputState +{ + CControls *m_pControls; + int *m_pVariable1; + int *m_pVariable2; +}; + static void ConKeyInputState(IConsole::IResult *pResult, void *pUserData) { - ((int *)pUserData)[0] = pResult->GetInteger(0); + CInputState *pState = (CInputState *)pUserData; + if (g_Config.m_ClDummy) + *pState->m_pVariable2 = pResult->GetInteger(0); + else + *pState->m_pVariable1 = pResult->GetInteger(0); } static void ConKeyInputCounter(IConsole::IResult *pResult, void *pUserData) { - int *v = (int *)pUserData; + CInputState *pState = (CInputState *)pUserData; + int *v; + if (g_Config.m_ClDummy) + v = pState->m_pVariable2; + else + v = pState->m_pVariable1; + if(((*v)&1) != pResult->GetInteger(0)) (*v)++; *v &= INPUT_STATE_MASK; @@ -64,7 +81,8 @@ static void ConKeyInputCounter(IConsole::IResult *pResult, void *pUserData) struct CInputSet { CControls *m_pControls; - int *m_pVariable; + int *m_pVariable1; + int *m_pVariable2; int m_Value; }; @@ -72,34 +90,39 @@ static void ConKeyInputSet(IConsole::IResult *pResult, void *pUserData) { CInputSet *pSet = (CInputSet *)pUserData; if(pResult->GetInteger(0)) - *pSet->m_pVariable = pSet->m_Value; + { + if (g_Config.m_ClDummy) + *pSet->m_pVariable2 = pSet->m_Value; + else + *pSet->m_pVariable1 = pSet->m_Value; + } } static void ConKeyInputNextPrevWeapon(IConsole::IResult *pResult, void *pUserData) { CInputSet *pSet = (CInputSet *)pUserData; - ConKeyInputCounter(pResult, pSet->m_pVariable); - pSet->m_pControls->m_InputData.m_WantedWeapon = 0; + ConKeyInputCounter(pResult, pSet); + pSet->m_pControls->m_InputData[g_Config.m_ClDummy].m_WantedWeapon = 0; } void CControls::OnConsoleInit() { // game commands - Console()->Register("+left", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputDirectionLeft, "Move left"); - Console()->Register("+right", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputDirectionRight, "Move right"); - Console()->Register("+jump", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputData.m_Jump, "Jump"); - Console()->Register("+hook", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputData.m_Hook, "Hook"); - Console()->Register("+fire", "", CFGFLAG_CLIENT, ConKeyInputCounter, &m_InputData.m_Fire, "Fire"); - Console()->Register("+showhookcoll", "", CFGFLAG_CLIENT, ConKeyInputState, &m_ShowHookColl, "Show Hook Collision"); + { static CInputState s_State = {this, &m_InputDirectionLeft[0], &m_InputDirectionLeft[1]}; Console()->Register("+left", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Move left"); } + { static CInputState s_State = {this, &m_InputDirectionRight[0], &m_InputDirectionRight[1]}; Console()->Register("+right", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Move right"); } + { static CInputState s_State = {this, &m_InputData[0].m_Jump, &m_InputData[1].m_Jump}; Console()->Register("+jump", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Jump"); } + { static CInputState s_State = {this, &m_InputData[0].m_Hook, &m_InputData[1].m_Hook}; Console()->Register("+hook", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Hook"); } + { static CInputState s_State = {this, &m_InputData[0].m_Fire, &m_InputData[1].m_Fire}; Console()->Register("+fire", "", CFGFLAG_CLIENT, ConKeyInputCounter, (void *)&s_State, "Fire"); } + { static CInputState s_State = {this, &m_ShowHookColl[0], &m_ShowHookColl[1]}; Console()->Register("+showhookcoll", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Show Hook Collision"); } - { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 1}; Console()->Register("+weapon1", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to hammer"); } - { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 2}; Console()->Register("+weapon2", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to gun"); } - { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 3}; Console()->Register("+weapon3", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to shotgun"); } - { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 4}; Console()->Register("+weapon4", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to grenade"); } - { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 5}; Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to rifle"); } + { static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[0].m_WantedWeapon, 1}; Console()->Register("+weapon1", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to hammer"); } + { static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[0].m_WantedWeapon, 2}; Console()->Register("+weapon2", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to gun"); } + { static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[0].m_WantedWeapon, 3}; Console()->Register("+weapon3", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to shotgun"); } + { static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[0].m_WantedWeapon, 4}; Console()->Register("+weapon4", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to grenade"); } + { static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[0].m_WantedWeapon, 5}; Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to rifle"); } - { static CInputSet s_Set = {this, &m_InputData.m_NextWeapon, 0}; Console()->Register("+nextweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to next weapon"); } - { static CInputSet s_Set = {this, &m_InputData.m_PrevWeapon, 0}; Console()->Register("+prevweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to previous weapon"); } + { static CInputSet s_Set = {this, &m_InputData[0].m_NextWeapon, &m_InputData[0].m_NextWeapon, 0}; Console()->Register("+nextweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to next weapon"); } + { static CInputSet s_Set = {this, &m_InputData[0].m_PrevWeapon, &m_InputData[0].m_PrevWeapon, 0}; Console()->Register("+prevweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to previous weapon"); } } void CControls::OnMessage(int Msg, void *pRawMsg) @@ -108,7 +131,7 @@ void CControls::OnMessage(int Msg, void *pRawMsg) { CNetMsg_Sv_WeaponPickup *pMsg = (CNetMsg_Sv_WeaponPickup *)pRawMsg; if(g_Config.m_ClAutoswitchWeapons) - m_InputData.m_WantedWeapon = pMsg->m_Weapon+1; + m_InputData[g_Config.m_ClDummy].m_WantedWeapon = pMsg->m_Weapon+1; } } @@ -119,29 +142,29 @@ int CControls::SnapInput(int *pData) // update player state if(m_pClient->m_pChat->IsActive()) - m_InputData.m_PlayerFlags = PLAYERFLAG_CHATTING; + m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_CHATTING; else if(m_pClient->m_pMenus->IsActive()) - m_InputData.m_PlayerFlags = PLAYERFLAG_IN_MENU; + m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_IN_MENU; else - m_InputData.m_PlayerFlags = PLAYERFLAG_PLAYING; + m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_PLAYING; if(m_pClient->m_pScoreboard->Active()) - m_InputData.m_PlayerFlags |= PLAYERFLAG_SCOREBOARD; + m_InputData[g_Config.m_ClDummy].m_PlayerFlags |= PLAYERFLAG_SCOREBOARD; - if (m_pClient->m_pControls->m_ShowHookColl) - m_InputData.m_PlayerFlags |= PLAYERFLAG_AIM; + if (m_pClient->m_pControls->m_ShowHookColl[g_Config.m_ClDummy]) + m_InputData[g_Config.m_ClDummy].m_PlayerFlags |= PLAYERFLAG_AIM; - if(m_LastData.m_PlayerFlags != m_InputData.m_PlayerFlags) + if(m_LastData[g_Config.m_ClDummy].m_PlayerFlags != m_InputData[g_Config.m_ClDummy].m_PlayerFlags) Send = true; - m_LastData.m_PlayerFlags = m_InputData.m_PlayerFlags; + m_LastData[g_Config.m_ClDummy].m_PlayerFlags = m_InputData[g_Config.m_ClDummy].m_PlayerFlags; // we freeze the input if chat or menu is activated - if(!(m_InputData.m_PlayerFlags&PLAYERFLAG_PLAYING)) + if(!(m_InputData[g_Config.m_ClDummy].m_PlayerFlags&PLAYERFLAG_PLAYING)) { OnReset(); - mem_copy(pData, &m_InputData, sizeof(m_InputData)); + mem_copy(pData, &m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); // send once a second just to be sure if(time_get() > LastSendTime + time_freq()) @@ -150,82 +173,74 @@ int CControls::SnapInput(int *pData) else { - m_InputData.m_TargetX = (int)m_MousePos.x; - m_InputData.m_TargetY = (int)m_MousePos.y; - if(!m_InputData.m_TargetX && !m_InputData.m_TargetY) + m_InputData[g_Config.m_ClDummy].m_TargetX = (int)m_MousePos[g_Config.m_ClDummy].x; + m_InputData[g_Config.m_ClDummy].m_TargetY = (int)m_MousePos[g_Config.m_ClDummy].y; + if(!m_InputData[g_Config.m_ClDummy].m_TargetX && !m_InputData[g_Config.m_ClDummy].m_TargetY) { - m_InputData.m_TargetX = 1; - m_MousePos.x = 1; + m_InputData[g_Config.m_ClDummy].m_TargetX = 1; + m_MousePos[g_Config.m_ClDummy].x = 1; } // set direction - m_InputData.m_Direction = 0; - if(m_InputDirectionLeft && !m_InputDirectionRight) - m_InputData.m_Direction = -1; - if(!m_InputDirectionLeft && m_InputDirectionRight) - m_InputData.m_Direction = 1; + m_InputData[g_Config.m_ClDummy].m_Direction = 0; + if(m_InputDirectionLeft[g_Config.m_ClDummy] && !m_InputDirectionRight[g_Config.m_ClDummy]) + m_InputData[g_Config.m_ClDummy].m_Direction = -1; + if(!m_InputDirectionLeft[g_Config.m_ClDummy] && m_InputDirectionRight[g_Config.m_ClDummy]) + m_InputData[g_Config.m_ClDummy].m_Direction = 1; // stress testing if(g_Config.m_DbgStress) { float t = Client()->LocalTime(); - mem_zero(&m_InputData, sizeof(m_InputData)); + mem_zero(&m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); - m_InputData.m_Direction = ((int)t/2)&1; - m_InputData.m_Jump = ((int)t); - m_InputData.m_Fire = ((int)(t*10)); - m_InputData.m_Hook = ((int)(t*2))&1; - m_InputData.m_WantedWeapon = ((int)t)%NUM_WEAPONS; - m_InputData.m_TargetX = (int)(sinf(t*3)*100.0f); - m_InputData.m_TargetY = (int)(cosf(t*3)*100.0f); - } - - if (g_Config.m_ClDummy != m_LastDummy) - { - int tmp = m_OtherFire; - m_OtherFire = m_InputData.m_Fire; - m_InputData.m_Fire = tmp; - m_LastDummy = g_Config.m_ClDummy; + m_InputData[g_Config.m_ClDummy].m_Direction = ((int)t/2)&1; + m_InputData[g_Config.m_ClDummy].m_Jump = ((int)t); + m_InputData[g_Config.m_ClDummy].m_Fire = ((int)(t*10)); + m_InputData[g_Config.m_ClDummy].m_Hook = ((int)(t*2))&1; + m_InputData[g_Config.m_ClDummy].m_WantedWeapon = ((int)t)%NUM_WEAPONS; + m_InputData[g_Config.m_ClDummy].m_TargetX = (int)(sinf(t*3)*100.0f); + m_InputData[g_Config.m_ClDummy].m_TargetY = (int)(cosf(t*3)*100.0f); } // check if we need to send input - if(m_InputData.m_Direction != m_LastData.m_Direction) Send = true; - else if(m_InputData.m_Jump != m_LastData.m_Jump) Send = true; - else if(m_InputData.m_Fire != m_LastData.m_Fire) Send = true; - else if(m_InputData.m_Hook != m_LastData.m_Hook) Send = true; - else if(m_InputData.m_WantedWeapon != m_LastData.m_WantedWeapon) Send = true; - else if(m_InputData.m_NextWeapon != m_LastData.m_NextWeapon) Send = true; - else if(m_InputData.m_PrevWeapon != m_LastData.m_PrevWeapon) Send = true; + if(m_InputData[g_Config.m_ClDummy].m_Direction != m_LastData[g_Config.m_ClDummy].m_Direction) Send = true; + else if(m_InputData[g_Config.m_ClDummy].m_Jump != m_LastData[g_Config.m_ClDummy].m_Jump) Send = true; + else if(m_InputData[g_Config.m_ClDummy].m_Fire != m_LastData[g_Config.m_ClDummy].m_Fire) Send = true; + else if(m_InputData[g_Config.m_ClDummy].m_Hook != m_LastData[g_Config.m_ClDummy].m_Hook) Send = true; + else if(m_InputData[g_Config.m_ClDummy].m_WantedWeapon != m_LastData[g_Config.m_ClDummy].m_WantedWeapon) Send = true; + else if(m_InputData[g_Config.m_ClDummy].m_NextWeapon != m_LastData[g_Config.m_ClDummy].m_NextWeapon) Send = true; + else if(m_InputData[g_Config.m_ClDummy].m_PrevWeapon != m_LastData[g_Config.m_ClDummy].m_PrevWeapon) Send = true; // send at at least 10hz if(time_get() > LastSendTime + time_freq()/25) Send = true; if(m_pClient->m_Snap.m_pLocalCharacter && m_pClient->m_Snap.m_pLocalCharacter->m_Weapon == WEAPON_NINJA - && (m_InputData.m_Direction || m_InputData.m_Jump || m_InputData.m_Hook)) + && (m_InputData[g_Config.m_ClDummy].m_Direction || m_InputData[g_Config.m_ClDummy].m_Jump || m_InputData[g_Config.m_ClDummy].m_Hook)) Send = true; } // copy and return size - m_LastData = m_InputData; + m_LastData[g_Config.m_ClDummy] = m_InputData[g_Config.m_ClDummy]; if(!Send) return 0; LastSendTime = time_get(); - mem_copy(pData, &m_InputData, sizeof(m_InputData)); - return sizeof(m_InputData); + mem_copy(pData, &m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); + return sizeof(m_InputData[0]); } void CControls::OnRender() { // update target pos if(m_pClient->m_Snap.m_pGameInfoObj && !m_pClient->m_Snap.m_SpecInfo.m_Active) - m_TargetPos = m_pClient->m_LocalCharacterPos + m_MousePos; + m_TargetPos[g_Config.m_ClDummy] = m_pClient->m_LocalCharacterPos + m_MousePos[g_Config.m_ClDummy]; else if(m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_UsePosition) - m_TargetPos = m_pClient->m_Snap.m_SpecInfo.m_Position + m_MousePos; + m_TargetPos[g_Config.m_ClDummy] = m_pClient->m_Snap.m_SpecInfo.m_Position + m_MousePos[g_Config.m_ClDummy]; else - m_TargetPos = m_MousePos; + m_TargetPos[g_Config.m_ClDummy] = m_MousePos[g_Config.m_ClDummy]; } bool CControls::OnMouseMove(float x, float y) @@ -234,7 +249,7 @@ bool CControls::OnMouseMove(float x, float y) (m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_pChat->IsActive())) return false; - m_MousePos += vec2(x, y); // TODO: ugly + m_MousePos[g_Config.m_ClDummy] += vec2(x, y); // TODO: ugly ClampMousePos(); return true; @@ -244,8 +259,8 @@ void CControls::ClampMousePos() { if(m_pClient->m_Snap.m_SpecInfo.m_Active && !m_pClient->m_Snap.m_SpecInfo.m_UsePosition) { - m_MousePos.x = clamp(m_MousePos.x, 200.0f, Collision()->GetWidth()*32-200.0f); - m_MousePos.y = clamp(m_MousePos.y, 200.0f, Collision()->GetHeight()*32-200.0f); + m_MousePos[g_Config.m_ClDummy].x = clamp(m_MousePos[g_Config.m_ClDummy].x, 200.0f, Collision()->GetWidth()*32-200.0f); + m_MousePos[g_Config.m_ClDummy].y = clamp(m_MousePos[g_Config.m_ClDummy].y, 200.0f, Collision()->GetHeight()*32-200.0f); } else @@ -254,7 +269,7 @@ void CControls::ClampMousePos() float FollowFactor = g_Config.m_ClMouseFollowfactor/100.0f; float MouseMax = min(CameraMaxDistance/FollowFactor + g_Config.m_ClMouseDeadzone, (float)g_Config.m_ClMouseMaxDistance); - if(length(m_MousePos) > MouseMax) - m_MousePos = normalize(m_MousePos)*MouseMax; + if(length(m_MousePos[g_Config.m_ClDummy]) > MouseMax) + m_MousePos[g_Config.m_ClDummy] = normalize(m_MousePos[g_Config.m_ClDummy])*MouseMax; } } diff --git a/src/game/client/components/controls.h b/src/game/client/components/controls.h index 3ce59ec3f..9eaf9f3ae 100644 --- a/src/game/client/components/controls.h +++ b/src/game/client/components/controls.h @@ -8,14 +8,14 @@ class CControls : public CComponent { public: - vec2 m_MousePos; - vec2 m_TargetPos; + vec2 m_MousePos[2]; + vec2 m_TargetPos[2]; - CNetObj_PlayerInput m_InputData; - CNetObj_PlayerInput m_LastData; - int m_InputDirectionLeft; - int m_InputDirectionRight; - int m_ShowHookColl; + CNetObj_PlayerInput m_InputData[2]; + CNetObj_PlayerInput m_LastData[2]; + int m_InputDirectionLeft[2]; + int m_InputDirectionRight[2]; + int m_ShowHookColl[2]; int m_LastDummy; int m_OtherFire; diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index fb2749f65..edd57a382 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -400,7 +400,7 @@ void CHud::RenderCursor() // render cursor RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS].m_pSpriteCursor); float CursorSize = 64; - RenderTools()->DrawSprite(m_pClient->m_pControls->m_TargetPos.x, m_pClient->m_pControls->m_TargetPos.y, CursorSize); + RenderTools()->DrawSprite(m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].x, m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].y, CursorSize); Graphics()->QuadsEnd(); } diff --git a/src/game/client/components/nameplates.cpp b/src/game/client/components/nameplates.cpp index db8d0ef2d..97e41fcc8 100644 --- a/src/game/client/components/nameplates.cpp +++ b/src/game/client/components/nameplates.cpp @@ -35,7 +35,7 @@ void CNamePlates::RenderNameplate( { float a = 1; if(g_Config.m_ClNameplatesAlways == 0) - a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos, Position)/200.0f,16.0f), 0.0f, 1.0f); + a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy], Position)/200.0f,16.0f), 0.0f, 1.0f); const char *pName = m_pClient->m_aClients[pPlayerInfo->m_ClientID].m_aName; float tw = TextRender()->TextWidth(0, FontSize, pName, -1); diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index dbe3be94d..8879c9794 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -410,7 +410,7 @@ void CPlayers::RenderPlayer( if(pInfo.m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK) { // just use the direct input if it's local player we are rendering - Angle = GetAngle(m_pClient->m_pControls->m_MousePos); + Angle = GetAngle(m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy]); } else { @@ -544,7 +544,7 @@ void CPlayers::RenderPlayer( vec2 ExDirection = Direction; if (pPlayerInfo->m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK) - ExDirection = normalize(vec2(m_pClient->m_pControls->m_InputData.m_TargetX, m_pClient->m_pControls->m_InputData.m_TargetY)); + ExDirection = normalize(vec2(m_pClient->m_pControls->m_InputData[g_Config.m_ClDummy].m_TargetX, m_pClient->m_pControls->m_InputData[g_Config.m_ClDummy].m_TargetY)); Graphics()->TextureSet(-1); vec2 initPos = Position; @@ -878,7 +878,7 @@ void CPlayers::RenderPlayer( { float a = 1; if(g_Config.m_ClNameplatesAlways == 0) - a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos, Position)/200.0f,16.0f), 0.0f, 1.0f); + a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy], Position)/200.0f,16.0f), 0.0f, 1.0f); const char *pName = m_pClient->m_aClients[pPlayerInfo->m_ClientID].m_aName; float tw = TextRender()->TextWidth(0, FontSize, pName, -1);