diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index b85213181..afb06194f 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -311,7 +311,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; @@ -466,7 +467,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) { @@ -476,23 +477,23 @@ 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 != (bool)g_Config.m_ClDummy) { - mem_copy(&DummyInput, &m_aInputs[(m_CurrentInput+200-1)%200], sizeof(DummyInput)); + mem_copy(&DummyInput, &m_aInputs[!g_Config.m_ClDummy][(m_CurrentInput[!g_Config.m_ClDummy]+200-1)%200], sizeof(DummyInput)); m_LastDummy = g_Config.m_ClDummy; if (g_Config.m_ClDummyResetOnSwitch) @@ -580,12 +581,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; } @@ -613,8 +614,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; @@ -1656,9 +1661,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 e17e36583..e7fc28c0a 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -146,9 +146,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/controls.cpp b/src/game/client/components/controls.cpp index 10b015cc7..b25e8a0ee 100644 --- a/src/game/client/components/controls.cpp +++ b/src/game/client/components/controls.cpp @@ -63,17 +63,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; m_JoystickFirePressed = false; m_JoystickRunPressed = false; @@ -85,7 +85,20 @@ void CControls::OnReset() void CControls::ResetDummyInput() { - + m_LastData[!g_Config.m_ClDummy].m_Direction = 0; + if(m_LastData[!g_Config.m_ClDummy].m_Fire & 1) + m_LastData[!g_Config.m_ClDummy].m_Fire++; + m_LastData[!g_Config.m_ClDummy].m_Hook = 0; + m_LastData[!g_Config.m_ClDummy].m_Jump = 0; + + m_InputData[!g_Config.m_ClDummy].m_Direction = 0; + if(m_InputData[!g_Config.m_ClDummy].m_Fire & 1) + m_InputData[!g_Config.m_ClDummy].m_Fire++; + m_InputData[!g_Config.m_ClDummy].m_Hook = 0; + m_InputData[!g_Config.m_ClDummy].m_Jump = 0; + + m_InputDirectionLeft[!g_Config.m_ClDummy] = 0; + m_InputDirectionRight[!g_Config.m_ClDummy] = 0; } void CControls::OnRelease() @@ -96,7 +109,7 @@ void CControls::OnRelease() void CControls::OnPlayerDeath() { if (g_Config.m_ClResetWantedWeaponOnDeath) - 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; for( int i = 0; i < NUM_WEAPONS; i++ ) m_AmmoCount[i] = 0; m_JoystickTapTime = 0; // Do not launch hook on first tap @@ -106,6 +119,7 @@ struct CInputState { CControls *m_pControls; int *m_pVariable1; + int *m_pVariable2; }; static void ConKeyInputState(IConsole::IResult *pResult, void *pUserData) @@ -120,7 +134,10 @@ static void ConKeyInputState(IConsole::IResult *pResult, void *pUserData) if ((IsGameTypeRace || IsGameTypeDDRace) && pState->m_pControls->GameClient()->m_Snap.m_SpecInfo.m_Active) return; - *pState->m_pVariable1 = pResult->GetInteger(0); + 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) @@ -136,7 +153,10 @@ static void ConKeyInputCounter(IConsole::IResult *pResult, void *pUserData) return; int *v; - v = pState->m_pVariable1; + if (g_Config.m_ClDummy) + v = pState->m_pVariable2; + else + v = pState->m_pVariable1; if(((*v)&1) != pResult->GetInteger(0)) (*v)++; @@ -147,6 +167,7 @@ struct CInputSet { CControls *m_pControls; int *m_pVariable1; + int *m_pVariable2; int m_Value; }; @@ -154,34 +175,39 @@ static void ConKeyInputSet(IConsole::IResult *pResult, void *pUserData) { CInputSet *pSet = (CInputSet *)pUserData; if(pResult->GetInteger(0)) - *pSet->m_pVariable1 = 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); - pSet->m_pControls->m_InputData.m_WantedWeapon = 0; + pSet->m_pControls->m_InputData[g_Config.m_ClDummy].m_WantedWeapon = 0; } void CControls::OnConsoleInit() { // game commands - { static CInputState s_State = {this, &m_InputDirectionLeft}; Console()->Register("+left", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Move left"); } - { static CInputState s_State = {this, &m_InputDirectionRight}; Console()->Register("+right", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Move right"); } - { static CInputState s_State = {this, &m_InputData.m_Jump}; Console()->Register("+jump", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Jump"); } - { static CInputState s_State = {this, &m_InputData.m_Hook}; Console()->Register("+hook", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "Hook"); } - { static CInputState s_State = {this, &m_InputData.m_Fire}; Console()->Register("+fire", "", CFGFLAG_CLIENT, ConKeyInputCounter, (void *)&s_State, "Fire"); } - { static CInputState s_State = {this, &m_ShowHookColl}; Console()->Register("+showhookcoll", "", CFGFLAG_CLIENT, ConKeyInputState, (void *)&s_State, "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[1].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[1].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[1].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[1].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[1].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[1].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[1].m_PrevWeapon, 0}; Console()->Register("+prevweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to previous weapon"); } } void CControls::OnMessage(int Msg, void *pRawMsg) @@ -190,7 +216,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; // We don't really know ammo count, until we'll switch to that weapon, but any non-zero count will suffice here m_AmmoCount[pMsg->m_Weapon%NUM_WEAPONS] = 10; } @@ -203,32 +229,32 @@ 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_InputData.m_PlayerFlags != PLAYERFLAG_PLAYING) + if(m_InputData[g_Config.m_ClDummy].m_PlayerFlags != PLAYERFLAG_PLAYING) m_JoystickTapTime = 0; // Do not launch hook on first tap - 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()) @@ -236,63 +262,63 @@ int CControls::SnapInput(int *pData) } else { - m_InputData.m_TargetX = (int)m_MousePos[g_Config.m_ClDummy].x; - m_InputData.m_TargetY = (int)m_MousePos[g_Config.m_ClDummy].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_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); + 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() @@ -325,10 +351,10 @@ void CControls::OnRender() if( RunPressed ) { if( m_JoystickTapTime + time_freq() > CurTime ) // Tap in less than 1 second to jump - m_InputData.m_Jump = 1; + m_InputData[g_Config.m_ClDummy].m_Jump = 1; } else - m_InputData.m_Jump = 0; + m_InputData[g_Config.m_ClDummy].m_Jump = 0; m_JoystickTapTime = CurTime; } @@ -336,15 +362,15 @@ void CControls::OnRender() if( RunPressed ) { - m_InputDirectionLeft = (RunX < -JOYSTICK_RUN_DISTANCE); - m_InputDirectionRight = (RunX > JOYSTICK_RUN_DISTANCE); + m_InputDirectionLeft[g_Config.m_ClDummy] = (RunX < -JOYSTICK_RUN_DISTANCE); + m_InputDirectionRight[g_Config.m_ClDummy] = (RunX > JOYSTICK_RUN_DISTANCE); } // Move 500ms in the same direction, to prevent speed bump when tapping if( !RunPressed && m_JoystickTapTime + time_freq() / 2 > CurTime ) { - m_InputDirectionLeft = 0; - m_InputDirectionRight = 0; + m_InputDirectionLeft[g_Config.m_ClDummy] = 0; + m_InputDirectionRight[g_Config.m_ClDummy] = 0; } //dbg_msg("dbg", "RunPressed %d m_JoystickSwipeJumpClear %lld m_JoystickSwipeJumpY %d RunY %d cond %d", @@ -355,11 +381,11 @@ void CControls::OnRender() { m_MousePos[g_Config.m_ClDummy] = vec2(HookX / 30, HookY / 30); ClampMousePos(); - m_InputData.m_Hook = 1; + m_InputData[g_Config.m_ClDummy].m_Hook = 1; } else { - m_InputData.m_Hook = 0; + m_InputData[g_Config.m_ClDummy].m_Hook = 0; } if( AimPressed ) @@ -373,9 +399,9 @@ void CControls::OnRender() // Fire when releasing joystick if( !AimPressed ) { - m_InputData.m_Fire ++; - if( (bool)(m_InputData.m_Fire % 2) != AimPressed ) - m_InputData.m_Fire ++; + m_InputData[g_Config.m_ClDummy].m_Fire ++; + if( (bool)(m_InputData[g_Config.m_ClDummy].m_Fire % 2) != AimPressed ) + m_InputData[g_Config.m_ClDummy].m_Fire ++; FireWasPressed = true; } } @@ -390,8 +416,8 @@ void CControls::OnRender() int RunY = SDL_JoystickGetAxis(m_Gamepad, LEFT_JOYSTICK_Y); if( m_UsingGamepad ) { - m_InputDirectionLeft = (RunX < -GAMEPAD_DEAD_ZONE); - m_InputDirectionRight = (RunX > GAMEPAD_DEAD_ZONE); + m_InputDirectionLeft[g_Config.m_ClDummy] = (RunX < -GAMEPAD_DEAD_ZONE); + m_InputDirectionRight[g_Config.m_ClDummy] = (RunX > GAMEPAD_DEAD_ZONE); } // Get input from right joystick @@ -415,7 +441,7 @@ void CControls::OnRender() // Keep track of ammo count, we know weapon ammo only when we switch to that weapon, this is tracked on server and protocol does not track that m_AmmoCount[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS] = m_pClient->m_Snap.m_pLocalCharacter->m_AmmoCount; // Autoswitch weapon if we're out of ammo - if( (m_InputData.m_Fire % 2 != 0 || FireWasPressed) && + if( (m_InputData[g_Config.m_ClDummy].m_Fire % 2 != 0 || FireWasPressed) && m_pClient->m_Snap.m_pLocalCharacter->m_AmmoCount == 0 && m_pClient->m_Snap.m_pLocalCharacter->m_Weapon != WEAPON_HAMMER && m_pClient->m_Snap.m_pLocalCharacter->m_Weapon != WEAPON_NINJA ) @@ -429,7 +455,7 @@ void CControls::OnRender() break; } if( w != m_pClient->m_Snap.m_pLocalCharacter->m_Weapon ) - m_InputData.m_WantedWeapon = w+1; + m_InputData[g_Config.m_ClDummy].m_WantedWeapon = w+1; } } diff --git a/src/game/client/components/controls.h b/src/game/client/components/controls.h index f8ceb9184..c8e08c266 100644 --- a/src/game/client/components/controls.h +++ b/src/game/client/components/controls.h @@ -24,11 +24,11 @@ public: int m_AmmoCount[NUM_WEAPONS]; - 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/players.cpp b/src/game/client/components/players.cpp index f55bd9fc0..0ace257ae 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -552,7 +552,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;