286 lines
7.8 KiB
Ucode
286 lines
7.8 KiB
Ucode
//=============================================================================
|
|
// KFMGA_AnimatedTrap
|
|
//=============================================================================
|
|
// Any trap-style minigame event that uses a similar idle/activate/deactivate
|
|
// set of animations. Manually handles movement to avoid client/server
|
|
// collision disagreements for collision assumed to be moving via-anims,
|
|
// or problems typical of client/server matinees.
|
|
//=============================================================================
|
|
// Killing Floor 2
|
|
// Copyright (C) 2015 Tripwire Interactive LLC
|
|
// - Dan Weiss
|
|
//=============================================================================
|
|
|
|
class KFMGA_AnimatedTrap extends SkeletalMeshActor
|
|
placeable
|
|
implements(KFInterface_MinigameActor);
|
|
|
|
/** Animation looping while the game is in the deactivated state. Plays into activation. */
|
|
var() name DeactivatedIdleAnim;
|
|
|
|
/** Animation triggered when activation begins. Plays into activated idle. */
|
|
var() name ActivationAnim;
|
|
|
|
/** Animation looping while in the activated state. Plays into deactivation. */
|
|
var() name ActivatedIdleAnim;
|
|
|
|
/** Animation triggered when deactivating. Plays into deactivated idle. */
|
|
var() name DeactivationAnim;
|
|
|
|
/** Activation state */
|
|
var repnotify bool bActivated;
|
|
|
|
/** Amount to move to rest/back to original */
|
|
var() Vector MovementVector;
|
|
|
|
/** Amount of time to handle move */
|
|
var() float MovementTime;
|
|
|
|
/** Movement curve */
|
|
var InterpCurveVector MovementCurve;
|
|
|
|
/** Sounds for start and end of various phases */
|
|
var() AkEvent ActivationStart;
|
|
var() AkEvent ActivationEnd;
|
|
var() AkEvent DeactivationStart;
|
|
var() AkEvent DeactivationEnd;
|
|
|
|
var AkComponent CageSFXComponent;
|
|
var AkEvent CurStartSound;
|
|
var AkEvent CurEndSound;
|
|
|
|
/** VFX for start and end of various phases */
|
|
var() ParticleSystemComponent ActivationStartFX;
|
|
var() ParticleSystemComponent ActivationEndFX;
|
|
var() ParticleSystemComponent DeactivationStartFX;
|
|
var() ParticleSystemComponent DeactivationEndFX;
|
|
|
|
var ParticleSystemComponent CurStartFX;
|
|
var ParticleSystemComponent CurEndFX;
|
|
|
|
replication
|
|
{
|
|
if (Role == ROLE_Authority)
|
|
bActivated;
|
|
}
|
|
|
|
simulated event ReplicatedEvent(name VarName)
|
|
{
|
|
super.ReplicatedEvent(VarName);
|
|
|
|
if (VarName == 'bActivated')
|
|
{
|
|
if (bActivated)
|
|
{
|
|
PlayActivation();
|
|
}
|
|
else
|
|
{
|
|
PlayDeactivation();
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated event PostBeginPlay()
|
|
{
|
|
super.PostBeginPlay();
|
|
SkeletalMeshComponent.PlayAnim(DeactivatedIdleAnim, , true);
|
|
SetTickIsDisabled(false);
|
|
}
|
|
|
|
/** 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;
|
|
}
|
|
|
|
function Activated(KFTrigger_MinigameButton ActivationSource)
|
|
{
|
|
if (!bActivated)
|
|
{
|
|
ClearTimer('PlayDeactivationIdle');
|
|
bActivated = true;
|
|
PlayActivation();
|
|
}
|
|
}
|
|
|
|
function Deactivated()
|
|
{
|
|
if (bActivated)
|
|
{
|
|
ClearTimer('ActivationIdle');
|
|
bActivated = false;
|
|
PlayDeactivation();
|
|
}
|
|
}
|
|
|
|
/** Bunch of animation code. Activation->Idle and Deactivation->Idle basically work as pairs trigged by a minigame button. */
|
|
simulated function PlayActivation()
|
|
{
|
|
SkeletalMeshComponent.StopAnim();
|
|
if (ActivationAnim != '')
|
|
{
|
|
SetTimer(SkeletalMeshComponent.GetAnimLength(ActivationAnim), false, 'PlayActivationIdle');
|
|
SkeletalMeshComponent.PlayAnim(ActivationAnim);
|
|
}
|
|
else
|
|
{
|
|
PlayActivationIdle();
|
|
}
|
|
|
|
CurStartSound = ActivationStart;
|
|
CurEndSound = ActivationEnd;
|
|
CurStartFX = ActivationStartFX;
|
|
CurEndFX = ActivationEndFX;
|
|
SetMoveActivationCurve();
|
|
}
|
|
|
|
simulated function PlayActivationIdle()
|
|
{
|
|
SkeletalMeshComponent.StopAnim();
|
|
if (ActivatedIdleAnim != '')
|
|
{
|
|
SkeletalMeshComponent.PlayAnim(ActivatedIdleAnim,,true);
|
|
}
|
|
}
|
|
|
|
simulated function PlayDeactivation()
|
|
{
|
|
SkeletalMeshComponent.StopAnim();
|
|
if (DeactivationAnim != '')
|
|
{
|
|
SetTimer(SkeletalMeshComponent.GetAnimLength(DeactivationAnim), false, 'PlayDeactivationIdle');
|
|
SkeletalMeshComponent.PlayAnim(DeactivationAnim);
|
|
}
|
|
else
|
|
{
|
|
PlayDeactivationIdle();
|
|
}
|
|
|
|
CurStartSound = DeactivationStart;
|
|
CurEndSound = DeactivationEnd;
|
|
CurStartFX = DeactivationStartFX;
|
|
CurEndFX = DeactivationEndFX;
|
|
SetMoveDeactivationCurve();
|
|
}
|
|
|
|
simulated function PlayDeactivationIdle()
|
|
{
|
|
SkeletalMeshComponent.StopAnim();
|
|
if (DeactivatedIdleAnim != '')
|
|
{
|
|
SkeletalMeshComponent.PlayAnim(DeactivatedIdleAnim, , true);
|
|
}
|
|
}
|
|
|
|
/** Curves for movement in and out of the activated idle point */
|
|
simulated function SetMoveActivationCurve()
|
|
{
|
|
MovementCurve.Points.Length = 2;
|
|
|
|
MovementCurve.Points[0].InVal = 0;
|
|
MovementCurve.Points[0].OutVal = Location;
|
|
MovementCurve.Points[0].InterpMode = CIM_CurveAuto;
|
|
|
|
MovementCurve.Points[1].InVal = MovementTime;
|
|
MovementCurve.Points[1].OutVal = Location + MovementVector;
|
|
MovementCurve.Points[1].InterpMode = CIM_CurveAuto;
|
|
|
|
GoToState('Moving');
|
|
}
|
|
|
|
simulated function SetMoveDeactivationCurve()
|
|
{
|
|
MovementCurve.Points.Length = 2;
|
|
|
|
MovementCurve.Points[0].InVal = 0;
|
|
MovementCurve.Points[0].OutVal = Location;
|
|
MovementCurve.Points[0].InterpMode = CIM_CurveAuto;
|
|
|
|
MovementCurve.Points[1].InVal = MovementTime;
|
|
MovementCurve.Points[1].OutVal = Location - MovementVector;
|
|
MovementCurve.Points[1].InterpMode = CIM_CurveAuto;
|
|
|
|
GoToState('Moving');
|
|
}
|
|
|
|
/** Only allow activation while not in the moving state */
|
|
function bool CanBeActivated(KFTrigger_MinigameButton ActivationSource)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
simulated function EndMovement();
|
|
simulated state Moving
|
|
{
|
|
simulated event BeginState(Name PreviousStateName)
|
|
{
|
|
super.BeginState(PreviousStateName);
|
|
SetTimer(MovementTime, false, 'EndMovement');
|
|
CageSFXComponent.PlayEvent(CurStartSound, , false, true);
|
|
CurStartFX.ActivateSystem(true);
|
|
}
|
|
|
|
simulated event Tick(float DeltaTime)
|
|
{
|
|
local float TimerCount;
|
|
global.Tick(DeltaTime);
|
|
|
|
//Watch for return to 0 on last tick when timer finishes
|
|
TimerCount = GetTimerCount('EndMovement');
|
|
if (TimerCount > 0)
|
|
{
|
|
SetLocation(EvalInterpCurveVector(MovementCurve, TimerCount));
|
|
}
|
|
}
|
|
|
|
simulated function EndMovement()
|
|
{
|
|
CageSFXComponent.PlayEvent(CurEndSound, , false, true);
|
|
CurEndFX.ActivateSystem(true);
|
|
GoToState('Auto');
|
|
}
|
|
|
|
/** Don't allow activation while it's moving */
|
|
function bool CanBeActivated(KFTrigger_MinigameButton ActivationSource)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
RemoteRole = ROLE_SimulatedProxy
|
|
NetPriority = +00002.500000
|
|
bUpdateSimulatedPosition = true
|
|
bAlwaysRelevant = true
|
|
|
|
Begin Object class=AkComponent Name=CageSFX0
|
|
End Object
|
|
CageSFXComponent=CageSFX0
|
|
Components.Add(CageSFX0)
|
|
|
|
Begin Object class=ParticleSystemComponent Name=PSC0
|
|
bAutoActivate=false
|
|
End Object
|
|
ActivationStartFX=PSC0
|
|
Components.Add(PSC0)
|
|
|
|
Begin Object class=ParticleSystemComponent Name=PSC1
|
|
bAutoActivate=false
|
|
End Object
|
|
ActivationEndFX=PSC1
|
|
Components.Add(PSC1)
|
|
|
|
Begin Object class=ParticleSystemComponent Name=PSC2
|
|
bAutoActivate=false
|
|
End Object
|
|
DeactivationStartFX=PSC2
|
|
Components.Add(PSC2)
|
|
|
|
Begin Object class=ParticleSystemComponent Name=PSC3
|
|
bAutoActivate=false
|
|
End Object
|
|
DeactivationEndFX=PSC3
|
|
Components.Add(PSC3)
|
|
} |