226 lines
5.3 KiB
Ucode
226 lines
5.3 KiB
Ucode
/*
|
|
--------------------------------------------------------------
|
|
KF_DialogueSpot_SE
|
|
--------------------------------------------------------------
|
|
|
|
|
|
|
|
Author : PooSH
|
|
Original Author: Alex Quick
|
|
|
|
--------------------------------------------------------------
|
|
*/
|
|
|
|
class KF_DialogueSpot_SE extends KF_DialogueSpot
|
|
placeable;
|
|
|
|
/**
|
|
ERequiredEventType - determines what to do on RequiredEvent triggered:
|
|
RET_Trigger Act the same as original KF_DialogueSpot - start dialogue from triggered index
|
|
RET_Enable Just enables triggered index (doesn't show dialogue).
|
|
RET_Disable Disables triggered index (doesn't show dialogue)
|
|
RET_Toggle Toggles between enabled and disabled
|
|
|
|
In all cases except RET_Trigger, bLooping shows if dialogue is initially DISABLED
|
|
*/
|
|
enum ERequiredEventType
|
|
{
|
|
RET_Trigger,
|
|
RET_Enable,
|
|
RET_Disable,
|
|
RET_Toggle
|
|
};
|
|
var(KF_DialogueSpot) const ERequiredEventType RequiredEventType;
|
|
|
|
var(KF_DialogueSpot) float DisplayTimePerWord;
|
|
var(KF_DialogueSpot) float DisplayTimePerChar;
|
|
var(KF_DialogueSpot) float MinDisplayTime;
|
|
var(KF_DialogueSpot) float MaxDisplayTime;
|
|
|
|
|
|
|
|
function PostBeginPlay()
|
|
{
|
|
local int i;
|
|
local Dialogue_EventListener NewListener;
|
|
|
|
/* No KFO Gametype, no Initialization */
|
|
if(KFStoryGameinfo(Level.Game) == none)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Spawn Event listeners for Dialogue entries which require them.
|
|
for(i = 0 ; i < Dialogues.length ; i ++)
|
|
{
|
|
NewListener = Spawn(class'Dialogue_EventListener_SE',self,Dialogues[i].Events.RequiredEvent);
|
|
NewListener.AssociatedIndex = i ;
|
|
Dialogues[i].EventListener = NewListener;
|
|
if ( RequiredEventType != RET_Trigger && Dialogues[i].Events.RequiredEvent != '' )
|
|
Dialogues[i].bWasTriggered = Dialogues[i].bLooping;
|
|
}
|
|
}
|
|
|
|
// C&P to set bLooping as default bWasTriggered state -- PooSH
|
|
function Reset()
|
|
{
|
|
local int i, SavedIdx;
|
|
local array<byte> SavedTriggerStates;
|
|
|
|
Super.Reset();
|
|
|
|
/* Partial reset using saved positions*/
|
|
|
|
bTraversing = false;
|
|
|
|
if(!bFinished)
|
|
{
|
|
SavedIdx = KFStoryGameInfo(Level.Game).CurrentCheckPoint.GetSavedDialogueIndexFor(self,SavedTriggerStates) ;
|
|
CurrentMsgIdx = SavedIdx;
|
|
|
|
if(bDebugDialogue)
|
|
{
|
|
log("----- DIALOGUE DEBUG ------ Resetting "@self@". Dialogue will play back from Index : "@SavedIdx, 'Story_Debug');
|
|
}
|
|
|
|
for(i = 0 ; i < Dialogues.length ; i ++)
|
|
{
|
|
Dialogues[i].bWasTriggered = bool(SavedTriggerStates[i]);
|
|
}
|
|
}
|
|
else /* Full reset from the start. */
|
|
{
|
|
for(i = 0 ; i < Dialogues.length ; i ++)
|
|
{
|
|
if ( RequiredEventType != RET_Trigger && Dialogues[i].Events.RequiredEvent != '' )
|
|
Dialogues[i].bWasTriggered = Dialogues[i].bLooping;
|
|
else
|
|
Dialogues[i].bWasTriggered = false;
|
|
}
|
|
|
|
CurrentMsgIdx = 0;
|
|
bFinished = false;
|
|
}
|
|
}
|
|
|
|
function int GetNextDlgRequiredEventIdx(int TestIndex)
|
|
{
|
|
if ( RequiredEventType == RET_Trigger )
|
|
return super.GetNextDlgRequiredEventIdx(TestIndex);
|
|
|
|
return -1; // for other event types - event is not required, it just enables/disables that dialogue
|
|
}
|
|
|
|
function int GetRandomEnabledDialogueIndex()
|
|
{
|
|
local array<int> AvaliableIndicies;
|
|
local int i;
|
|
|
|
for ( i=0; i<Dialogues.length; ++i ) {
|
|
if ( !Dialogues[i].bWasTriggered )
|
|
AvaliableIndicies[AvaliableIndicies.Length] = i;
|
|
}
|
|
|
|
if ( AvaliableIndicies.length == 0 )
|
|
return -1;
|
|
if ( AvaliableIndicies.length == 1)
|
|
return 0;
|
|
return AvaliableIndicies[RandRange(0,AvaliableIndicies.length)];
|
|
}
|
|
|
|
function TraverseDialogue()
|
|
{
|
|
local float DisplayDur;
|
|
|
|
if ( RequiredEventType == RET_Trigger ) {
|
|
super.TraverseDialogue();
|
|
return;
|
|
}
|
|
|
|
/* Hit the end. early out */
|
|
if( bTraversing || bFinished )
|
|
return;
|
|
|
|
if(bRandomize) {
|
|
CurrentMsgIdx = GetRandomEnabledDialogueIndex();
|
|
if ( CurrentMsgIdx == -1 ) {
|
|
OnDialogueCompleted();
|
|
return;
|
|
}
|
|
}
|
|
else if ( CurrentMsgIdx >= Dialogues.length ) {
|
|
return;
|
|
}
|
|
|
|
while ( CurrentMsgIdx < Dialogues.length && Dialogues[CurrentMsgIdx].bWasTriggered )
|
|
CurrentMsgIdx++;
|
|
|
|
if ( CurrentMsgIdx >= Dialogues.length ) {
|
|
OnDialogueCompleted();
|
|
return;
|
|
}
|
|
|
|
|
|
if(bDebugDialogue)
|
|
{
|
|
log("----- DIALOGUE DEBUG ------ Showing Dialogue at index .. "@CurrentMsgIdx, 'Story_Debug');
|
|
}
|
|
ShowDialogue(CurrentMsgIdx);
|
|
|
|
if( !bRandomize ) {
|
|
if(CurrentMsgIdx + 1 < Dialogues.length )
|
|
{
|
|
bTraversing = true;
|
|
|
|
DisplayDur = GetCurrentDisplayDur();
|
|
if(DisplayDur > 0)
|
|
{
|
|
SetTimer(DisplayDur,false);
|
|
}
|
|
else
|
|
{
|
|
Timer();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* we're finished. Reset the actor */
|
|
OnDialogueCompleted();
|
|
}
|
|
}
|
|
}
|
|
|
|
function Timer()
|
|
{
|
|
if ( RequiredEventType == RET_Trigger ) {
|
|
super.Timer();
|
|
return;
|
|
}
|
|
|
|
if(bTraversing) {
|
|
bTraversing = false;
|
|
CurrentMsgIdx++ ;
|
|
TraverseDialogue();
|
|
}
|
|
}
|
|
|
|
/* Helper function - calculates the amount of time a string should
|
|
be displayed for based on its word length */
|
|
|
|
function float CalcDisplayTime(string InString)
|
|
{
|
|
local array<string> Words;
|
|
|
|
if ( DisplayTimePerWord > 0 )
|
|
Split(InString," ",Words);
|
|
|
|
return FClamp(Words.length * DisplayTimePerWord + Len(InString)*DisplayTimePerChar, MinDisplayTime, MaxDisplayTime);
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
DisplayTimePerWord=0.300000
|
|
MinDisplayTime=3.000000
|
|
MaxDisplayTime=60.000000
|
|
}
|