//============================================================================= // KFSeqAct_StartScriptedPawn //============================================================================= // Action that activates a scripted pawn //============================================================================= // Killing Floor 2 // Copyright (C) 2018 Tripwire Interactive LLC //============================================================================= class KFSeqAct_StartScriptedPawn extends SeqAct_Latent; // Whether pawn should be spawned in an inactive state var() bool bSpawnInactivePawn; static event int GetObjClassVersion() { return Super.GetObjClassVersion() + 1; } event VersionUpdated(int OldVersion, int NewVersion) { local SeqVarLink UpdatedLink; if (OldVersion == 1 && NewVersion == 2) { UpdatedLink.ExpectedType = class'SeqVar_Object'; UpdatedLink.LinkDesc = "KF Scripted Pawn Start"; UpdatedLink.PropertyName = ''; UpdatedLink.MaxVars = 1; VariableLinks[0] = UpdatedLink; UpdatedLink.ExpectedType = class'SequenceVariable'; UpdatedLink.LinkDesc = "Set Initial Health From"; UpdatedLink.PropertyName = ''; UpdatedLink.MaxVars = 1; VariableLinks[1] = UpdatedLink; UpdatedLink.ExpectedType = class'SequenceVariable'; UpdatedLink.LinkDesc = "Set Maximum Health From"; UpdatedLink.PropertyName = ''; UpdatedLink.MaxVars = 1; VariableLinks[2] = UpdatedLink; } } event Activated() { local SequenceVariable SeqVar; local SeqVar_Object ObjVar; local KFScriptedPawnSpawner PawnStart, ReferencePawnStart; if (InputLinks[0].bHasImpulse) { // Grab our pawn start foreach LinkedVariables(class'SeqVar_Object', ObjVar, "KF Scripted Pawn Spawner") { PawnStart = KFScriptedPawnSpawner(ObjVar.GetObjectValue()); break; } // Sanity if (PawnStart == none) { return; } // Grab our health foreach LinkedVariables(class'SequenceVariable', SeqVar, "Set Initial Health From") { if (SeqVar_Float(SeqVar) != none) { PawnStart.PawnHealth = SeqVar_Float(SeqVar).FloatValue; break; } else if (SeqVar_Object(SeqVar) != none) { ReferencePawnStart = KFScriptedPawnSpawner(SeqVar_Object(SeqVar).GetObjectValue()); if (ReferencePawnStart != none) { if (ReferencePawnStart.Pawn != none) { PawnStart.ReferencePawn = ReferencePawnStart.Pawn; PawnStart.bUseReferencePawnHealth = true; break; } } } `warn(self$"::Activated - 'Set Initial Health From' not set to a valid object (Float or KFScriptedPawnSpawner)"); break; } // Grab our health foreach LinkedVariables(class'SequenceVariable', SeqVar, "Set Maximum Health From") { if (SeqVar_Float(SeqVar) != none) { PawnStart.PawnHealthMax = SeqVar_Float(SeqVar).FloatValue; break; } else if (SeqVar_Object(SeqVar) != none) { if (ReferencePawnStart == none) { ReferencePawnStart = KFScriptedPawnSpawner(SeqVar_Object(SeqVar).GetObjectValue()); } if (ReferencePawnStart != none) { if (ReferencePawnStart.Pawn != none) { PawnStart.ReferencePawn = ReferencePawnStart.Pawn; PawnStart.bUseReferencePawnHealthMax = true; break; } } } `warn(self$"::Activated - 'Set Maximum Health From' not set to a valid object (Float or KFScriptedPawnSpawner)"); break; } PawnStart.StartPawn(bSpawnInactivePawn); // Because we want to pulse an output sometime in the future, this needs to be a latent action. // However, for latent actions to stay active, they need latent actors, and their latent actors // need to reference them. There are several ways to accomplish this, but some require native code // (which I want to avoid) and some require using Kismet differently than we currently do // (which I want to avoid). This is the slightly hacky way to get this action to stay active // until the pawn finishes its route, at which point an output is pulsed depending on the success // of the pawn. LatentActors.AddItem(PawnStart); PawnStart.LatentActions.AddItem(self); bAborted = false; } } function CheckPawnFinished(Pawn P) { local SeqVar_Object ObjVar; local KFScriptedPawnSpawner PawnStart; foreach LinkedVariables(class'SeqVar_Object', ObjVar, "KF Scripted Pawn Spawner") { PawnStart = KFScriptedPawnSpawner(ObjVar.GetObjectValue()); break; } if (PawnStart != none) { if (PawnStart.Pawn == P) { if (!PawnStart.Pawn.IsAliveAndWell()) { bAborted = true; } PawnStart.LatentActions.RemoveItem(self); // Removing latent actors is what causes this latent action to end and be deactivated LatentActors.RemoveItem(PawnStart); } } } DefaultProperties { ObjCategory="Killing Floor" ObjName="Spawn Scripted Pawn" InputLinks(0)=(LinkDesc="Start") VariableLinks(0)=(ExpectedType=class'SeqVar_Object',LinkDesc="KF Scripted Pawn Spawner",PropertyName="",MaxVars=1) VariableLinks(1)=(ExpectedType=class'SequenceVariable',LinkDesc="Set Initial Health From",PropertyName="",MaxVars=1) VariableLinks(2)=(ExpectedType=class'SequenceVariable',LinkDesc="Set Maximum Health From",PropertyName="",MaxVars=1) OutputLinks(0)=(LinkDesc="Finish") OutputLinks(1)=(LinkDesc="Fail") bCallHandler=false bAutoActivateOutputLinks=false }