rott/kf_sources/ScrnStoryGame/Classes/KF_DialogueSpot_SE.uc
2026-07-14 20:27:09 +07:00

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
}