1
0
KF2-Dev-Scripts/KFGameContent/Classes/KFMG_SwingRide.uc
2020-12-13 18:01:13 +03:00

222 lines
6.2 KiB
Ucode

//=============================================================================
// KFMG_SwingRide
//=============================================================================
// Custom code for swing ride minigame. Rotates in code to avoid Matinee
// client/server desync issues doing it directly in the level. Client
// simulates movement to reduce hitching caused by lower server tick rate.
//
// Note: Ticking enabled while rotation is occuring. Otherwise uses optimized
// setup from the skeletal actor base class.
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// - Dan Weiss
//=============================================================================
class KFMG_SwingRide extends SkeletalMeshActor
placeable
implements(KFInterface_MinigameActor);
/** Amount of time to full speed */
var() float SpinUpTime;
/** Amount of time from deactivation to full stop */
var() float SpinDownTime;
/** Amount of rotation per second (in Rotator units) */
var() float RotationPerSecond;
/** Trigger to start client simulation */
var repnotify bool bSwingActive;
/** Curves for bringing the ride up to speed and to stop */
var InterpCurveFloat SpinUpCurve;
var InterpCurveFloat SpinDownCurve;
replication
{
if (bNetDirty)
bSwingActive;
}
simulated event ReplicatedEvent(name VarName)
{
super.ReplicatedEvent(VarName);
if (VarName == 'bSwingActive')
{
if (bSwingActive)
{
Activated(none);
}
else
{
Deactivated();
}
}
}
/** Whether this is in a valid state */
function bool CanBeActivated(KFTrigger_MinigameButton ActivationSource)
{
return true;
}
/** Called on rigged games to check whether a target at a specific bone can be played */
simulated event bool CanPlayAkEvent(Actor inOwner, name BoneName)
{
return true;
}
/** Setup accel curves here. Since they're dynamic based on times, poke around in code to get the values you want */
simulated function SetSpinUpCurve()
{
SpinUpCurve.Points.Length = 4;
SpinUpCurve.Points[0].InVal = 0;
SpinUpCurve.Points[0].OutVal = 0;
SpinUpCurve.Points[0].InterpMode = CIM_CurveAuto;
SpinUpCurve.Points[1].InVal = 0.25 * SpinUpTime;
SpinUpCurve.Points[1].OutVal = RotationPerSecond * 0.15f;
SpinUpCurve.Points[1].InterpMode = CIM_CurveAuto;
SpinUpCurve.Points[2].InVal = 0.75 * SpinUpTime;
SpinUpCurve.Points[2].OutVal = RotationPerSecond * 0.85f;
SpinUpCurve.Points[2].InterpMode = CIM_CurveAuto;
SpinUpCurve.Points[3].InVal = SpinUpTime;
SpinUpCurve.Points[3].OutVal = RotationPerSecond;
SpinUpCurve.Points[3].InterpMode = CIM_CurveAuto;
}
simulated function SetSpinDownCurve()
{
SpinDownCurve.Points.Length = 4;
SpinDownCurve.Points[0].InVal = 0;
SpinDownCurve.Points[0].OutVal = RotationPerSecond;
SpinDownCurve.Points[0].InterpMode = CIM_CurveAuto;
SpinDownCurve.Points[1].InVal = 0.25 * SpinDownTime;
SpinDownCurve.Points[1].OutVal = RotationPerSecond * 0.85f;
SpinDownCurve.Points[1].InterpMode = CIM_CurveAuto;
SpinDownCurve.Points[2].InVal = 0.75 * SpinDownTime;
SpinDownCurve.Points[2].OutVal = RotationPerSecond * 0.15f;
SpinDownCurve.Points[2].InterpMode = CIM_CurveAuto;
SpinDownCurve.Points[3].InVal = SpinDownTime;
SpinDownCurve.Points[3].OutVal = 0;
SpinDownCurve.Points[3].InterpMode = CIM_CurveAuto;
}
simulated function Activated(KFTrigger_MinigameButton ActivationSource)
{
SetTickIsDisabled(false);
bSwingActive = true;
SetSpinUpCurve();
SetTimer(SpinUpTime, false, 'EnableFullRide');
GoToState('SpinUp');
}
simulated function Deactivated()
{
if (IsInState('Active') || IsInState('SpinUp'))
{
bSwingActive = false;
SetTimer(SpinDownTime, false, 'RideStopped');
SetSpinDownCurve();
GoToState('SpinDown');
}
}
/** Default state, do nothing */
auto simulated state Stopped
{
simulated event BeginState(Name PreviousStateName)
{
super.BeginState(PreviousStateName);
SetTickIsDisabled(true);
}
}
/** Spin up state. Accelerate fake rotation up to full speed */
simulated state SpinUp
{
simulated event Tick(float DeltaTime)
{
local Rotator NewRotation;
global.Tick(DeltaTime);
NewRotation = Rotation;
NewRotation.Yaw = (NewRotation.Yaw + (EvalInterpCurveFloat(SpinUpCurve, GetTimerCount('EnableFullRide')) * DeltaTime)) % 65536;
SetRotation(NewRotation);
}
simulated function EnableFullRide()
{
GoToState('Active');
}
/** Don't allow activation while it's spinning up or spinning down */
function bool CanBeActivated(KFTrigger_MinigameButton ActivationSource)
{
return false;
}
}
/** Active state. Maintain rotation until ride is shut down */
simulated state Active
{
simulated event Tick(float DeltaTime)
{
local Rotator NewRotation;
global.Tick(DeltaTime);
NewRotation = Rotation;
NewRotation.Yaw = (NewRotation.Yaw + (RotationPerSecond * DeltaTime)) % 65536;
SetRotation(NewRotation);
}
}
/** Spin down state. Decelerate fake rotation until stopped */
function RideStopped();
simulated state SpinDown
{
simulated event Tick(float DeltaTime)
{
local Rotator NewRotation;
global.Tick(DeltaTime);
NewRotation = Rotation;
NewRotation.Yaw = (NewRotation.Yaw + (EvalInterpCurveFloat(SpinDownCurve, GetTimerCount('RideStopped')) * DeltaTime)) % 65536;
SetRotation(NewRotation);
}
simulated function RideStopped()
{
GoToState('Stopped');
}
/** Don't allow activation while it's spinning up or spinning down */
function bool CanBeActivated(KFTrigger_MinigameButton ActivationSource)
{
return false;
}
}
defaultproperties
{
SpinUpTime = 1.5f
SpinDownTime = 1.5f
RemoteRole = ROLE_SimulatedProxy
NetPriority = +00002.500000
bUpdateSimulatedPosition = true
bAlwaysRelevant = true
}