517 lines
16 KiB
Ucode
517 lines
16 KiB
Ucode
//=============================================================================
|
|
// KFTrigger_MinigameGenerator
|
|
//=============================================================================
|
|
// Trigger used to activate all minigames in a level
|
|
//=============================================================================
|
|
// Killing Floor 2
|
|
// Copyright (C) 2015 Tripwire Interactive LLC
|
|
// - Dan Weiss
|
|
//=============================================================================
|
|
|
|
class KFTrigger_MinigameGenerator extends Trigger_PawnsOnly
|
|
config(Game)
|
|
implements(KFInterface_Usable);
|
|
|
|
/** Amount of time (in seconds) that the generator should remain running */
|
|
var() float ActiveTime;
|
|
|
|
/** Amount of time until the generator can be reactivated */
|
|
var() float ReactivationTime;
|
|
|
|
var bool bActiveGenerator;
|
|
var bool bCanBeActivated;
|
|
|
|
var array<KFTrigger_MinigameButton> LevelButtons;
|
|
|
|
/** Objective index for the event this is tied to */
|
|
var() int ObjectiveIndex;
|
|
|
|
/** Index of the event this is tied to */
|
|
var() int EventIndex;
|
|
|
|
/** Amount of time remaining until the generator shuts off */
|
|
var repnotify byte GeneratorTimeRemaining;
|
|
var float PreviousTimeRemaining;
|
|
|
|
/** Actor reference showing status indicator */
|
|
var() array<StaticMeshActor> GeneratorStatusIndicators;
|
|
|
|
/** Material slot to use for the status modification */
|
|
var() int GlowIndex;
|
|
|
|
struct GeneratorStatus
|
|
{
|
|
var() float MinTimeRemaining;
|
|
var() LinearColor StatusColor;
|
|
};
|
|
|
|
var() array<GeneratorStatus> StatusIndicator;
|
|
var int CurrentStatusIndex;
|
|
|
|
struct EmissiveActor
|
|
{
|
|
var() Actor EmissiveActor;
|
|
var float GeneratorOnValue;
|
|
var float GeneratorOffValue;
|
|
|
|
structdefaultproperties
|
|
{
|
|
GeneratorOnValue=0.f
|
|
GeneratorOffValue=0.f
|
|
}
|
|
};
|
|
|
|
struct EmissiveUpdateActorList
|
|
{
|
|
var() float ActivationDelay;
|
|
var() array<Actor> ActorList;
|
|
var array<EmissiveActor> CachedActorList;
|
|
};
|
|
|
|
var() array<EmissiveUpdateActorList> MapEmissiveActorList;
|
|
var int CurrentEmissiveActorListIndex;
|
|
|
|
replication
|
|
{
|
|
if (bNetDirty)
|
|
GeneratorTimeRemaining;
|
|
}
|
|
|
|
simulated event ReplicatedEvent(name VarName)
|
|
{
|
|
if (VarName == 'GeneratorTimeRemaining')
|
|
{
|
|
UpdateGeneratorStatus();
|
|
}
|
|
else
|
|
{
|
|
super.ReplicatedEvent(VarName);
|
|
}
|
|
}
|
|
|
|
function Tick(float DeltaTime)
|
|
{
|
|
super.Tick(DeltaTime);
|
|
|
|
if (bActiveGenerator)
|
|
{
|
|
GeneratorTimeRemaining = FloatToByte(GetRemainingTimeForTimer('DeactivateMinigames') / ActiveTime);
|
|
UpdateGeneratorStatus();
|
|
}
|
|
}
|
|
|
|
simulated function UpdateGeneratorStatus()
|
|
{
|
|
local float CurrentTimeRemaining;
|
|
local LinearColor ParamColor;
|
|
local bool bStatusChange;
|
|
local int CurIndex;
|
|
local int i;
|
|
|
|
if (WorldInfo.NetMode != NM_DedicatedServer && StatusIndicator.Length > 0)
|
|
{
|
|
CurIndex = CurrentStatusIndex;
|
|
CurrentTimeRemaining = ByteToFloat(GeneratorTimeRemaining);
|
|
|
|
//Reset or first startup
|
|
if (PreviousTimeRemaining < CurrentTimeRemaining)
|
|
{
|
|
CurrentStatusIndex = 0;
|
|
if (CurrentTimeRemaining > 0)
|
|
{
|
|
EnableEmissiveActors();
|
|
}
|
|
}
|
|
|
|
//Update if we've gone past the time required for current color
|
|
if (StatusIndicator[CurrentStatusIndex].MinTimeRemaining > CurrentTimeRemaining)
|
|
{
|
|
for (CurrentStatusIndex = 0; CurrentStatusIndex < StatusIndicator.Length; ++CurrentStatusIndex)
|
|
{
|
|
if (StatusIndicator[CurrentStatusIndex].MinTimeRemaining < CurrentTimeRemaining)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
CurrentStatusIndex = Min(CurrentStatusIndex, StatusIndicator.Length - 1);
|
|
|
|
//Check for change and update color if necessary
|
|
bStatusChange = CurrentStatusIndex != CurIndex;
|
|
if (bStatusChange && GeneratorStatusIndicators.Length > 0 )
|
|
{
|
|
ParamColor = StatusIndicator[CurrentStatusIndex].StatusColor;
|
|
for (i = 0; i < GeneratorStatusIndicators.Length; ++i)
|
|
{
|
|
if (MaterialInstance(GeneratorStatusIndicators[i].StaticMeshComponent.GetMaterial(GlowIndex)) != none)
|
|
{
|
|
MaterialInstance(GeneratorStatusIndicators[i].StaticMeshComponent.GetMaterial(GlowIndex)).SetVectorParameterValue('Scalar_Glow_color', ParamColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
PreviousTimeRemaining = CurrentTimeRemaining;
|
|
|
|
if (CurrentTimeRemaining <= 0)
|
|
{
|
|
DisableEmissiveActors();
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function EnableEmissiveActors()
|
|
{
|
|
CurrentEmissiveActorListIndex = 0;
|
|
if (MapEmissiveActorList.Length > 0)
|
|
{
|
|
if (MapEmissiveActorList[0].ActivationDelay > 0.f)
|
|
{
|
|
SetTimer(MapEmissiveActorList[0].ActivationDelay, false, nameof(EnableNextEmissiveList));
|
|
}
|
|
else
|
|
{
|
|
EnableNextEmissiveList();
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function EnableNextEmissiveList()
|
|
{
|
|
local EmissiveActor CurrentActor;
|
|
local int i;
|
|
local StaticMeshActor Smesh;
|
|
local SkeletalMeshActor Skmesh;
|
|
local MaterialInstance MatInst;
|
|
|
|
if (MapEmissiveActorList[CurrentEmissiveActorListIndex].ActorList.Length > 0)
|
|
{
|
|
foreach MapEmissiveActorList[CurrentEmissiveActorListIndex].CachedActorList(CurrentActor)
|
|
{
|
|
Smesh = StaticMeshActor(CurrentActor.EmissiveActor);
|
|
Skmesh = SkeletalMeshActor(CurrentActor.EmissiveActor);
|
|
if (Smesh != none)
|
|
{
|
|
for (i = 0; i < Smesh.StaticMeshComponent.Materials.Length; ++i)
|
|
{
|
|
MatInst = MaterialInstance(Smesh.StaticMeshComponent.GetMaterial(i));
|
|
if (MatInst != None)
|
|
{
|
|
MatInst.SetScalarParameterValue('Scalar_Emissive_Intensity', CurrentActor.GeneratorOnValue);
|
|
}
|
|
}
|
|
}
|
|
else if (Skmesh != none)
|
|
{
|
|
for (i = 0; i < Skmesh.SkeletalMeshComponent.Materials.Length; ++i)
|
|
{
|
|
MatInst = MaterialInstance(Skmesh.SkeletalMeshComponent.GetMaterial(i));
|
|
if (MatInst != None)
|
|
{
|
|
MatInst.SetScalarParameterValue('Scalar_Emissive_Intensity', CurrentActor.GeneratorOnValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CurrentEmissiveActorListIndex++;
|
|
if (CurrentEmissiveActorListIndex < MapEmissiveActorList.Length)
|
|
{
|
|
if (MapEmissiveActorList[CurrentEmissiveActorListIndex].ActivationDelay > 0.f)
|
|
{
|
|
SetTimer(MapEmissiveActorList[CurrentEmissiveActorListIndex].ActivationDelay - MapEmissiveActorList[CurrentEmissiveActorListIndex - 1].ActivationDelay, false, nameof(EnableNextEmissiveList));
|
|
}
|
|
else
|
|
{
|
|
EnableNextEmissiveList();
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function DisableEmissiveActors()
|
|
{
|
|
local EmissiveUpdateActorList CurrentList;
|
|
local EmissiveActor CurrentActor;
|
|
local int i;
|
|
local StaticMeshActor Smesh;
|
|
local SkeletalMeshActor Skmesh;
|
|
local MaterialInstance MatInst;
|
|
|
|
foreach MapEmissiveActorList(CurrentList)
|
|
{
|
|
foreach CurrentList.CachedActorList(CurrentActor)
|
|
{
|
|
Smesh = StaticMeshActor(CurrentActor.EmissiveActor);
|
|
Skmesh = SkeletalMeshActor(CurrentActor.EmissiveActor);
|
|
if (Smesh != none)
|
|
{
|
|
for (i = 0; i < Smesh.StaticMeshComponent.Materials.Length; ++i)
|
|
{
|
|
MatInst = MaterialInstance(Smesh.StaticMeshComponent.GetMaterial(i));
|
|
if (MatInst != None)
|
|
{
|
|
MatInst.SetScalarParameterValue('Scalar_Emissive_Intensity', CurrentActor.GeneratorOffValue);
|
|
}
|
|
}
|
|
}
|
|
else if (Skmesh != none)
|
|
{
|
|
for (i = 0; i < Skmesh.SkeletalMeshComponent.Materials.Length; ++i)
|
|
{
|
|
MatInst = MaterialInstance(Skmesh.SkeletalMeshComponent.GetMaterial(i));
|
|
if (MatInst != None)
|
|
{
|
|
MatInst.SetScalarParameterValue('Scalar_Emissive_Intensity', CurrentActor.GeneratorOffValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function InitEmissiveActors()
|
|
{
|
|
local EmissiveActor NewActor;
|
|
local int i, j, k;
|
|
local StaticMeshActor Smesh;
|
|
local SkeletalMeshActor Skmesh;
|
|
local float CurValue;
|
|
|
|
for (i = 0; i < MapEmissiveActorList.Length; ++i)
|
|
{
|
|
for (j = 0; j < MapEmissiveActorList[i].ActorList.Length; ++j)
|
|
{
|
|
Smesh = StaticMeshActor(MapEmissiveActorList[i].ActorList[j]);
|
|
Skmesh = SkeletalMeshActor(MapEmissiveActorList[i].ActorList[j]);
|
|
NewActor.EmissiveActor = MapEmissiveActorList[i].ActorList[j];
|
|
k = 0;
|
|
if (Smesh != none)
|
|
{
|
|
while (Smesh.StaticMeshComponent.GetMaterial(k) != none)
|
|
{
|
|
Smesh.StaticMeshComponent.CreateAndSetMaterialInstanceConstant(k);
|
|
MaterialInstance(Smesh.StaticMeshComponent.GetMaterial(k)).Parent.GetScalarParameterValue('Scalar_Emissive_Intensity', CurValue);
|
|
++k;
|
|
NewActor.GeneratorOnValue = Max(CurValue, NewActor.GeneratorOnValue);
|
|
}
|
|
}
|
|
else if (Skmesh != none)
|
|
{
|
|
while (Skmesh.SkeletalMeshComponent.GetMaterial(k) != none)
|
|
{
|
|
Skmesh.SkeletalMeshComponent.CreateAndSetMaterialInstanceConstant(k);
|
|
MaterialInstance(Skmesh.SkeletalMeshComponent.GetMaterial(k)).Parent.GetScalarParameterValue('Scalar_Emissive_Intensity', NewActor.GeneratorOnValue);
|
|
++k;
|
|
NewActor.GeneratorOnValue = Max(CurValue, NewActor.GeneratorOnValue);
|
|
}
|
|
}
|
|
MapEmissiveActorList[i].CachedActorList.AddItem(NewActor);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** KFInterface_Usable */
|
|
simulated function bool GetIsUsable(Pawn User)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/** KFInterface_Usable */
|
|
simulated function int GetInteractionIndex(Pawn User)
|
|
{
|
|
return IMT_UseMinigameGenerator;
|
|
}
|
|
|
|
/** HUD */
|
|
event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal)
|
|
{
|
|
super.Touch(Other, OtherComp, HitLocation, HitNormal);
|
|
class'KFPlayerController'.static.UpdateInteractionMessages(Other);
|
|
}
|
|
|
|
/** HUD */
|
|
event UnTouch(Actor Other)
|
|
{
|
|
super.UnTouch(Other);
|
|
class'KFPlayerController'.static.UpdateInteractionMessages(Other);
|
|
}
|
|
|
|
/** Cache all minigame triggers at startup so we don't have to do all actors every activation */
|
|
simulated function PostBeginPlay()
|
|
{
|
|
local KFTrigger_MinigameButton MinigameTrigger;
|
|
local int i;
|
|
|
|
super.PostBeginPlay();
|
|
|
|
if (Role == ROLE_Authority)
|
|
{
|
|
foreach WorldInfo.AllActors(class'KFTrigger_MinigameButton', MinigameTrigger)
|
|
{
|
|
LevelButtons.AddItem(MinigameTrigger);
|
|
}
|
|
}
|
|
|
|
if (WorldInfo.NetMode != NM_DedicatedServer)
|
|
{
|
|
if (GeneratorStatusIndicators.Length > 0 && GlowIndex >= 0)
|
|
{
|
|
for (i = 0; i < GeneratorStatusIndicators.Length; ++i)
|
|
{
|
|
if (GlowIndex < GeneratorStatusIndicators[i].StaticMeshComponent.Materials.Length)
|
|
{
|
|
GeneratorStatusIndicators[i].StaticMeshComponent.CreateAndSetMaterialInstanceConstant(GlowIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
InitEmissiveActors();
|
|
UpdateGeneratorStatus();
|
|
}
|
|
}
|
|
|
|
/** Handles trigger interaction */
|
|
function bool UsedBy(Pawn User)
|
|
{
|
|
if (bCanBeActivated)
|
|
{
|
|
//Clear any timer that was already started, treat this as a full reactivation of minigames
|
|
ClearTimer('DeactivateMinigames');
|
|
SetTimer(ActiveTime, false, 'DeactivateMinigames');
|
|
|
|
//Set reactivation timer to prevent button spam
|
|
bCanBeActivated = false;
|
|
SetTimer(ReactivationTime, false, 'AllowActivation');
|
|
|
|
ActivateMinigames();
|
|
|
|
//Activate objective completion for turning on generator
|
|
TriggerObjectiveCompletion();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function TriggerObjectiveCompletion()
|
|
{
|
|
local KFPlayercontroller KFPC;
|
|
local bool bIsObjectiveDataValid;
|
|
|
|
bIsObjectiveDataValid = ObjectiveIndex >= 0 && ObjectiveIndex < 5 && EventIndex > SEI_None && EventIndex < SEI_MAX;
|
|
|
|
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
|
|
{
|
|
KFPC.ClientOnTriggerUsed(class'KFTrigger_MinigameGenerator');
|
|
if(bIsObjectiveDataValid)
|
|
{
|
|
KFPC.ClientOnTryCompleteObjective(ObjectiveIndex, EventIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
function AllowActivation()
|
|
{
|
|
local int i;
|
|
|
|
bCanBeActivated = true;
|
|
|
|
for (i = 0; i < Touching.Length; ++i)
|
|
{
|
|
class'KFPlayerController'.static.UpdateInteractionMessages(Touching[i]);
|
|
}
|
|
}
|
|
|
|
/** Handle activation of the generator and minigames in the level */
|
|
function ActivateMinigames()
|
|
{
|
|
local KFTrigger_MinigameButton MinigameButton;
|
|
|
|
//Don't activate if we're simply updating the timer
|
|
if (!bActiveGenerator)
|
|
{
|
|
foreach LevelButtons(MinigameButton)
|
|
{
|
|
MinigameButton.SetMinigameActive();
|
|
}
|
|
|
|
bActiveGenerator = true;
|
|
UpdateGeneratorState();
|
|
}
|
|
else
|
|
{
|
|
GeneratorReactivated();
|
|
}
|
|
}
|
|
|
|
/** Handle deactivation of the generator and minigames in the level */
|
|
function DeactivateMinigames()
|
|
{
|
|
local KFTrigger_MinigameButton MinigameButton;
|
|
|
|
//Don't deactivate if we're already inactive
|
|
if (bActiveGenerator)
|
|
{
|
|
foreach LevelButtons(MinigameButton)
|
|
{
|
|
MinigameButton.SetMinigameInactive();
|
|
}
|
|
|
|
bActiveGenerator = false;
|
|
UpdateGeneratorState();
|
|
GeneratorTimeRemaining = 0;
|
|
UpdateGeneratorStatus();
|
|
}
|
|
}
|
|
|
|
function GeneratorReactivated()
|
|
{
|
|
local KFSeqEvent_MinigameGeneratorStateChanged StateChangeEvent;
|
|
local int i;
|
|
|
|
//Notify Kismet that minigame state has been changed
|
|
for (i = 0; i < GeneratedEvents.Length; i++)
|
|
{
|
|
StateChangeEvent = KFSeqEvent_MinigameGeneratorStateChanged(GeneratedEvents[i]);
|
|
if (StateChangeEvent != none)
|
|
{
|
|
StateChangeEvent.StateChanged(self, self, bActiveGenerator, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
function UpdateGeneratorState()
|
|
{
|
|
local KFSeqEvent_MinigameGeneratorStateChanged StateChangeEvent;
|
|
local int i;
|
|
|
|
//Notify Kismet that minigame state has been changed
|
|
for (i = 0; i < GeneratedEvents.Length; i++)
|
|
{
|
|
StateChangeEvent = KFSeqEvent_MinigameGeneratorStateChanged(GeneratedEvents[i]);
|
|
if (StateChangeEvent != none)
|
|
{
|
|
StateChangeEvent.StateChanged(self, self, bActiveGenerator, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
SupportedEvents.Empty
|
|
SupportedEvents.Add(class'KFSeqEvent_MinigameGeneratorStateChanged')
|
|
|
|
RemoteRole=ROLE_SimulatedProxy
|
|
NetPriority=+00002.500000
|
|
bAlwaysRelevant=true
|
|
|
|
ActiveTime=300.0f
|
|
ReactivationTime=10.0f
|
|
bCanBeActivated=true
|
|
CurrentStatusIndex=-1
|
|
GlowIndex=1
|
|
PreviousTimeRemaining=-1.f
|
|
CurrentEmissiveActorListIndex=-1
|
|
|
|
EventIndex=-1
|
|
ObjectiveIndex=-1
|
|
} |