355 lines
8.3 KiB
Ucode
355 lines
8.3 KiB
Ucode
//=============================================================================
|
|
// PlayerInput
|
|
// Object within playercontroller that manages player input.
|
|
// only spawned on client
|
|
//=============================================================================
|
|
|
|
class PlayerInput extends Object within PlayerController
|
|
config(User)
|
|
native
|
|
transient;
|
|
|
|
var globalconfig bool bInvertMouse;
|
|
|
|
var bool bWasForward; // used for doubleclick move
|
|
var bool bWasBack;
|
|
var bool bWasLeft;
|
|
var bool bWasRight;
|
|
var bool bEdgeForward;
|
|
var bool bEdgeBack;
|
|
var bool bEdgeLeft;
|
|
var bool bEdgeRight;
|
|
var bool bAdjustSampling;
|
|
|
|
// Mouse smoothing
|
|
var globalconfig byte MouseSmoothingMode;
|
|
var globalconfig float MouseSmoothingStrength;
|
|
var globalconfig float MouseSensitivity;
|
|
var globalconfig float MouseSamplingTime;
|
|
var globalconfig float MouseAccelThreshold;
|
|
|
|
var float SmoothedMouse[2], ZeroTime[2], SamplingTime[2], MaybeTime[2], OldSamples[4];
|
|
var int MouseSamples[2];
|
|
|
|
var float DoubleClickTimer; // max double click interval for double click move
|
|
var globalconfig float DoubleClickTime;
|
|
var globalconfig bool bEnableDodging;
|
|
|
|
//=============================================================================
|
|
// Input related functions.
|
|
|
|
function bool InvertLook();
|
|
|
|
// Postprocess the player's input.
|
|
event PlayerInput( float DeltaTime )
|
|
{
|
|
local float FOVScale, MouseScale;
|
|
|
|
// Ignore input if we're playing back a client-side demo.
|
|
if( Outer.bDemoOwner && !Outer.default.bDemoOwner )
|
|
return;
|
|
|
|
// Check for Double click move
|
|
// flag transitions
|
|
bEdgeForward = (bWasForward ^^ (aBaseY > 0));
|
|
bEdgeBack = (bWasBack ^^ (aBaseY < 0));
|
|
bEdgeLeft = (bWasLeft ^^ (aStrafe < 0));
|
|
bEdgeRight = (bWasRight ^^ (aStrafe > 0));
|
|
bWasForward = (aBaseY > 0);
|
|
bWasBack = (aBaseY < 0);
|
|
bWasLeft = (aStrafe < 0);
|
|
bWasRight = (aStrafe > 0);
|
|
|
|
// Smooth and amplify mouse movement
|
|
FOVScale = DesiredFOV * 0.01111; // 0.01111 = 1/90
|
|
MouseScale = MouseSensitivity * FOVScale;
|
|
aMouseX = SmoothMouse(aMouseX*MouseScale, DeltaTime,bXAxis,0);
|
|
aMouseY = SmoothMouse(aMouseY*MouseScale, DeltaTime,bYAxis,1);
|
|
|
|
aMouseX = AccelerateMouse(aMouseX);
|
|
aMouseY = AccelerateMouse(aMouseY);
|
|
|
|
// adjust keyboard and joystick movements
|
|
aLookUp *= FOVScale;
|
|
aTurn *= FOVScale;
|
|
|
|
// Remap raw x-axis movement.
|
|
if( bStrafe!=0 ) // strafe
|
|
aStrafe += aBaseX * 7.5 + aMouseX;
|
|
else // forward
|
|
aTurn += aBaseX * FOVScale + aMouseX;
|
|
|
|
aBaseX = 0;
|
|
|
|
// Remap mouse y-axis movement.
|
|
if( (bStrafe == 0) && (bAlwaysMouseLook || (bLook!=0)) )
|
|
{
|
|
// Look up/down.
|
|
if ( bInvertMouse )
|
|
aLookUp -= aMouseY;
|
|
else
|
|
aLookUp += aMouseY;
|
|
}
|
|
else // Move forward/backward.
|
|
aForward += aMouseY;
|
|
|
|
if ( bSnapLevel != 0 )
|
|
{
|
|
bCenterView = true;
|
|
bKeyboardLook = false;
|
|
}
|
|
else if (aLookUp != 0)
|
|
{
|
|
bCenterView = false;
|
|
bKeyboardLook = true;
|
|
}
|
|
else if ( bSnapToLevel && !bAlwaysMouseLook )
|
|
{
|
|
bCenterView = true;
|
|
bKeyboardLook = false;
|
|
}
|
|
|
|
// Remap other y-axis movement.
|
|
if ( bFreeLook != 0 )
|
|
{
|
|
bKeyboardLook = true;
|
|
aLookUp += 0.5 * aBaseY * FOVScale;
|
|
}
|
|
else
|
|
aForward += aBaseY;
|
|
|
|
aBaseY = 0;
|
|
|
|
// Handle walking.
|
|
HandleWalking();
|
|
}
|
|
|
|
exec function SetSmoothingMode(byte B)
|
|
{
|
|
MouseSmoothingMode = B;
|
|
// log("Smoothing mode "$MouseSmoothingMode);
|
|
}
|
|
|
|
exec function SetSmoothingStrength(float F)
|
|
{
|
|
MouseSmoothingStrength = FClamp(F,0,1);
|
|
default.MouseSmoothingStrength = MouseSmoothingStrength;
|
|
class'PlayerInput'.static.StaticSaveConfig();
|
|
}
|
|
|
|
function float AccelerateMouse(float aMouse)
|
|
{
|
|
local float Accel;
|
|
|
|
if ( abs(aMouse) == 0 )
|
|
return 0;
|
|
|
|
Accel = MouseAccelThreshold * MouseSensitivity;
|
|
if ( abs(aMouse) < Accel )
|
|
{
|
|
if ( abs(aMouse) < 0.1 * Accel )
|
|
aMouse *= 0.1;
|
|
else
|
|
aMouse = aMouse * abs(aMouse)/Accel;
|
|
}
|
|
return aMouse;
|
|
}
|
|
|
|
function float SmoothMouse(float aMouse, float DeltaTime, out byte SampleCount, int Index)
|
|
{
|
|
local int i, sum;
|
|
|
|
if ( MouseSmoothingMode == 0 )
|
|
return aMouse;
|
|
|
|
if ( aMouse == 0 )
|
|
{
|
|
ZeroTime[Index] += DeltaTime;
|
|
if ( ZeroTime[Index] < MouseSamplingTime )
|
|
{
|
|
SamplingTime[Index] += DeltaTime;
|
|
MaybeTime[Index] += DeltaTime;
|
|
aMouse = SmoothedMouse[Index];
|
|
}
|
|
else
|
|
{
|
|
if ( bAdjustSampling && (MouseSamples[Index] > 9) )
|
|
{
|
|
SamplingTime[Index] -= MaybeTime[Index];
|
|
MouseSamplingTime = 0.9 * MouseSamplingTime + 0.1 * SamplingTime[Index]/MouseSamples[Index];
|
|
}
|
|
SamplingTime[Index] = 0;
|
|
SmoothedMouse[Index] = 0;
|
|
MouseSamples[Index] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MaybeTime[Index] = 0;
|
|
|
|
if ( SmoothedMouse[Index] != 0 )
|
|
{
|
|
MouseSamples[Index] += SampleCount;
|
|
if ( DeltaTime > MouseSamplingTime * (SampleCount + 1) )
|
|
SamplingTime[Index] += MouseSamplingTime * SampleCount;
|
|
else
|
|
{
|
|
SamplingTime[Index] += DeltaTime;
|
|
aMouse = aMouse * DeltaTime/(MouseSamplingTime * SampleCount);
|
|
}
|
|
}
|
|
else
|
|
SamplingTime[Index] = 0.5 * MouseSamplingTime;
|
|
|
|
SmoothedMouse[Index] = aMouse/SampleCount;
|
|
ZeroTime[Index] = 0;
|
|
}
|
|
SampleCount = 0;
|
|
|
|
if ( MouseSmoothingMode > 1 )
|
|
{
|
|
if ( aMouse == 0 )
|
|
{
|
|
// stop in next tick
|
|
for ( i=0; i<3; i++ )
|
|
{
|
|
sum += (i+1) * 0.1;
|
|
aMouse += sum * OldSamples[i];
|
|
OldSamples[i] = 0;
|
|
}
|
|
OldSamples[3] = 0;
|
|
}
|
|
else
|
|
{
|
|
aMouse = 0.4 * aMouse;
|
|
OldSamples[3] = aMouse;
|
|
for ( i=0; i<3; i++ )
|
|
{
|
|
aMouse += (i+1) * 0.1 * OldSamples[i];
|
|
OldSamples[i] = OldSamples[i+1];
|
|
}
|
|
|
|
}
|
|
}
|
|
return aMouse;
|
|
}
|
|
|
|
function UpdateSensitivity(float F)
|
|
{
|
|
MouseSensitivity = FMax(0,F);
|
|
default.MouseSensitivity = MouseSensitivity;
|
|
class'PlayerInput'.static.StaticSaveConfig();
|
|
}
|
|
|
|
function UpdateAccel(float F)
|
|
{
|
|
MouseAccelThreshold = FMax(0,f);
|
|
default.MouseAccelThreshold = MouseAccelThreshold;
|
|
class'PlayerInput'.static.StaticSaveConfig();
|
|
}
|
|
|
|
function UpdateSmoothing( int Mode )
|
|
{
|
|
MouseSmoothingMode = Mode;
|
|
default.MouseSmoothingMode = MouseSmoothingMode;
|
|
class'PlayerInput'.static.StaticSaveConfig();
|
|
}
|
|
|
|
function InvertMouse(optional string Invert)
|
|
{
|
|
if (Invert != "")
|
|
bInvertMouse = bool(Invert);
|
|
|
|
else bInvertMouse = !bInvertMouse;
|
|
|
|
SaveConfig();
|
|
default.bInvertMouse = bInvertMouse;
|
|
}
|
|
|
|
function ChangeSnapView( bool B )
|
|
{
|
|
bSnapToLevel = B;
|
|
}
|
|
|
|
// check for double click move
|
|
function Actor.eDoubleClickDir CheckForDoubleClickMove(float DeltaTime)
|
|
{
|
|
local Actor.eDoubleClickDir DoubleClickMove, OldDoubleClick;
|
|
|
|
if (!bEnableDodging)
|
|
{
|
|
DoubleClickMove = DCLICK_None;
|
|
return DoubleClickMove;
|
|
}
|
|
|
|
if ( DoubleClickDir == DCLICK_Active )
|
|
DoubleClickMove = DCLICK_Active;
|
|
else
|
|
DoubleClickMove = DCLICK_None;
|
|
if (DoubleClickTime > 0.0)
|
|
{
|
|
if ( DoubleClickDir == DCLICK_Active )
|
|
{
|
|
if ( (Pawn != None) && (Pawn.Physics == PHYS_Walking) )
|
|
{
|
|
DoubleClickTimer = 0;
|
|
DoubleClickDir = DCLICK_Done;
|
|
}
|
|
}
|
|
else if ( DoubleClickDir != DCLICK_Done )
|
|
{
|
|
OldDoubleClick = DoubleClickDir;
|
|
DoubleClickDir = DCLICK_None;
|
|
|
|
if (bEdgeForward && bWasForward)
|
|
DoubleClickDir = DCLICK_Forward;
|
|
else if (bEdgeBack && bWasBack)
|
|
DoubleClickDir = DCLICK_Back;
|
|
else if (bEdgeLeft && bWasLeft)
|
|
DoubleClickDir = DCLICK_Left;
|
|
else if (bEdgeRight && bWasRight)
|
|
DoubleClickDir = DCLICK_Right;
|
|
|
|
if ( DoubleClickDir == DCLICK_None)
|
|
DoubleClickDir = OldDoubleClick;
|
|
else if ( DoubleClickDir != OldDoubleClick )
|
|
DoubleClickTimer = DoubleClickTime + 0.5 * DeltaTime;
|
|
else
|
|
DoubleClickMove = DoubleClickDir;
|
|
}
|
|
|
|
if (DoubleClickDir == DCLICK_Done)
|
|
{
|
|
DoubleClickTimer = FMin(DoubleClickTimer-DeltaTime,0);
|
|
if (DoubleClickTimer < -0.35)
|
|
{
|
|
DoubleClickDir = DCLICK_None;
|
|
DoubleClickTimer = DoubleClickTime;
|
|
}
|
|
}
|
|
else if ((DoubleClickDir != DCLICK_None) && (DoubleClickDir != DCLICK_Active))
|
|
{
|
|
DoubleClickTimer -= DeltaTime;
|
|
if (DoubleClickTimer < 0)
|
|
{
|
|
DoubleClickDir = DCLICK_None;
|
|
DoubleClickTimer = DoubleClickTime;
|
|
}
|
|
}
|
|
}
|
|
return DoubleClickMove;
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
bInvertMouse=false
|
|
bAdjustSampling=true
|
|
MouseSamplingTime=+0.008333
|
|
MouseSmoothingStrength=+0.3
|
|
MouseSmoothingMode=1
|
|
MouseSensitivity=3.000000
|
|
MouseAccelThreshold=0.0
|
|
DoubleClickTime=0.250000
|
|
bEnableDodging=true
|
|
}
|