1
0
KF2-Dev-Scripts/KFGame/Classes/KFDynamicFogAndDamageVolumeInfo.uc

371 lines
10 KiB
Ucode
Raw Permalink Normal View History

2020-12-13 15:01:13 +00:00
//=============================================================================
// KFDynamicFogAndDamageVolumeInfo
//=============================================================================
// A fog volume that can be dynamically blended in and out, and which can
// also damage actors within the bounds of the volume
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// - John "Ramm-Jaeger" Gibson
//=============================================================================
class KFDynamicFogAndDamageVolumeInfo extends FogVolumeConstantDensityInfo
showcategories(Movement)
placeable;
/** The spawn group setup of a wave */
/** This property allows the fog volume to damage a player as long as they are within it. Using a negative value will allow the volume to have a regenerative effect. NB. bPainCausing must be set to TRUE to activate this */
var() float DamagePerSec;
/** When damage is applied to an object, it is done so using a specific DamageType. Each available DamageType has a KDamageImpulse property which controls the magnitude of the impulse to be applied along the momentum vector. */
var() class<DamageType> DamageType<AllowAbstract>;
/** This property activates the ability to cause damage. Used in conjunction with DamagePerSecond and PainInterval */
var() bool bPainCausing;
/** Amount of time, in seconds, between damage applications. NB. bPainCausing must be set to TRUE to activate this */
var() float PainInterval;
/** True if this volume should damage zeds */
var() bool bDamageZeds;
/** How long to take to blend fog in/out. Note: Damage blends in/out with the fading */
var() float FogBlendTime;
/** The remaining time for this fog blend transition */
var float FogBlendTimeRemaining;
/** Fog is blending in */
var bool bBlendingFogIn;
/** Fog is blending out */
var bool bBlendingFogOut;
/** Stores the old value of bEnabled for checking against */
var bool bOldEnabled;
/** Fog is blending out */
var repnotify byte FogBlendAmountRep;
/** What was the density when this fog volume spawned */
var float InitialDensity;
/** What is the current fog density */
var float CurrentDensity;
/** Temp message to play when this volume activates */
var() String ActivateMessage;
/** Temp message to play when this volume deactivates */
var() String DeactivateMessage;
replication
{
if (Role == ROLE_Authority)
FogBlendAmountRep;
}
simulated event PostBeginPlay()
{
Super.PostBeginPlay();
// Store the initial density
InitialDensity = FogVolumeConstantDensityComponent(DensityComponent).Density;
CurrentDensity = InitialDensity;
// Clear the density if it's not enabled, so it won't pop in with density
if( !bEnabled )
{
FogVolumeConstantDensityComponent(DensityComponent).Density = 0;
ReattachComponent(DensityComponent);
}
if ( Role < ROLE_Authority )
return;
if ( bPainCausing )
{
SetTimer(PainInterval, true, nameof(TimerPop));
}
}
simulated event ReplicatedEvent(name VarName)
{
local float BlendedFogAmount;
if (VarName == 'FogBlendAmountRep')
{
BlendedFogAmount = Float(FogBlendAmountRep)/255.0;
SetFogDensity( BlendedFogAmount );
}
else if (VarName != 'bEnabled')
{
Super.ReplicatedEvent(VarName);
}
}
/* epic ===============================================
* ::OnToggle
*
* Scripted support for toggling height fog, checks which
* operation to perform by looking at the action input.
*
* Input 1: turn on
* Input 2: turn off
* Input 3: toggle
*
* =====================================================
*/
simulated function OnToggle(SeqAct_Toggle action)
{
if (action.InputLinks[0].bHasImpulse)
{
// turn on
StartBlendIn();
}
else if (action.InputLinks[1].bHasImpulse)
{
// turn off
StartBlendOut();
}
else if (action.InputLinks[2].bHasImpulse)
{
// toggle
if( bEnabled )
{
StartBlendOut();
}
else
{
StartBlendIn();
}
}
}
/** Set the fog density and handle setting replicated fog density */
simulated function SetFogDensity( float NewDensity )
{
if ( Role < ROLE_Authority )
{
if( NewDensity == 0 )
{
if( bOldEnabled )
Deactivate();
}
else
{
if( !bOldEnabled )
Activate();
}
}
FogVolumeConstantDensityComponent(DensityComponent).Density = NewDensity * InitialDensity;
CurrentDensity = FogVolumeConstantDensityComponent(DensityComponent).Density;
if ( Role == ROLE_Authority )
{
FogBlendAmountRep = CurrentDensity/InitialDensity * 255;
bNetDirty = true;
bForceNetUpdate = TRUE;
}
//`log("FogBlendAmountRep = "$FogBlendAmountRep$" CurrentDensity = "$CurrentDensity$" InitialDensity = "$InitialDensity);
// Must reattach the component to get the fog values to change. TODO: this may be expensive, so might need a graphics programmer to improve this
if( WorldInfo.NetMode != NM_DedicatedServer )
{
ReattachComponent(DensityComponent);
}
}
event Tick( float DeltaTime )
{
if ( Role < ROLE_Authority )
return;
if( bBlendingFogIn )
{
FogBlendTimeRemaining -= DeltaTime;
if( FogBlendTimeRemaining <= 0 )
{
SetFogDensity( 1.0 );
bBlendingFogIn=false;
//`log("Blending in complete, density = "$FogVolumeConstantDensityComponent(DensityComponent).Density);
}
else
{
SetFogDensity( 1.0 - (FogBlendTimeRemaining/FogBlendTime) );
//`log("Blending in, density = "$FogVolumeConstantDensityComponent(DensityComponent).Density$" blend time: "$(FogBlendTimeRemaining/FogBlendTime));
}
}
else if( bBlendingFogOut )
{
FogBlendTimeRemaining -= DeltaTime;
if( FogBlendTimeRemaining <= 0 )
{
SetFogDensity( 0 );
bBlendingFogOut=false;
//`log("Blending out complete, density = "$FogVolumeConstantDensityComponent(DensityComponent).Density);
Deactivate();
}
else
{
SetFogDensity( FogBlendTimeRemaining/FogBlendTime );
//`log("Blending out, density = "$FogVolumeConstantDensityComponent(DensityComponent).Density$" blend time: "$(FogBlendTimeRemaining/FogBlendTime));
}
}
}
event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
{
Super.Touch(Other, OtherComp, HitLocation, HitNormal);
if ( (Other == None) || Other.bStatic )
return;
if ( bPainCausing )
{
if ( Other.bCanBeDamaged )
{
if( bEnabled )
{
CausePainTo(Other);
}
}
}
}
function CausePainTo(Actor Other)
{
if( !bDamageZeds && KFPawn_Monster(Other) != none )
{
return;
}
if (DamagePerSec > 0)
{
if ( (DamageType == None) || (DamageType == class'DamageType') )
`log("No valid damagetype ("$DamageType$") specified for "$PathName(self));
Other.TakeDamage(DamagePerSec*PainInterval*(CurrentDensity/InitialDensity), none/*DamageInstigator*/, Location, vect(0,0,1), DamageType,, self);
//`log("Damaging other for "$DamagePerSec*PainInterval*(CurrentDensity/InitialDensity));
}
else
{
Other.HealDamage(-DamagePerSec * PainInterval*(CurrentDensity/InitialDensity), none/*DamageInstigator*/, DamageType);
}
}
/*
TimerPop
damage touched actors if pain causing.
*/
function TimerPop()
{
local Actor A;
if( !bEnabled )
{
return;
}
if ( !bPainCausing )
return;
ForEach TouchingActors(class'Actor', A)
{
if ( A.bCanBeDamaged && !A.bStatic )
{
CausePainTo(A);
}
}
}
/** Activate this fog volume */
simulated function Activate()
{
SetEnabled( true );
TempMessagePlayers( ActivateMessage );
}
/** Deactivate this fog volume */
simulated function Deactivate()
{
if( bEnabled )
{
TempMessagePlayers( DeactivateMessage );
}
SetEnabled( false );
}
/** Blend in and activate this fog volume */
simulated function StartBlendIn()
{
Activate();
bBlendingFogIn = true;
bBlendingFogOut = false;
FogBlendTimeRemaining = FogBlendTime;
}
/** Blend out and deactivate this fog volume */
simulated function StartBlendOut()
{
if( bEnabled )
{
bBlendingFogOut = true;
bBlendingFogIn = false;
FogBlendTimeRemaining = FogBlendTime;
}
}
/** Toggled the enabled setting for this fog volume */
simulated function SetEnabled( bool bNewEnabled )
{
DensityComponent.SetEnabled(bNewEnabled);
bEnabled = DensityComponent.bEnabled;
bOldEnabled = bEnabled;
ForceNetRelevant();
SetForcedInitialReplicatedProperty(Property'Engine.FogVolumeDensityInfo.bEnabled', (bEnabled == default.bEnabled));
NetUpdateFrequency = 5.0;
}
/** Temporary method of handling messaging the players for this volume */
simulated function TempMessagePlayers( coerce String Msg )
{
`if(`notdefined(FINAL_RELEASE))
local KFPlayerController KFPC;
`log( "!!!!"@Msg@"!!!!" );
foreach LocalPlayerControllers(class'KFPlayerController', KFPC)
{
KFPC.MyGFxHUD.ShowNonCriticalMessage( Msg );
}
`endif
}
defaultproperties
{
Begin Object Name=AutomaticMeshComponent0
CollideActors=true
StaticMesh=StaticMesh'EngineMeshes.Cube'
bCastDynamicShadow=FALSE
BlockActors=false
BlockZeroExtent=false
BlockNonZeroExtent=true
BlockRigidBody=false
bForceDirectLightMap=FALSE
bAcceptsDynamicLights=FALSE
bAcceptsLights=FALSE
CastShadow=FALSE
bUsePrecomputedShadows=FALSE
bAcceptsStaticDecals=FALSE
bAcceptsDynamicDecals=FALSE
bUseAsOccluder=FALSE
bSelectable=FALSE
bIgnoreOwnerHidden=TRUE
WireframeColor=(R=100,G=100,B=200,A=255)
End Object
bCollideActors=True
DamageType=class'Engine.DamageType'
PainInterval=1.f
FogBlendTime=3.0
}