2010-05-29 07:25:38 +00:00
# include <base/math.h>
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
# include <engine/shared/config.h>
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
# include <game/collision.h>
# include <game/client/gameclient.h>
# include <game/client/component.h>
# include <game/client/components/chat.h>
# include <game/client/components/menus.h>
# include "controls.h"
CControls : : CControls ( )
2008-08-27 15:48:50 +00:00
{
}
2010-05-29 07:25:38 +00:00
static void ConKeyInputState ( IConsole : : IResult * pResult , void * pUserData )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
( ( int * ) pUserData ) [ 0 ] = pResult - > GetInteger ( 0 ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
static void ConKeyInputCounter ( IConsole : : IResult * pResult , void * pUserData )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
int * v = ( int * ) pUserData ;
if ( ( ( * v ) & 1 ) ! = pResult - > GetInteger ( 0 ) )
2008-08-27 15:48:50 +00:00
( * v ) + + ;
* v & = INPUT_STATE_MASK ;
}
2008-08-27 20:04:07 +00:00
2010-05-29 07:25:38 +00:00
struct CInputSet
2008-08-27 20:04:07 +00:00
{
2010-05-29 07:25:38 +00:00
CControls * m_pControls ;
int * m_pVariable ;
int m_Value ;
2008-08-27 20:04:07 +00:00
} ;
2010-05-29 07:25:38 +00:00
static void ConKeyInputSet ( IConsole : : IResult * pResult , void * pUserData )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
CInputSet * pSet = ( CInputSet * ) pUserData ;
if ( pResult - > GetInteger ( 0 ) )
* pSet - > m_pVariable = pSet - > m_Value ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
static void ConKeyInputNextPrevWeapon ( IConsole : : IResult * pResult , void * pUserData )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
CInputSet * pSet = ( CInputSet * ) pUserData ;
ConKeyInputCounter ( pResult , pSet - > m_pVariable ) ;
pSet - > m_pControls - > m_InputData . m_WantedWeapon = 0 ;
2008-08-27 20:04:07 +00:00
}
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
void CControls : : OnConsoleInit ( )
2008-08-27 15:48:50 +00:00
{
// game commands
2010-05-29 07:25:38 +00:00
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 " ) ;
{ 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 . 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 " ) ; }
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
void CControls : : OnMessage ( int Msg , void * pRawMsg )
2008-08-31 21:50:14 +00:00
{
2010-05-29 07:25:38 +00:00
if ( Msg = = NETMSGTYPE_SV_WEAPONPICKUP )
2008-08-31 21:50:14 +00:00
{
2010-05-29 07:25:38 +00:00
CNetMsg_Sv_WeaponPickup * pMsg = ( CNetMsg_Sv_WeaponPickup * ) pRawMsg ;
if ( g_Config . m_ClAutoswitchWeapons )
m_InputData . m_WantedWeapon = pMsg - > m_Weapon + 1 ;
2008-08-31 21:50:14 +00:00
}
}
2010-05-29 07:25:38 +00:00
int CControls : : SnapInput ( int * pData )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
static CNetObj_PlayerInput LastData = { 0 } ;
static int64 LastSendTime = 0 ;
bool Send = false ;
2008-08-27 15:48:50 +00:00
// update player state
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_pChat - > IsActive ( ) )
m_InputData . m_PlayerState = PLAYERSTATE_CHATTING ;
else if ( m_pClient - > m_pMenus - > IsActive ( ) )
m_InputData . m_PlayerState = PLAYERSTATE_IN_MENU ;
2008-08-27 15:48:50 +00:00
else
2010-05-29 07:25:38 +00:00
m_InputData . m_PlayerState = PLAYERSTATE_PLAYING ;
2009-01-10 13:34:01 +00:00
2010-05-29 07:25:38 +00:00
if ( LastData . m_PlayerState ! = m_InputData . m_PlayerState )
Send = true ;
2009-01-10 13:34:01 +00:00
2010-05-29 07:25:38 +00:00
LastData . m_PlayerState = m_InputData . m_PlayerState ;
2008-08-27 15:48:50 +00:00
// we freeze the input if chat or menu is activated
2010-05-29 07:25:38 +00:00
if ( m_InputData . m_PlayerState ! = PLAYERSTATE_PLAYING )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
LastData . m_Direction = 0 ;
LastData . m_Hook = 0 ;
LastData . m_Jump = 0 ;
m_InputData = LastData ;
2008-10-20 22:53:42 +00:00
2010-05-29 07:25:38 +00:00
m_InputDirectionLeft = 0 ;
m_InputDirectionRight = 0 ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
mem_copy ( pData , & m_InputData , sizeof ( m_InputData ) ) ;
2009-01-10 13:34:01 +00:00
// send once a second just to be sure
2010-05-29 07:25:38 +00:00
if ( time_get ( ) > LastSendTime + time_freq ( ) )
Send = true ;
2008-08-30 22:38:56 +00:00
}
2009-01-10 13:34:01 +00:00
else
2008-08-27 15:48:50 +00:00
{
2009-01-10 13:34:01 +00:00
2010-05-29 07:25:38 +00:00
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 . m_TargetX = 1 ;
m_MousePos . x = 1 ;
}
2009-01-10 13:34:01 +00:00
// set direction
2010-05-29 07:25:38 +00:00
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 ;
2009-01-10 13:34:01 +00:00
// stress testing
2010-05-29 07:25:38 +00:00
if ( g_Config . m_DbgStress )
2009-01-10 13:34:01 +00:00
{
2010-05-29 07:25:38 +00:00
float t = Client ( ) - > LocalTime ( ) ;
mem_zero ( & m_InputData , sizeof ( m_InputData ) ) ;
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 ) ;
2009-01-10 13:34:01 +00:00
}
// check if we need to send input
2010-05-29 07:25:38 +00:00
if ( m_InputData . m_Direction ! = LastData . m_Direction ) Send = true ;
else if ( m_InputData . m_Jump ! = LastData . m_Jump ) Send = true ;
else if ( m_InputData . m_Fire ! = LastData . m_Fire ) Send = true ;
else if ( m_InputData . m_Hook ! = LastData . m_Hook ) Send = true ;
else if ( m_InputData . m_PlayerState ! = LastData . m_PlayerState ) Send = true ;
else if ( m_InputData . m_WantedWeapon ! = LastData . m_WantedWeapon ) Send = true ;
else if ( m_InputData . m_NextWeapon ! = LastData . m_NextWeapon ) Send = true ;
else if ( m_InputData . m_PrevWeapon ! = LastData . m_PrevWeapon ) Send = true ;
2009-01-10 13:34:01 +00:00
// send at at least 10hz
2010-05-29 07:25:38 +00:00
if ( time_get ( ) > LastSendTime + time_freq ( ) / 25 )
Send = true ;
2008-08-27 15:48:50 +00:00
}
2009-01-10 13:34:01 +00:00
// copy and return size
2010-05-29 07:25:38 +00:00
LastData = m_InputData ;
2009-01-10 13:34:01 +00:00
2010-05-29 07:25:38 +00:00
if ( ! Send )
2008-08-27 15:48:50 +00:00
return 0 ;
2010-05-29 07:25:38 +00:00
LastSendTime = time_get ( ) ;
mem_copy ( pData , & m_InputData , sizeof ( m_InputData ) ) ;
return sizeof ( m_InputData ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
void CControls : : OnRender ( )
2008-09-13 05:57:11 +00:00
{
// update target pos
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_pGameobj & & ! ( m_pClient - > m_Snap . m_pGameobj - > m_Paused | | m_pClient - > m_Snap . m_Spectate ) )
m_TargetPos = m_pClient - > m_LocalCharacterPos + m_MousePos ;
2008-09-13 05:57:11 +00:00
}
2010-05-29 07:25:38 +00:00
bool CControls : : OnMouseMove ( float x , float y )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_pGameobj & & m_pClient - > m_Snap . m_pGameobj - > m_Paused )
2008-11-16 15:39:22 +00:00
return false ;
2010-05-29 07:25:38 +00:00
m_MousePos + = vec2 ( x , y ) ; // TODO: ugly
2008-08-27 15:48:50 +00:00
//
2010-05-29 07:25:38 +00:00
float CameraMaxDistance = 200.0f ;
float FollowFactor = g_Config . m_ClMouseFollowfactor / 100.0f ;
float DeadZone = g_Config . m_ClMouseDeadzone ;
float MouseMax = min ( CameraMaxDistance / FollowFactor + DeadZone , ( float ) g_Config . m_ClMouseMaxDistance ) ;
2008-08-27 15:48:50 +00:00
//vec2 camera_offset(0, 0);
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_Spectate )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( m_MousePos . x < 200.0f ) m_MousePos . x = 200.0f ;
if ( m_MousePos . y < 200.0f ) m_MousePos . y = 200.0f ;
if ( m_MousePos . x > Collision ( ) - > GetWidth ( ) * 32 - 200.0f ) m_MousePos . x = Collision ( ) - > GetWidth ( ) * 32 - 200.0f ;
if ( m_MousePos . y > Collision ( ) - > GetHeight ( ) * 32 - 200.0f ) m_MousePos . y = Collision ( ) - > GetHeight ( ) * 32 - 200.0f ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
m_TargetPos = m_MousePos ;
2008-08-27 15:48:50 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
float l = length ( m_MousePos ) ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
if ( l > MouseMax )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
m_MousePos = normalize ( m_MousePos ) * MouseMax ;
l = MouseMax ;
2008-08-27 15:48:50 +00:00
}
//float offset_amount = max(l-deadzone, 0.0f) * follow_factor;
//if(l > 0.0001f) // make sure that this isn't 0
//camera_offset = normalize(mouse_pos)*offset_amount;
}
return true ;
}