1580 lines
44 KiB
Ucode
1580 lines
44 KiB
Ucode
/*
|
|
--------------------------------------------------------------
|
|
KF_StoryObjective
|
|
--------------------------------------------------------------
|
|
|
|
Placeable Objective Actor which stores a set of Conditions and
|
|
Actions.
|
|
|
|
Conditions determine how to complete the objective while actions
|
|
determine what happens once the objective is completed. Objective
|
|
progress is handled server-side and there can only be one active
|
|
objective at a time per server.
|
|
|
|
Author : Alex Quick
|
|
|
|
--------------------------------------------------------------
|
|
*/
|
|
|
|
class KF_StoryObjective extends StoryObjectiveBase
|
|
HideCategories(Sound)
|
|
dependson(KFStoryGameInfo)
|
|
placeable ;
|
|
|
|
#exec OBJ LOAD FILE=KFStoryGame_Tex.utx
|
|
|
|
const MAXCONDITIONS = 6;
|
|
|
|
|
|
var(Debug) bool bDebugConditionInstancing;
|
|
|
|
/* Cached reference to Story gameinfo to cut down on typecasting */
|
|
var KFStoryGameInfo StoryGI;
|
|
|
|
/* Assigned when a checkpoint has set this Objective as its 'RestartFromObjective'. */
|
|
var KF_StoryCheckPointVolume ActiveCheckPoint;
|
|
|
|
var array<Actor> RelevantActors;
|
|
|
|
/* ====================== HUD =======================================================================
|
|
|
|
=====================================================================================================*/
|
|
|
|
var(Objective_HUD) KFStoryGameInfo.SObjectiveHeaderInfo HUD_Header;
|
|
|
|
var(Objective_HUD) KFStoryGameInfo.SObjectiveBackGroundInfo HUD_Background;
|
|
|
|
/* should we show this objective on the HUD at all ? */
|
|
var(Objective_HUD) bool bShowOnHUD;
|
|
|
|
/* displays on the HUD - gives the player a hint about what his current objective is */
|
|
var localized string ObjectiveHint;
|
|
|
|
/* for letting the player know what kind of failure condition this objective has (if any) */
|
|
var/*(Objective_HUD)*/ string ObjectiveFailureHint;
|
|
|
|
/* local message to display when the objective is successfully completed */
|
|
var localized string SuccessText;
|
|
|
|
/* local message to display when the objective is failed */
|
|
var localized string FailureText;
|
|
|
|
var texture BackgroundTexture;
|
|
|
|
var bool bBGScaleUniform;
|
|
|
|
var(Objective_HUD) KFStoryGameInfo.SVect2D HUD_ScreenPosition;
|
|
|
|
var color Header_Clr;
|
|
|
|
|
|
/* Un-touched Hintstring ( before we append timer info )*/
|
|
var string InitialHint;
|
|
|
|
var float StartTime;
|
|
|
|
/* Replication Throttling ===========================================================================*/
|
|
|
|
/* Number of replication updates that have been pushed in the last second for conditions belonging to this objective */
|
|
var int CurrentRepUpdates;
|
|
|
|
/* Maximum number of condition replication updates per second for conditions belonging to this objective */
|
|
var int MaxRepUpdatesPerSecond;
|
|
|
|
/* ====================== Audio =======================================================================
|
|
|
|
=====================================================================================================*/
|
|
|
|
|
|
/* Sounds to play when the Objective is completed or becomes active, respectively. */
|
|
var(Objective_Audio) Sound CompletionSound,ActivationSound,FailureSound;
|
|
|
|
var(Objective_Audio) localized string ObjectiveInProgressMusic;
|
|
|
|
var(Objective_Audio) float MusicFadeInTime,MusicFadeOutTime;
|
|
|
|
var(Objective_Audio) bool bStopMusicOnCompletion;
|
|
|
|
var string CompletionSoundName,ActivationSoundName;
|
|
|
|
|
|
/* ====================== General Settings ===========================================================
|
|
|
|
=====================================================================================================*/
|
|
|
|
/* Can checkpoints save/restart from this objective ? */
|
|
var(Objective_Settings) bool bCheckPointable;
|
|
|
|
/* Can this objective be completed more than once without a checkpoint / level reset ? */
|
|
var(Objective_Settings) bool bRecurring;
|
|
|
|
/* Is this whole objective not mandatory for players to complete ? */
|
|
var(Objective_Settings) bool bOptional;
|
|
|
|
/* if true this objective & its conditions should revert to their starting state when this obj is no longer active . Defaults true*/
|
|
var(Objective_Settings) bool bResetOnDeactivation;
|
|
|
|
/* ====================== Events =====================================================================
|
|
|
|
=====================================================================================================*/
|
|
|
|
|
|
/* Events to use when the Objective becoems active / completes respectively. Reduces the need for multiple trigger actors / scripted actions */
|
|
var(Objective_Events) array<name> ActivationEvents;
|
|
|
|
/* Events to call when the Objective is de-activated (either by failing, succeeding, or simply switching to another objective via cheats */
|
|
var(Objective_Events) array<name> DeActivationEvents;
|
|
|
|
/* Events to fire off when the Objective is marked 'Complete' */
|
|
var(Objective_Events) array<name> CompletionEvents;
|
|
|
|
/* Events to fire off when the Objecvtive is marked 'Failed ' */
|
|
var(Objective_Events) array<name> FailureEvents;
|
|
|
|
/* =====================================================================================
|
|
=======================================================================================*/
|
|
|
|
/* true when ObjectiveCompleted() has been called. This Objective cannot be activated again */
|
|
var bool bCompleted;
|
|
|
|
/* true if this objective had a secondary condition that was not met */
|
|
var bool bFailed;
|
|
|
|
|
|
/* ====================== Success CONDITIONS ========================================================
|
|
|
|
Specifies a type of condition the player will succeed in completing the objective if he satisfies
|
|
|
|
=====================================================================================================*/
|
|
|
|
var(Objective_Conditions) export editinlineuse array<KF_ObjectiveCondition> SuccessConditions;
|
|
|
|
var(Objective_Conditions) export editinlineuse array<KF_ObjectiveCondition> OptionalConditions;
|
|
|
|
var bool bPendingSuccessActions;
|
|
|
|
var bool bPendingFailureActions;
|
|
|
|
|
|
/* OBJ_Touch vars ============================================================================
|
|
==============================================================================================*/
|
|
|
|
/* true if Touch() was called on this objective by a valid instigator. OBJ_Touch objectives will be considered complete the next tick */
|
|
var bool bWasTouched;
|
|
|
|
/* OBJ_Triggered vars ========================================================================
|
|
==============================================================================================*/
|
|
|
|
var bool bWasUsed;
|
|
|
|
/* ====================== FAILURE CONDITIONS ========================================================
|
|
|
|
Specifies a type of condition the player will fail the objective if he does not satisfy.
|
|
|
|
=====================================================================================================*/
|
|
|
|
var(Objective_Conditions) export editinlineuse array<KF_ObjectiveCondition> FailureConditions;
|
|
|
|
/* Conditions in this array are active & ticked */
|
|
var array<KF_ObjectiveCondition> AllConditions;
|
|
|
|
/* Condition Instancing ================================================================================ */
|
|
|
|
/* If set - this objective's own failure condition will be ignored in place of the F.C in the specified Objective. */
|
|
var(Objective_Instancing) name Copy_FailureConditions_From;
|
|
|
|
/* first objective in the Failure conditions' linked list */
|
|
var KF_StoryObjective FirstFailureParent;
|
|
|
|
/* If set - this objective's own success condition will be ignored in place of the F.C in the specified Objective. */
|
|
var(Objective_Instancing) name Copy_SuccessConditions_From;
|
|
|
|
var KF_StoryObjective FirstSuccessParent;
|
|
|
|
var KF_StoryObjective FirstOptionalParent;
|
|
|
|
/* If set - this objective's own success condition will be ignored in place of the F.C in the specified Objective. */
|
|
var(Objective_Instancing) name Copy_OptionalConditions_From;
|
|
|
|
var(Objective_Instancing) name Copy_FailureActions_From;
|
|
|
|
var(Objective_Instancing) name Copy_SuccessActions_From;
|
|
|
|
var KF_StoryObjective Action_FirstFailureParent;
|
|
|
|
var KF_StoryObjective Action_FirstSuccessParent;
|
|
|
|
var float LastWhispTime;
|
|
|
|
var float WhispInterval;
|
|
|
|
var bool bShowWhispTrails;
|
|
|
|
var float RemainingTime;
|
|
|
|
|
|
/* Called in GameInfo.PostLogin() */
|
|
function OnPlayerJoined(Controller JoiningPlayer)
|
|
{
|
|
local int i;
|
|
local KFPlayerController_Story KFSPC;
|
|
|
|
KFSPC = KFPlayerController_Story(JoiningPlayer);
|
|
if(KFSPC == none)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Push Existing Condition data through to newly connected client */
|
|
for(i = 0 ; i < AllConditions.Length ; i ++)
|
|
{
|
|
AllConditions[i].ReliableConditionUpdate(KFSPC);
|
|
}
|
|
}
|
|
|
|
/* Event called when player leaves the game - Update Condition values*/
|
|
function OnPlayerLeft(Controller LeavingPlayer){}
|
|
/* Event called when the objective list finishes sorting / populating in the gameinfo */
|
|
function OnObjPopulationComplete(){}
|
|
|
|
|
|
simulated function PostBeginPlay()
|
|
{
|
|
local int i;
|
|
|
|
Super.PostBeginPlay();
|
|
|
|
InitialHint = ObjectiveHint;
|
|
StoryGI = KFStoryGameInfo(level.Game);
|
|
|
|
/* No KFO Gametype, no Initialization */
|
|
if(StoryGI == none)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
SuccessConditions[i].PostBeginPlay(self);
|
|
}
|
|
for(i = 0 ; i < OptionalConditions.length ; i ++)
|
|
{
|
|
OptionalConditions[i].PostBeginPlay(self);
|
|
}
|
|
for(i = 0 ; i < FailureConditions.length ; i ++)
|
|
{
|
|
FailureConditions[i].PostBeginPlay(self);
|
|
}
|
|
|
|
SetTimer(1.0,true);
|
|
}
|
|
|
|
/* Throttle the amount of data that is being replicated to clients */
|
|
function bool AllowConditionRepUpdate()
|
|
{
|
|
if(CurrentRepUpdates >= MaxRepUpdatesPerSecond ||
|
|
Level.Pauser != none)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function Timer()
|
|
{
|
|
CurrentRepUpdates = 0;
|
|
}
|
|
|
|
|
|
/* Adds a condition to the 'AllConditions' array in this objective. This means that
|
|
the condition will then be ticked & Displayed on the HUD, etc. */
|
|
|
|
function ActivateCondition( KF_ObjectiveCondition NewCondition)
|
|
{
|
|
if(FindConditionByName(NewCondition.name) == none)
|
|
{
|
|
AllConditions[AllConditions.length] = NewCondition;
|
|
NewCondition.ConditionActivated(Instigator);
|
|
}
|
|
}
|
|
|
|
function DeActivateCondition( KF_ObjectiveCondition OldCondition)
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i ++)
|
|
{
|
|
if(AllConditions[i] == OldCondition)
|
|
{
|
|
AllConditions[i].ConditionDeActivated();
|
|
AllConditions.Remove(i,1);
|
|
i -- ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 0 == Failure Condition, 1 == Success */
|
|
simulated function byte GetNamedConditionType( name ConditionName)
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
if(SuccessConditions[i].name == ConditionName)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
for(i = 0 ; i < FailureConditions.length ; i ++)
|
|
{
|
|
if(FailureConditions[i].name == ConditionName)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 255;
|
|
}
|
|
|
|
/*
|
|
Init Conditions
|
|
|
|
- Fill the AllConditions array so we can easily iterate conditions
|
|
- Set this Objective as the owner of each condition
|
|
- Spawn event listeners for each condition so they can receive trigger events
|
|
|
|
|
|
*/
|
|
|
|
function InitConditions()
|
|
{
|
|
local int i;
|
|
|
|
AllConditions.length = 0;
|
|
|
|
for( i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
SuccessConditions[i].ConditionType = 1;
|
|
SuccessConditions[i].SetObjOwner(self);
|
|
|
|
if(SuccessConditions[i].ShouldInitOnActivation())
|
|
{
|
|
ActivateCondition(SuccessConditions[i]);
|
|
}
|
|
}
|
|
i = 0 ;
|
|
for( i = 0 ; i < FailureConditions.length ; i ++)
|
|
{
|
|
FailureConditions[i].ConditionType = 0;
|
|
FailureConditions[i].SetObjOwner(self);
|
|
|
|
if(FailureConditions[i].ShouldInitOnActivation())
|
|
{
|
|
ActivateCondition(FailureConditions[i]);
|
|
}
|
|
}
|
|
|
|
i = 0 ;
|
|
for( i = 0 ; i < OptionalConditions.length ; i ++)
|
|
{
|
|
OptionalConditions[i].ConditionType = 2;
|
|
OptionalConditions[i].SetObjOwner(self);
|
|
|
|
if(OptionalConditions[i].ShouldInitOnActivation())
|
|
{
|
|
ActivateCondition(OptionalConditions[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function float GetGameDifficulty()
|
|
{
|
|
return Level.Game.GameDifficulty ;
|
|
}
|
|
|
|
function InitActions()
|
|
{
|
|
if(SuccessAction != none)
|
|
{
|
|
SuccessAction.SetObjOwner(self);
|
|
SuccessAction.ActionType = 1;
|
|
}
|
|
|
|
if(FailureAction != none)
|
|
{
|
|
FailureAction.SetObjOwner(self);
|
|
FailureAction.ActionType = 0;
|
|
}
|
|
}
|
|
|
|
function UpdateInstancedConditions()
|
|
{
|
|
local KF_StoryObjective FP,SP,FPA,SPA,OP;
|
|
local int i,idx;
|
|
|
|
FindFirstSuccessParent();
|
|
FindFirstOptionalParent();
|
|
FindFirstFailureParent();
|
|
FindFirstActionSuccessParent();
|
|
FindFirstActionFailureParent();
|
|
|
|
SP = GetSuccessParent() ;
|
|
FP = GetFailureParent() ;
|
|
OP = GetOptionalParent();
|
|
SPA = GetActionSuccessParent();
|
|
FPA = GetActionFailureParent();
|
|
|
|
if(bDebugConditionInstancing)
|
|
{
|
|
log(" OBJ INSTANCE DEBUG ===============================================================",'Story_Debug');
|
|
log(ObjectiveName@":::: Success Condition Parent ---> "@SP.ObjectiveName,'Story_Debug');
|
|
log(ObjectiveName@":::: Failure Condition Parent ---> "@FP.ObjectiveName,'Story_Debug');
|
|
log(ObjectiveName@":::: Optional Condition Parent ---> "@OP.ObjectiveName,'Story_Debug');
|
|
log(ObjectiveName@":::: Success Action Parent ---> "@SPA.ObjectiveName,'Story_Debug');
|
|
log(ObjectiveName@":::: Failure Action Parent ---> "@FPA.ObjectiveName,'Story_Debug');
|
|
}
|
|
|
|
if(SP != none && SP != self && SP.SuccessConditions.length > 0)
|
|
{
|
|
if(bDebugConditionInstancing)
|
|
log("=========== Copying ("$SP.SuccessConditions.length$") Success Condition(s) from : "@SP.ObjectiveName@" to : "@ObjectiveName,'Story_Debug');
|
|
|
|
for(i = 0 ; i < SP.SuccessConditions.length ; i ++)
|
|
{
|
|
if(SP.SuccessConditions[i].ConditionisValid())
|
|
{
|
|
SuccessConditions[i] = SP.SuccessConditions[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if(SPA != none && SPA != self && SPA.SuccessAction != none)
|
|
{
|
|
if(bDebugConditionInstancing)
|
|
log("=========== Copying Success Action from : "@SPA.ObjectiveName@" to : "@ObjectiveName,'Story_Debug');
|
|
|
|
SuccessAction = SPA.SuccessAction;
|
|
}
|
|
|
|
if(FP != none && FP != self && FP.FailureConditions.length > 0)
|
|
{
|
|
if(bDebugConditionInstancing)
|
|
log("=========== Copying ("$FP.FailureConditions.length$") Failure Condition(s) from : "@FP.ObjectiveName@" to : "@ObjectiveName,'Story_Debug');
|
|
|
|
for(idx = 0 ; idx < FP.FailureConditions.length ; idx ++)
|
|
{
|
|
if(FP.FailureConditions[idx].ConditionisValid())
|
|
{
|
|
FailureConditions[idx] = FP.FailureConditions[idx];
|
|
}
|
|
}
|
|
}
|
|
|
|
if(FPA != none && FPA != self && FPA.FailureAction != none)
|
|
{
|
|
if(bDebugConditionInstancing)
|
|
log("=========== Copying Failure Action from : "@FPA.ObjectiveName@" to : "@ObjectiveName,'Story_Debug');
|
|
|
|
FailureAction = FPA.FailureAction;
|
|
}
|
|
if(OP != none && OP != self && OP.OptionalConditions.length > 0)
|
|
{
|
|
if(bDebugConditionInstancing)
|
|
log("=========== Copying ("$OP.OptionalConditions.length$") Optional Condition(s) from : "@OP.ObjectiveName@" to : "@ObjectiveName,'Story_Debug');
|
|
|
|
for(i = 0 ; i < OP.OptionalConditions.length ; i ++)
|
|
{
|
|
if(OP.OptionalConditions[i].ConditionIsValid())
|
|
{
|
|
OptionalConditions[i] = OP.OptionalConditions[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Returns the first SuccessCondition Parent Objective in the Linked list */
|
|
function FindFirstSuccessParent()
|
|
{
|
|
local int i;
|
|
local KF_StoryObjective Obj;
|
|
|
|
if(FirstSuccessParent != none ||
|
|
StoryGI == none ||
|
|
Copy_SuccessConditions_From == '' ||
|
|
Copy_SuccessConditions_From == ObjectiveName)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(i = 0 ; i < StoryGI.AllObjectives.length ; i ++)
|
|
{
|
|
Obj = StoryGI.AllObjectives[i];
|
|
if(Obj.ObjectiveName == Copy_SuccessConditions_From)
|
|
{
|
|
FirstSuccessParent = Obj;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Returns the first FailureCondition Parent Objective in the Linked list */
|
|
function FindFirstFailureParent()
|
|
{
|
|
local int i;
|
|
local KF_StoryObjective Obj;
|
|
|
|
if(FirstFailureParent != none ||
|
|
StoryGI == none ||
|
|
Copy_FailureConditions_From == '' ||
|
|
Copy_FailureConditions_From == ObjectiveName)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(i = 0 ; i < StoryGI.AllObjectives.length ; i ++)
|
|
{
|
|
Obj = StoryGI.AllObjectives[i];
|
|
if(Obj.ObjectiveName == Copy_FailureConditions_From)
|
|
{
|
|
FirstFailureParent = Obj;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Returns the first Optional Condition Parent Objective in the Linked list */
|
|
function FindFirstOptionalParent()
|
|
{
|
|
local int i;
|
|
local KF_StoryObjective Obj;
|
|
|
|
if(FirstOptionalParent != none ||
|
|
StoryGI == none ||
|
|
Copy_OptionalConditions_From == '' ||
|
|
Copy_OptionalConditions_From == ObjectiveName)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(i = 0 ; i < StoryGI.AllObjectives.length ; i ++)
|
|
{
|
|
Obj = StoryGI.AllObjectives[i];
|
|
if(Obj.ObjectiveName == Copy_OptionalConditions_From)
|
|
{
|
|
FirstOptionalParent = Obj;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Returns the first FailureCondition Parent Objective in the Linked list */
|
|
function FindFirstActionSuccessParent()
|
|
{
|
|
local int i;
|
|
local KF_StoryObjective Obj;
|
|
|
|
if(Action_FirstSuccessParent != none ||
|
|
StoryGI == none ||
|
|
Copy_SuccessActions_From == '' ||
|
|
Copy_SuccessActions_From == ObjectiveName)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(i = 0 ; i < StoryGI.AllObjectives.length ; i ++)
|
|
{
|
|
Obj = StoryGI.AllObjectives[i];
|
|
if(Obj.ObjectiveName == Copy_SuccessActions_From)
|
|
{
|
|
Action_FirstSuccessParent = Obj;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* Returns the first FailureCondition Parent Objective in the Linked list */
|
|
function FindFirstActionFailureParent()
|
|
{
|
|
local int i;
|
|
local KF_StoryObjective Obj;
|
|
|
|
if(Action_FirstFailureParent != none ||
|
|
StoryGI == none ||
|
|
Copy_FailureActions_From == '' ||
|
|
Copy_FailureActions_From == ObjectiveName)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(i = 0 ; i < StoryGI.AllObjectives.length ; i ++)
|
|
{
|
|
Obj = StoryGI.AllObjectives[i];
|
|
if(Obj.ObjectiveName == Copy_FailureActions_From)
|
|
{
|
|
Action_FirstFailureParent = Obj;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* accessor for retrieving this objective's Success parent. (if using instanced conditions) */
|
|
function KF_StoryObjective GetSuccessParent()
|
|
{
|
|
if(FirstSuccessParent == none)
|
|
{
|
|
return none;
|
|
}
|
|
else
|
|
{
|
|
return FirstSuccessParent ;
|
|
}
|
|
}
|
|
|
|
|
|
/* accessor for retrieving this objective's Optional objective parent. (if using instanced conditions) */
|
|
function KF_StoryObjective GetOptionalParent()
|
|
{
|
|
if(FirstOptionalParent == none)
|
|
{
|
|
return self;
|
|
}
|
|
else
|
|
{
|
|
return FirstOptionalParent.GetOptionalParent() ;
|
|
}
|
|
}
|
|
|
|
function KF_StoryObjective GetActionSuccessParent()
|
|
{
|
|
if(Action_FirstSuccessParent == none)
|
|
{
|
|
return self;
|
|
}
|
|
else
|
|
{
|
|
return Action_FirstSuccessParent.GetActionSuccessParent() ;
|
|
}
|
|
}
|
|
|
|
/* accessor for retrieving this objective's Failure parent. (if using instanced conditions) */
|
|
function KF_StoryObjective GetFailureParent()
|
|
{
|
|
if(FirstFailureParent == none)
|
|
{
|
|
return self;
|
|
}
|
|
else
|
|
{
|
|
return FirstFailureParent.GetFailureParent() ;
|
|
}
|
|
}
|
|
|
|
function KF_StoryObjective GetActionFailureParent()
|
|
{
|
|
if(Action_FirstFailureParent == none)
|
|
{
|
|
return self;
|
|
}
|
|
else
|
|
{
|
|
return Action_FirstFailureParent.GetActionFailureParent() ;
|
|
}
|
|
}
|
|
|
|
|
|
/* reset objective to its initial state - used when restarting from a checkpoint */
|
|
|
|
function Reset()
|
|
{
|
|
StartTime = 0.f;
|
|
InitialHint = ObjectiveHint;
|
|
bCompleted = false;
|
|
bFailed = false;
|
|
bWasUsed = false;
|
|
bWasTouched = false;
|
|
ResetConditions();
|
|
ResetActions();
|
|
// UpdateInstancedConditions();
|
|
}
|
|
|
|
function ResetConditions()
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i ++)
|
|
{
|
|
if(AllConditions[i].GetObjOwner() == self)
|
|
{
|
|
AllConditions[i].ConditionDeActivated();
|
|
}
|
|
}
|
|
}
|
|
|
|
function ResetActions()
|
|
{
|
|
if(SuccessAction!=none)
|
|
{
|
|
SuccessAction.ActionDeActivated();
|
|
}
|
|
|
|
if(FailureAction != none)
|
|
{
|
|
FailureAction.ActionDeActivated();
|
|
}
|
|
}
|
|
|
|
|
|
/* Wrapper for checking if this objective is the player's current goal */
|
|
function bool IsCurrentObjective()
|
|
{
|
|
if(StoryGI != none)
|
|
{
|
|
return StoryGI.CurrentObjective == self ;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/* Returns true if this objective is able to be set as active (ie. Not already Completed or failed) */
|
|
function bool IsValidForActivation()
|
|
{
|
|
return !bCompleted && !bFailed ;
|
|
}
|
|
|
|
/* Notification that this objective has just been assigned as the current goal in GameInfo*/
|
|
|
|
function Notify_ObjectiveActivated(pawn ActivatingPlayer)
|
|
{
|
|
local int i;
|
|
local Controller C;
|
|
local PlayerController PC;
|
|
|
|
StartTime = Level.TimeSeconds;
|
|
NetUpdateFrequency = 10.f;
|
|
SetHumanInstigator(ActivatingPlayer);
|
|
|
|
UpdateInstancedConditions();
|
|
InitConditions();
|
|
InitActions();
|
|
|
|
for(i = 0 ; i < ActivationEvents.length ; i ++)
|
|
{
|
|
TriggerEvent(ActivationEvents[i],self,ActivatingPlayer);
|
|
// log("===========================================================",'Story_Debug');
|
|
// log(self@"is triggering Activation event : "@ActivationEvents[i],'Story_Debug');
|
|
}
|
|
|
|
for ( C=Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
// log("Playing sound : "@ActivationSound,'Story_Debug');
|
|
PC = PlayerController(C);
|
|
if(PC != none )
|
|
{
|
|
if(ActivationSound != none)
|
|
{
|
|
PC.ClientPlaySound(ActivationSound,,,SLOT_MISC);
|
|
}
|
|
}
|
|
}
|
|
|
|
ShowWhispTrails(true);
|
|
PlayObjectiveMusic();
|
|
Notify_ConditionsActivated(ActivatingPlayer);
|
|
}
|
|
|
|
|
|
function Notify_ObjectiveDeActivated()
|
|
{
|
|
local int i;
|
|
|
|
NetUpdateFrequency = 1.f ;
|
|
ShowWhispTrails(false);
|
|
|
|
for(i = 0 ; i < DeActivationEvents.length ; i ++)
|
|
{
|
|
TriggerEvent(DeActivationEvents[i],self,Instigator);
|
|
}
|
|
|
|
/* even if the objective isn't recurring we still need to reset the conditions (since they could be instanced
|
|
by other objectives and need to be returned to their default states */
|
|
|
|
if(bResetOnDeactivation)
|
|
{
|
|
if(!bRecurring)
|
|
{
|
|
ResetConditions();
|
|
ResetActions();
|
|
}
|
|
else
|
|
{
|
|
Reset(); // if its a recurring objective then just reset everything.
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
function Notify_ConditionsActivated(pawn ActivatingPlayer)
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i ++)
|
|
{
|
|
AllConditions[i].ConditionActivated(ActivatingPlayer);
|
|
}
|
|
}
|
|
|
|
function ShowWhispTrails(bool On)
|
|
{
|
|
bShowWhispTrails = On ;
|
|
}
|
|
|
|
|
|
function PlayObjectiveMusic()
|
|
{
|
|
local Controller C;
|
|
|
|
if(ObjectiveInProgressMusic != "" &&
|
|
ObjectiveInProgressMusic != StoryGI.CurrentMusicTrack)
|
|
{
|
|
for( C=Level.ControllerList;C!=None;C=C.NextController )
|
|
{
|
|
if (KFPlayerController(C)!= none)
|
|
{
|
|
KFPlayerController(C).NetPlayMusic(ObjectiveInProgressMusic, MusicFadeInTime,MusicFadeOutTime);
|
|
}
|
|
}
|
|
|
|
StoryGI.CurrentMusicTrack = ObjectiveInProgressMusic;
|
|
}
|
|
}
|
|
|
|
function ForceCompleteObjective()
|
|
{
|
|
local int i,idx;
|
|
|
|
bCompleted = false;
|
|
|
|
for(i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
for(idx = 0 ; idx < SuccessConditions[i].ProgressEvents.Length ; idx ++)
|
|
{
|
|
if(!SuccessConditions[i].ProgressEvents[idx].bWasTriggered)
|
|
{
|
|
TriggerEvent(SuccessConditions[i].ProgressEvents[idx].EventName,self,Instigator);
|
|
}
|
|
}
|
|
|
|
SuccessConditions[i].bLockCompletion = true;
|
|
SuccessConditions[i].ConditionCompleted();
|
|
}
|
|
}
|
|
|
|
/* Called when this Actor's conditions have been met - notify the gameinfo that it may proceed to the next objective */
|
|
function ObjectiveCompleted(Controller Scorer, optional bool SkipActions)
|
|
{
|
|
local int i;
|
|
local Controller C;
|
|
local PlayerController PC;
|
|
local KFSteamStatsAndAchievements KFSteamStats;
|
|
local KFGameReplicationInfo KFGRI;
|
|
|
|
if(IsValidForActivation())
|
|
{
|
|
bCompleted = true;
|
|
|
|
Log("======================================",'Story_Debug');
|
|
Log("OBJECTIVE "@ObjectiveName@" COMPLETE ",'Story_Debug');
|
|
Log("======================================",'Story_Debug');
|
|
|
|
for(i = 0 ; i < CompletionEvents.length ; i ++)
|
|
{
|
|
TriggerEvent(CompletionEvents[i],self,Instigator);
|
|
}
|
|
|
|
for ( C=Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
PC = PlayerController(C);
|
|
if(PC != none)
|
|
{
|
|
if(CompletionSound != none )
|
|
{
|
|
PC.ClientPlaySound(CompletionSound,,,SLOT_MISC);
|
|
}
|
|
|
|
if(SuccessText != "")
|
|
{
|
|
PC.ClientMessage( SuccessText, 'CriticalEvent');
|
|
}
|
|
|
|
KFGRI = KFGameReplicationInfo( Level.GRI );
|
|
if( KFGRI != none )
|
|
{
|
|
if( !KFGRI.bObjectiveAchievementFailed )
|
|
{
|
|
KFSteamStats = KFSteamStatsAndAchievements( PC.SteamStatsAndAchievements );
|
|
if ( KFSteamStats != none )
|
|
{
|
|
KFSteamStats.OnObjectiveCompleted( ObjectiveName );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
KFGRI.bObjectiveAchievementFailed = false;
|
|
|
|
if(!SkipActions)
|
|
{
|
|
bPendingSuccessActions = true;
|
|
}
|
|
|
|
if(StoryGI != none)
|
|
{
|
|
StoryGI.OnObjectiveCompleted(self);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// log(" WARNING - OBJECTIVE : "@ObjectiveName@" is already complete. ",'Story_Debug');
|
|
}
|
|
}
|
|
|
|
/* Deferred execution of actions to allow Actors which are triggered by Success / Failure events to be ticked before
|
|
the objective is changed */
|
|
|
|
function ExecuteSuccessActions()
|
|
{
|
|
if(SuccessAction != none)
|
|
{
|
|
SuccessAction.ExecuteAction(Instigator.Controller);
|
|
}
|
|
}
|
|
|
|
/* Counterpart to ObjectiveCompleted() - Called when this Objective's Failure condition has not been satisfied - notify the gameinfo that it should end the game in defeat */
|
|
function ObjectiveFailed(Controller Failer, optional bool SkipActions)
|
|
{
|
|
local int i;
|
|
local Controller C;
|
|
local PlayerController PC;
|
|
|
|
if(IsValidForActivation())
|
|
{
|
|
bFailed = true;
|
|
|
|
Log("======================================",'Story_Debug');
|
|
Log("OBJECTIVE "@ObjectiveName@" FAILED ",'Story_Debug');
|
|
Log("======================================",'Story_Debug');
|
|
|
|
|
|
for(i = 0 ; i < FailureEvents.length ; i ++)
|
|
{
|
|
TriggerEvent(FailureEvents[i],self,Instigator);
|
|
}
|
|
|
|
if(FailureText != "")
|
|
{
|
|
for ( C=Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
PC = PlayerController(C);
|
|
if(PC != none)
|
|
{
|
|
PC.ClientMessage( FailureText, 'CriticalEvent');
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!SkipActions)
|
|
{
|
|
bPendingFailureActions = true;
|
|
}
|
|
|
|
if(StoryGI != none)
|
|
{
|
|
StoryGI.OnObjectiveFailed(self);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Deferred execution of actions to allow Actors which are triggered by Success / Failure events to be ticked before
|
|
the objective is changed */
|
|
|
|
function ExecuteFailureActions()
|
|
{
|
|
if(FailureAction != none)
|
|
{
|
|
FailureAction.ExecuteAction(Instigator.Controller);
|
|
}
|
|
}
|
|
|
|
/* for triggering events - Some actors require a human pawn instigator to receive trigger events. Movers for example.*/
|
|
function SetHumanInstigator(Actor NewInstigator)
|
|
{
|
|
local Controller C;
|
|
|
|
if(Pawn(NewInstigator) != none &&
|
|
PlayerController(Pawn(NewInstigator).Controller) != none)
|
|
{
|
|
Instigator = Pawn(NewInstigator);
|
|
}
|
|
else // time to get a little more creative ...
|
|
{
|
|
for ( C=Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
if(PlayerController(C) != none && C.Pawn != none)
|
|
{
|
|
Instigator = C.Pawn ;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function Touch( Actor Other )
|
|
{
|
|
if(IsCurrentObjective())
|
|
{
|
|
if(Pawn(Other) != none && Pawn(Other).Controller != none && Pawn(Other).Controller.bIsPlayer)
|
|
{
|
|
bWasTouched = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function Trigger( actor Other, pawn EventInstigator )
|
|
{
|
|
if(PendingGameRestart() || bCompleted || bFailed)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
/* triggering an inactive objective will activate it and set it as the current objective .. */
|
|
if(!IsCurrentObjective())
|
|
{
|
|
StoryGI.SetActiveObjective(self,Instigator);
|
|
}
|
|
}
|
|
|
|
|
|
function Tick(float DeltaTime)
|
|
{
|
|
if(bCompleted || bFailed)
|
|
{
|
|
if(bPendingFailureActions)
|
|
{
|
|
bPendingFailureActions = false;
|
|
ExecuteFailureActions();
|
|
}
|
|
|
|
if(bPendingSuccessActions)
|
|
{
|
|
bPendingSuccessActions = false;
|
|
ExecuteSuccessActions();
|
|
}
|
|
|
|
/* This would only happen if we didn't have any success / failure action defined
|
|
that transitioned to another objective.*/
|
|
|
|
if(IsCurrentObjective() &&
|
|
(bCompleted || bFailed))
|
|
{
|
|
StoryGI.SetActiveObjective(none);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(IsCurrentObjective())
|
|
{
|
|
TickConditions(DeltaTime);
|
|
RefreshWhispTrails();
|
|
|
|
if(CheckConditions())
|
|
{
|
|
ObjectiveCompleted(Instigator.Controller);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function RefreshWhispTrails()
|
|
{
|
|
local Controller C;
|
|
local PlayerController PC;
|
|
|
|
if( bShowWhispTrails && Level.TimeSeconds - LastWhispTime > WhispInterval)
|
|
{
|
|
LastWhispTime = Level.TimeSeconds;
|
|
|
|
For( C=Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
PC = PlayerController(C);
|
|
if( PC != none && PC.Pawn!=None && PC.Pawn.Health>0 )
|
|
{
|
|
StoryGI.ShowPathToObj(PC);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function TickConditions(float DeltaTime)
|
|
{
|
|
local int i;
|
|
local bool bUpdatedTime;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i ++)
|
|
{
|
|
if(AllConditions[i].GetObjOwner() == self &&
|
|
AllConditions[i].ConditionIsActive())
|
|
{
|
|
AllConditions[i].ConditionTick(DeltaTime);
|
|
|
|
/* Kind of a hack - we need to grab the remaining time for an
|
|
active timer condition to use on the trader menu */
|
|
if(!bUpdatedTime && ObjCondition_Timed(AllConditions[i]) != none)
|
|
{
|
|
bUpdatedTime = true;
|
|
RemainingTime = ObjCondition_Timed(AllConditions[i]).RemainingSeconds ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Returns true if this Objective has a 'TraderTime' condition that is currently active */
|
|
function bool IsTraderObj()
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
if(SuccessConditions[i].GetObjOwner() == self &&
|
|
SuccessConditions[i].ConditionIsActive() &&
|
|
ObjCondition_TraderTime(SuccessConditions[i]) != none )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function bool PendingGameRestart()
|
|
{
|
|
return StoryGI != none && StoryGI.bPendingTeamRespawn ;
|
|
}
|
|
|
|
|
|
/* Returns true if this condition's progress should be used to determine the
|
|
completion state of the objective. Inactive or optional conditions are ignored .. */
|
|
function bool CheckConditionProgress(KF_ObjectiveCondition TestCondition)
|
|
{
|
|
return TestCondition != none &&
|
|
TestCondition.ProgressImportance != Ignore &&
|
|
TestCondition.bActive &&
|
|
TestCondition.ConditionIsValid();
|
|
}
|
|
|
|
/* Verifies when and If this objective has satisfied (or failed)
|
|
all its conditions
|
|
|
|
We failed/Succeeded if ...
|
|
|
|
A. a condition marked 'Critical' was completed.
|
|
B. all conditions with normal importance were completed *
|
|
*/
|
|
|
|
function bool CheckConditions()
|
|
{
|
|
local int i;
|
|
local bool bNewFailedObj;
|
|
local int NumGoals,NumComplete,NumFailed;
|
|
local int NumFailConditions;
|
|
local bool bNewComplete;
|
|
|
|
if(bCompleted || PendingGameRestart())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/* Check the failure conditions first - If we screwed this objective up, no point checking anything else */
|
|
|
|
for(i = 0 ; i < FailureConditions.length ; i ++)
|
|
{
|
|
if(CheckConditionProgress(FailureConditions[i]))
|
|
{
|
|
NumFailConditions ++ ;
|
|
if(FailureConditions[i].bComplete)
|
|
{
|
|
NumFailed ++ ;
|
|
}
|
|
|
|
bNewFailedObj = (FailureConditions[i].bComplete &&
|
|
FailureConditions[i].ProgressImportance == Critical) ;
|
|
|
|
if(bNewFailedObj)
|
|
{
|
|
SetHumanInstigator(FailureConditions[i].GetInstigator());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
i = 0;
|
|
|
|
bNewFailedObj = bNewFailedObj || (NumFailConditions > 0 && NumFailed >= NumFailConditions);
|
|
if(bNewFailedObj != bFailed)
|
|
{
|
|
if(bNewFailedObj)
|
|
{
|
|
ObjectiveFailed(Instigator.Controller);
|
|
}
|
|
}
|
|
|
|
if( bFailed )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/* Ok - If we got this far we haven't failed this objective so ... Check to see if we've succeeded instead */
|
|
|
|
for(i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
if(CheckConditionProgress(SuccessConditions[i]))
|
|
{
|
|
NumGoals ++ ;
|
|
if(SuccessConditions[i].bComplete)
|
|
{
|
|
NumComplete ++ ;
|
|
}
|
|
|
|
bNewComplete = (SuccessConditions[i].bComplete &&
|
|
SuccessConditions[i].ProgressImportance == Critical) ;
|
|
|
|
if(bNewComplete)
|
|
{
|
|
SetHumanInstigator(SuccessConditions[i].GetInstigator());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bNewComplete = bNewComplete || (NumGoals > 0 && NumComplete >= NumGoals) ;
|
|
|
|
if(NumGoals == 0)
|
|
{
|
|
log("WARNING - no Success Conditions assigned to : "@ObjectiveName@". It is impossible to complete this objective.",'Story_Debug');
|
|
}
|
|
|
|
return bNewComplete;
|
|
|
|
}
|
|
|
|
// called if this Actor was touching a Pawn who pressed Use
|
|
event UsedBy( Pawn user )
|
|
{
|
|
local int i;
|
|
|
|
/* If we don't have to hold the key down, just immediately complete */
|
|
if(!bCompleted && IsCurrentObjective() && User != none)
|
|
{
|
|
bWasUsed = true;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i ++)
|
|
{
|
|
AllConditions[i].StartedUsing(user);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* We walked away from this Objective - stop using it */
|
|
event UnTouch( Actor Other )
|
|
{
|
|
if(Pawn(Other) != none)
|
|
{
|
|
StoppedUsing(Pawn(Other));
|
|
}
|
|
}
|
|
|
|
/* called by KFPlayerController_Story when the player releases the Use key */
|
|
function StoppedUsing( Pawn user)
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i ++)
|
|
{
|
|
AllConditions[i].StoppedUsing(user);
|
|
}
|
|
}
|
|
|
|
/* Average completion %age of active failure conditions */
|
|
|
|
function float GetFailureProgressPct()
|
|
{
|
|
local float Pct;
|
|
local int i;
|
|
local float HighestPct;
|
|
|
|
if(bFailed)
|
|
{
|
|
return 1.f;
|
|
}
|
|
|
|
for( i = 0 ; i < FailureConditions.length ; i ++)
|
|
{
|
|
Pct = FailureConditions[i].GetCompletionPct();
|
|
if(Pct > HighestPct)
|
|
{
|
|
HighestPct = Pct;
|
|
}
|
|
}
|
|
|
|
return HighestPct;
|
|
}
|
|
|
|
|
|
/* Average completion %age of active success conditions */
|
|
|
|
function float GetSuccessProgressPct()
|
|
{
|
|
local float Pct;
|
|
local int i;
|
|
|
|
if(bCompleted)
|
|
{
|
|
return 1.f;
|
|
}
|
|
|
|
for( i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
Pct += SuccessConditions[i].GetCompletionPct();
|
|
}
|
|
Pct /= SuccessConditions.length ;
|
|
|
|
return Pct;
|
|
}
|
|
|
|
simulated function KF_ObjectiveCondition FindConditionByName(name ConditionName)
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i++)
|
|
{
|
|
if(AllConditions[i].Name == ConditionName)
|
|
{
|
|
return AllConditions[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function int FindIndexForCondition(KF_ObjectiveCondition TestCondition, optional name TestConditionName, optional bool bSearchAllConditionArray)
|
|
{
|
|
local int i;
|
|
local array<KF_ObjectiveCondition> SearchArray;
|
|
|
|
if(TestCondition == none && TestConditionName != '')
|
|
{
|
|
for(i = 0 ; i < Allconditions.length ; i ++)
|
|
{
|
|
if(AllConditions[i].name == TestConditionName)
|
|
{
|
|
TestCondition = AllConditions[i] ;
|
|
if(bSearchAllConditionArray)
|
|
{
|
|
return i;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
i = 0;
|
|
|
|
switch(TestCondition.ConditionType)
|
|
{
|
|
case 0 : SearchArray = FailureConditions; break;
|
|
case 1 : SearchArray = SuccessConditions; break;
|
|
case 2 : SearchArray = OptionalConditions; break;
|
|
}
|
|
|
|
for(i = 0 ; i < SearchArray.length ; i ++)
|
|
{
|
|
if(SearchArray[i] == TestCondition)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
|
|
log("Warning - Could not find index for condition : "@TestCondition@" in "@ObjectiveName,'Story_Debug');
|
|
return -1 ;
|
|
}
|
|
|
|
/* Debug helper function - Returns the names of the next Objective after this one */
|
|
|
|
function name GetNextObjectiveName()
|
|
{
|
|
return '' ;
|
|
}
|
|
|
|
function SetCheckPoint(KF_StoryCheckPointVolume Instigator)
|
|
{
|
|
local int i;
|
|
|
|
if(bCheckPointable)
|
|
{
|
|
ActiveCheckPoint = Instigator;
|
|
|
|
for(i = 0 ; i < AllConditions.length ; i ++)
|
|
{
|
|
AllConditions[i].SaveState();
|
|
}
|
|
}
|
|
}
|
|
|
|
function ClearCheckPoint()
|
|
{
|
|
ActiveCheckPoint = none;
|
|
}
|
|
|
|
|
|
|
|
/* ======= UnrealED Storymode Visualisation ====================================================================================
|
|
================================================================================================================================*/
|
|
|
|
function GetEvents(out array<name> TriggeredEvents, out array<name> ReceivedEvents)
|
|
{
|
|
local int i,idx;
|
|
|
|
Super.GetEvents(TriggeredEvents,ReceivedEvents);
|
|
|
|
|
|
/* Things this Objective Triggers */
|
|
|
|
for(i = 0 ; i < ActivationEvents.length ; i ++)
|
|
{
|
|
if(ActivationEvents[i] != '')
|
|
{
|
|
TriggeredEvents[TriggeredEvents.length] = ActivationEvents[i];
|
|
}
|
|
}
|
|
for(i = 0 ; i < DeActivationEvents.length ; i ++)
|
|
{
|
|
if(DeActivationEvents[i] != '')
|
|
{
|
|
TriggeredEvents[TriggeredEvents.length] = DeActivationEvents[i];
|
|
}
|
|
}
|
|
for(i = 0 ; i < CompletionEvents.length ; i ++)
|
|
{
|
|
if(CompletionEvents[i] != '')
|
|
{
|
|
TriggeredEvents[TriggeredEvents.length] = CompletionEvents[i];
|
|
}
|
|
}
|
|
for(i = 0 ; i < FailureEvents.length ; i ++)
|
|
{
|
|
if(FailureEvents[i] != '')
|
|
{
|
|
TriggeredEvents[TriggeredEvents.length] = FailureEvents[i];
|
|
}
|
|
}
|
|
for(i = 0 ; i < SuccessConditions.length ; i ++)
|
|
{
|
|
for(idx = 0 ; idx < SuccessConditions[i].ProgressEvents.length ;idx ++)
|
|
{
|
|
if(SuccessConditions[i].ProgressEvents[idx].EventName != '')
|
|
{
|
|
TriggeredEvents[TriggeredEvents.length] = SuccessConditions[i].ProgressEvents[idx].EventName;
|
|
}
|
|
}
|
|
|
|
if(SuccessConditions[i].Tag != '' &&
|
|
SuccessConditions[i].ActivationMethod > 0 &&
|
|
SuccessConditions[i].ActivationMethod < 4)
|
|
{
|
|
ReceivedEvents[ReceivedEvents.length] = SuccessConditions[i].Tag ;
|
|
}
|
|
|
|
}
|
|
for(i = 0 ; i < FailureConditions.length ; i ++)
|
|
{
|
|
for(idx = 0 ; idx <FailureConditions[i].ProgressEvents.length ;idx ++)
|
|
{
|
|
if(FailureConditions[i].ProgressEvents[idx].EventName != '')
|
|
{
|
|
TriggeredEvents[TriggeredEvents.length] = FailureConditions[i].ProgressEvents[idx].EventName;
|
|
}
|
|
}
|
|
|
|
if(FailureConditions[i].Tag != '' &&
|
|
FailureConditions[i].ActivationMethod > 0 &&
|
|
FailureConditions[i].ActivationMethod < 4)
|
|
{
|
|
ReceivedEvents[ReceivedEvents.length] = FailureConditions[i].Tag ;
|
|
}
|
|
}
|
|
for(i = 0 ; i < OptionalConditions.length ; i ++)
|
|
{
|
|
for(idx = 0 ; idx <OptionalConditions[i].ProgressEvents.length ;idx ++)
|
|
{
|
|
if(OptionalConditions[i].ProgressEvents[idx].EventName != '')
|
|
{
|
|
TriggeredEvents[TriggeredEvents.length] = OptionalConditions[i].ProgressEvents[idx].EventName;
|
|
}
|
|
}
|
|
|
|
if(OptionalConditions[i].Tag != '' &&
|
|
OptionalConditions[i].ActivationMethod > 0 &&
|
|
OptionalConditions[i].ActivationMethod < 4)
|
|
{
|
|
ReceivedEvents[ReceivedEvents.length] = OptionalConditions[i].Tag ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ======= UnrealED Storymode Visualisation ====================================================================================
|
|
================================================================================================================================*/
|
|
|
|
defaultproperties
|
|
{
|
|
Begin Object Class=ObjAction_GoToNextObjective Name=DefaultSuccessAction
|
|
End Object
|
|
|
|
SuccessAction=DefaultSuccessAction
|
|
|
|
WhispInterval = 1.1
|
|
MaxRepUpdatesPerSecond = 10
|
|
|
|
bCheckPointable = true
|
|
bResetOnDeactivation=true
|
|
|
|
bStatic = false
|
|
RemoteRole = Role_None
|
|
bCollideActors = true
|
|
bHidden = true
|
|
bNoDelete=true
|
|
|
|
Texture = Texture 'KFStoryGame_Tex.Editor.KFObj_Ico'
|
|
|
|
bShowOnHUD = true
|
|
DrawScale = 0.5
|
|
|
|
// Audio
|
|
|
|
MusicFadeinTime = 1.0
|
|
MusicFadeOutTime = 2.0
|
|
bStopMusicOnCompletion = true
|
|
|
|
HUD_Header=(Header_Color=(R=255,G=255,B=255,A=255),Header_Scale=Font_Large)
|
|
HUD_Background=(Background_Texture=Texture'KFStoryGame_Tex.HUD.ObjectiveHUDBG',Background_Texture_Collapsed=Texture'KFStoryGame_Tex.HUD.ObjectiveHUDBG_Collapsed',Background_AspectRatio=Aspect_FromTexture,BackGround_Padding=64,Background_Scale=1.f)
|
|
HUD_ScreenPosition=(Horizontal=1,Vertical=0.02)
|
|
}
|
|
|
|
|