rott/kf_sources/FrightScript/Classes/ContainerCrane.uc
2026-07-14 20:27:09 +07:00

180 lines
5.3 KiB
Ucode

/*
--------------------------------------------------------------
Container Crane
--------------------------------------------------------------
An Animated Container Crane mesh whos animation is controlled by the
the progress state of an Objective condition.
Animation is played only on the client.
Author : Alex Quick
--------------------------------------------------------------
*/
class ContainerCrane extends Actor
placeable;
// Tag of the condition which control's this Crane's animation.
var () const name AssociatedConditionTag;
// Object reference to the condition which controls this Crane's animation
var private KF_ObjectiveCondition AssociatedCondition;
// Name of the animation the Crane plays when its lowering / raising its winch.
var () const name WinchLoweringAnim;
// The Current frame the animation is playing (used for interpolation)
var float CurrentAnimFramePct;
// The last position in the animation expressed as a percent.
var float LastAnimFramePct;
// True if the animation is not playing in reverse.
var bool bPlayingForward;
// Struct representing a sound effect we should play at some time during the animation.
struct SAnimSoundEffect
{
// reference to the actual sound in the package.
var () sound SoundToPlay;
// The frame %age to start playing the sound at. (i.e In a 600 frame animation if you want to play at frame 300, this value should be 0.5 )
var () float StartFramePct;
// the frame %age to stop playing the sound at.
var () float EndFramePct;
// Is this a looping sound or not. If not, 'EndFramePct' has no actual relevance.
var () bool bLooping;
// Has this sound been played already? Only has real relevance to non-looping sounds.
var bool bPlayed;
};
var () array<SAnimSoundEffect> AnimSounds;
var float ConditionCompletionPct;
replication
{
unreliable if(Role == Role_Authority && bNetDirty)
ConditionCompletionPct;
}
function PostbeginPlay()
{
local KF_ObjectiveCondition Condition;
foreach AllObjects(class 'KF_ObjectiveCondition', Condition)
{
if(Condition.Tag == AssociatedConditionTag)
{
AssociatedCondition = Condition;
NetupdateFrequency = 1.f / Condition.ConditionRepInterval; // Sync net update rates.
break;
}
}
}
simulated function Tick(float DeltaTime)
{
local bool bOldDirection;
local int i;
if(Role == Role_Authority && AssociatedCondition != none && AssociatedCondition.bActive)
{
ConditionCompletionPct = AssociatedCondition.GetCompletionPct();
}
LastAnimFramePct = CurrentAnimFramePct;
CurrentAnimFramePct = Lerp(DeltaTime,CurrentAnimFramePct,ConditionCompletionPct);
bOldDirection = bPlayingForward;
bPlayingForward = CurrentAnimFramePct >= LastAnimFramePct;
// Animation is reversing , reset sounds.
if(Role == Role_Authority && bOldDirection != bPlayingForward)
{
for(i = 0 ; i < AnimSounds.length ; i ++)
{
AnimSounds[i].bPlayed = false;
}
}
if(Level.NetMode != NM_DedicatedServer &&
ConditionCompletionPct != CurrentAnimFramePct &&
ConditionCompletionPct < 1.f)
{
SetAnimFramePct(CurrentAnimFramePct);
}
if(CurrentAnimFramePct > 0.f)
{
PlayAnimSounds(CurrentAnimFramePct);
}
}
function PlayAnimSounds(float CurrentPct)
{
local int i;
local Sound AmbSoundToPlay;
local bool bShouldPlaySound;
local bool bReversing;
if(Role < Role_Authority)
{
return;
}
for(i = 0 ; i < AnimSounds.length ; i ++)
{
if(AnimSounds[i].SoundToPlay != none)
{
bReversing = !bPlayingForward;
// Play Looped sounds. There can only be one of these at a time.
if(AnimSounds[i].bLooping)
{
bShouldPlaySound = CurrentPct >= AnimSounds[i].StartFramePct && (AnimSounds[i].EndFramePct == 0.f || CurrentPct <= AnimSounds[i].EndFramePct) ;
if(bShouldPlaySound)
{
AnimSounds[i].bPlayed = true;
AmbSoundToPlay = AnimSounds[i].SoundToPlay;
}
}
else // Play one-off sounds. These can overlap.
{
bShouldPlaySound = !AnimSounds[i].bPlayed && CurrentPct >= AnimSounds[i].StartFramePct ;
if(bShouldPlaySound)
{
AnimSounds[i].bPlayed = true;
PlaySound(AnimSounds[i].SoundToPlay,SLOT_None,((SoundVolume/255) * 2.0),true,SoundRadius,,!bFullVolume);
}
}
}
}
if(AmbSoundToPlay != AmbientSound)
{
AmbientSound = AmbSoundToPlay;
}
}
simulated function SetAnimFramePct( float NewPct)
{
PlayAnim( WinchLoweringAnim, 1.0f,0.f);
SetAnimFrame(NewPct,0);
}
defaultproperties
{
bAlwaysRelevant = true
bNoDelete = true
RemoteRole = Role_SimulatedProxy
SoundRadius = 2000
SoundVolume = 255
bFullVolume = true
DrawType = DT_Mesh
Mesh = Mesh 'FrightYard_SKM.SKM_DockCrane'
WinchLoweringAnim="LowerCrane"
}