Core.Object | +--Engine.Actor | +--Engine.Info | +--XIDCine.DialogueManager
float
Alpha
name
Bone
Pawn
CurrentSpeakerPawn
rotator
JawRotator
Machoire,
Levre
OriginalTag
Ouverture
XIIIPlayerController
PC
Pause
Temps
TempsPauseFerme
bool
bAfficheVignette
bStop
void
EndOfLine( )
ForceLine(int line)
InterpolTick(out structInterpol, float dt)
//##############################################################################
IsSpeaking()
MustBeStop( )
Speak( )
StartDialogue(optional int)
WarnIfAVoiceIsAlreadyRunning()
NextSentence()
RestoreCineEvents( )
00001 //----------------------------------------------------------- 00002 // DialogueManager 00003 // Created by iKi 00004 //----------------------------------------------------------- 00005 class DialogueManager extends Info 00006 HideCategories(Advanced,Display) 00007 placeable; 00008 00009 #exec Texture Import File=Textures\dialman_ico.tga Name=DialMan_ico Mips=Off 00010 00011 STRUCT SLine 00012 { 00013 VAR() int SpeakerIndex; 00014 VAR() int SentenceIndex; 00015 VAR() float TimeBeforeSentence; 00016 VAR() name ExpectedEventBeforeNext; 00017 VAR() string SpeakersToWarnAtTheEndOfThisLine; 00018 }; 00019 00020 STRUCT SSpeaker 00021 { 00022 VAR() String PawnName; 00023 VAR() Actor Pawn; 00024 VAR() localized Array<String> Sentences; 00025 }; 00026 00027 VAR(Dialog) bool BreathSteam; 00028 VAR bool bSpeaking, bPaused, bDialoguePlaying, mustStopDialogue, bStarted, bPostPonedDialogue ; 00029 VAR(Dialog) localized Array<SSpeaker> Speakers; 00030 VAR(Dialog) Array<SLine> Lines; 00031 VAR Array<BreathSteamEmitter> BSE; 00032 VAR Array<byte> bGivenSpeaker; 00033 VAR TRANSIENT int LineIndex; 00034 VAR TRANSIENT XIIIPlayerController PC; 00035 VAR TRANSIENT Pawn CurrentSpeakerPawn; 00036 VAR TRANSIENT name OriginalTag; 00037 00038 //VAR TRANSIENT vector InitialLocation; 00039 00040 STRUCT structInterpol 00041 { 00042 VAR float Alpha; 00043 VAR float Temps; 00044 VAR float TempsPauseFerme; 00045 VAR rotator Ouverture; // TOREMOVE !!! 00046 VAR name Bone; 00047 VAR float Pause; 00048 VAR bool bStop; 00049 }; 00050 00051 VAR rotator JawRotator; 00052 VAR structInterpol Machoire, Levre; 00053 00054 CONST NoSoundTime = 2.0; 00055 00056 // MLK: Allows the DialogueManager to r/w data to the right place 00057 //var int DlgMgrListIndex; 00058 //var MapInfo MI; 00059 00060 var bool bAfficheVignette; 00061 00062 00063 //----------------------------------------------------------- 00064 EVENT PostBeginPlay() 00065 { 00066 LOCAL int i; 00067 00068 bGivenSpeaker.Insert( 0, Speakers.Length ); 00069 00070 for ( i = 0; i < Speakers.Length; ++i ) 00071 bGivenSpeaker[ i ] = byte( Speakers[ i ].Pawn!=none && ( Speakers[ i ].Pawn.IsA('Pawn') || Speakers[ i ].Pawn.IsA('GenNMI') ) ); 00072 00073 OriginalTag = Tag; 00074 } 00075 00076 EVENT Trigger(actor Other,pawn EventInstigator) 00077 { 00078 if ( CineController2( other )!=none ) 00079 CineController2( other ).dm = self; 00080 tag = ''; 00081 00082 StartDialogue( ); 00083 } 00084 00085 FUNCTION ForceLine(coerce int line) 00086 { 00087 if ( PC == none ) 00088 PC = XIIIGameInfo( Level.Game ).MapInfo.XIIIController; 00089 00090 if ( MustBeStop( ) ) 00091 { 00092 Destroy( ); 00093 return; 00094 } 00095 00096 LineIndex = line; 00097 Disable( 'Trigger' ); 00098 tag = ''; 00099 Speak( ); 00100 } 00101 00102 FUNCTION StartDialogue( optional int firstline ) 00103 { 00104 LOCAL int i; 00105 00106 if ( !bStarted ) 00107 { 00108 if ( PC == none ) 00109 PC = XIIIGameInfo( Level.Game ).MapInfo.XIIIController; 00110 00111 if ( MustBeStop( ) ) 00112 { 00113 Destroy( ); 00114 return; 00115 } 00116 00117 if ( BreathSteam ) 00118 { 00119 BSE.Insert( 0, Speakers.Length ); 00120 for ( i = 0; i < Speakers.Length; ++i ) 00121 { 00122 if ( Speakers[ i ].Pawn.IsA('Pawn') ) 00123 { 00124 BSE[ i ] = Spawn( class'BreathSteamEmitter' ); 00125 Speakers[ i ].Pawn.AttachToBone( BSE[ i ], 'X Lips' ); 00126 } 00127 else 00128 if ( Left( Speakers[ Lines[ i ].SpeakerIndex ].PawnName, 4 ) ~= "XIII" ) 00129 { 00130 BSE[ i ] = Spawn( class'BreathSteamEmitter',,, PC.Pawn.Location+PC.Pawn.EyePosition() + 20*vector(PC.Rotation)); 00131 BSE[ i ].SetBase( PC.Pawn ); //.AttachToBone( , 'X Lips' ); 00132 // PC.Pawn.AttachToBone( BSE[ i ], 'X Lips' ); 00133 } 00134 } 00135 } 00136 00137 // MLK: {-1, DialNumber} begin a new 'scene' & used as a separator 00138 // MI._Dial.Lineind = -1; MI._dial.Speakerind = DlgMgrListIndex; 00139 // MI.DialogToSave[MI.DialogToSave.Length] = MI._Dial; 00140 00141 LineIndex = firstline; 00142 bStarted = true; 00143 GotoState( 'STA_PlayingDialogue' ); 00144 } 00145 else 00146 { 00147 ForceLine( firstline ); 00148 } 00149 } 00150 00151 EVENT Tick( float dt) 00152 { 00153 // LOG(" Coucou"@self ); 00154 if ( bPostPonedDialogue ) 00155 Speak(); 00156 } 00157 00158 FUNCTION Speak( ) 00159 { 00160 LOCAL int TextIndex, i; 00161 LOCAL SSpeaker SpeakingSpeaker; // :) 00162 LOCAL float WaveLength; 00163 LOCAL string SoundName; 00164 00165 if ( WarnIfAVoiceIsAlreadyRunning() ) 00166 bPostPonedDialogue=true; 00167 else 00168 { 00169 bPostPonedDialogue=false; 00170 if ( ( Lines[ LineIndex ].SpeakerIndex == -1 ) || ( Lines[ LineIndex ].SentenceIndex == -1 ) ) 00171 { 00172 EndOfLine( ); 00173 return; 00174 } 00175 SpeakingSpeaker = Speakers[ Lines[ LineIndex ].SpeakerIndex ]; 00176 TextIndex = Lines[ LineIndex ].SentenceIndex; 00177 00178 // Compute Sound Name 00179 if ( TextIndex < 10 ) 00180 SoundName = "0" $ string( TextIndex ); 00181 else if ( TextIndex < 100 ) 00182 SoundName = string( TextIndex ); 00183 // else 00184 // SoundName = "xx"; 00185 00186 if ( Left( SpeakingSpeaker.PawnName, 2) ~= "HF" ) 00187 { 00188 // sfx window display for HF dialogue 00189 bAfficheVignette = true; 00190 TriggerEvent( name(SpeakingSpeaker.PawnName), self, none ); 00191 // HF letters is used to recognize HF dialogue, they won't be present in SoundName 00192 SoundName = Level.Title $ "_" $ Mid(SpeakingSpeaker.PawnName,2) $ "_" $ SoundName; 00193 } 00194 else 00195 if ( Left( SpeakingSpeaker.PawnName, 4) ~= "NORM" ) 00196 { 00197 // sfx window display for NORM dialogue 00198 bAfficheVignette = true; 00199 TriggerEvent( name(SpeakingSpeaker.PawnName), self, none ); 00200 // NORM letters is used to recognize NORM dialogue, they won't be present in SoundName 00201 SoundName = Level.Title $ "_" $ Mid(SpeakingSpeaker.PawnName,4) $ "_" $ SoundName; 00202 } 00203 else 00204 SoundName = Level.Title $ "_" $ SpeakingSpeaker.PawnName $ "_" $ SoundName; 00205 00206 // DisplaySentence 00207 WaveLength = GetWaveDuration( SoundName ) + 1.0; 00208 00209 if ( WaveLength==0 ) // If no sound display sentence NoSoundTime seconds 00210 WaveLength = NoSoundTime + 1.0; 00211 00212 if ( (Speakers[ Lines[ LineIndex ].SpeakerIndex ].Pawn == none) && ( Left(Speakers[ Lines[ LineIndex ].SpeakerIndex ].PawnName, 4) ~= "XIII") ) 00213 PC.MyHud.LocalizedMessage( class'XIIIDialogMessage', 1, none, none, none, SpeakingSpeaker.Sentences[ TextIndex ] ); 00214 else if ( ( (Speakers[ Lines[ LineIndex ].SpeakerIndex ].Pawn == none) && !WaveHasPosition(SoundName) ) || ( Left(Speakers[ Lines[ LineIndex ].SpeakerIndex ].PawnName, 2) ~= "HP") || ( Left(Speakers[ Lines[ LineIndex ].SpeakerIndex ].PawnName, 2) ~= "HF") ) 00215 PC.MyHud.LocalizedMessage( class'XIIIDialogMessage', 2, none, none, Speakers[ Lines[ LineIndex ].SpeakerIndex ].Pawn, SpeakingSpeaker.Sentences[ TextIndex ] ); 00216 else 00217 PC.MyHud.LocalizedMessage( class'XIIIDialogMessage', 0, none, none, Speakers[ Lines[ LineIndex ].SpeakerIndex ].Pawn, SpeakingSpeaker.Sentences[ TextIndex ] ); 00218 00219 // :: iKi :: beurk... not clean... 00220 XIIIBaseHud( PC.MyHud ).HudDlg.MyMessage.EndOfLife = WaveLength + Level.TimeSeconds; 00221 XIIIBaseHud( PC.MyHud ).HudDlg.MyMessage.LifeTime = WaveLength; 00222 00223 // Play Speaker Voice 00224 if ( SpeakingSpeaker.Pawn!=none && SpeakingSpeaker.Pawn.IsA('GenNMI') ) 00225 { 00226 CurrentSpeakerPawn = SpeakingSpeaker.Pawn.Instigator; 00227 } 00228 else 00229 { 00230 CurrentSpeakerPawn = Pawn(SpeakingSpeaker.Pawn); 00231 } 00232 00233 if ( BreathSteam && BSE[ Lines[ LineIndex ].SpeakerIndex ]!=none ) 00234 BSE[ Lines[ LineIndex ].SpeakerIndex ].Trigger( none, none ); 00235 00236 if ( PlayStrVoice( SoundName, SpeakingSpeaker.Pawn ) ) 00237 { 00238 // Log( "DIALOGMANAGER PLAYSTRVOICE ~~~"@self@":"@SpeakingSpeaker.Sentences[ TextIndex ]); 00239 GotoState( 'STA_HeadAnimation' ); 00240 } 00241 else 00242 { 00243 // Log( "DIALOGMANAGER PLAYSTRVOICE ~~~ ECHEC"@self); 00244 GotoState( 'STA_HeadAnimation','NoSound' ); 00245 } 00246 } 00247 } 00248 00249 FUNCTION bool WarnIfAVoiceIsAlreadyRunning() 00250 { 00251 LOCAL DialogueManager dm; 00252 // LOCAL bool bFirst; 00253 00254 // bFirst=true; 00255 foreach DynamicActors( class'DialogueManager', dm ) 00256 { 00257 // if ( dm==self ) 00258 // continue; 00259 if ( dm.bSpeaking ) 00260 { 00261 /* if ( bFirst ) 00262 { 00263 LOG( "#####################################" ); 00264 LOG( "## ##" ); 00265 LOG( "## DIALOGUE INTERROMPU SAUVAGEMENT ##" ); 00266 LOG( "## ##" ); 00267 LOG( "#####################################" ); 00268 LOG( "DATE:"@Level.TimeSeconds ); 00269 bFirst=false; 00270 } 00271 00272 LOG( self@"INTERROMPT"@dm );*/ 00273 // LOG( "######################################################################" ); 00274 // LOG( "## ##" ); 00275 // LOG( "## DIALOGUE EN COURS : DEMANDE DE VOIX REPOUSSEE A PLUS TARD ##" ); 00276 // LOG( "## ##" ); 00277 // LOG( "## LE LEVEL-DESIGN EST GROS MECHANT QUI NE FAIT CE QU'ON LUI DIT !! ##" ); 00278 // LOG( "## ##" ); 00279 // LOG( "######################################################################" ); 00280 return true; 00281 } 00282 } 00283 // if ( !bFirst ) 00284 // LOG( "-------------------------------------" ); 00285 return false; 00286 } 00287 00288 FUNCTION EndOfLine( ) 00289 { 00290 } 00291 00292 //############################################################################## 00293 function InterpolTick( out structInterpol ri, float dt ) 00294 { 00295 if ( bPaused ) 00296 { 00297 if ( ri.alpha == 0 ) 00298 return; 00299 if ( ri.Temps > 0 ) 00300 ri.Temps = -ri.Temps; 00301 ri.Pause = 0; 00302 } 00303 ri.Pause -= dt; 00304 if ( ri.Pause < 0 ) 00305 { 00306 if ( ! ri.bStop || (ri.alpha!=0) ) 00307 ri.alpha += dt / ri.Temps; 00308 if ( ri.alpha > 1.0 ) 00309 { 00310 ri.alpha = 1.0; 00311 ri.Temps = -ri.Temps; 00312 ri.Pause = 0.0; // ri.TempsPauseOuvert; 00313 } 00314 else if ( ri.alpha < 0.0 ) 00315 { 00316 ri.alpha = 0.0; 00317 ri.Temps = -ri.Temps; 00318 ri.Pause = ri.TempsPauseFerme; 00319 } 00320 } 00321 } 00322 00323 //############################################################################## 00324 function bool MustBeStop( ) 00325 { 00326 LOCAL int i; 00327 LOCAL Pawn p; 00328 00329 for ( i = 0; i < Speakers.Length; ++i ) 00330 { 00331 if ( bGivenSpeaker[ i ] != 0 ) 00332 { 00333 if ( Speakers[i].Pawn.IsA('GenNMI') ) 00334 p = Speakers[i].Pawn.Instigator; 00335 else 00336 p = Pawn(Speakers[i].Pawn); 00337 00338 if ( 00339 ( p==none ) || ( p.bDeleteMe ) || p.bIsDead // Pawn only conditions 00340 || 00341 ( p.Controller==none ) 00342 || 00343 ( p.Controller.IsA( 'IAController' ) && ( p.controller.Enemy!=none ) ) 00344 ) 00345 { 00346 // LOG ("========================================================"); 00347 // LOG ( self@"STOPPED on actor"@i@"("@Speakers[i].PawnName@")"); 00348 // LOG ("--------------------------------------------------------"); 00349 // if ( Speakers[i].Pawn.IsA('GenNMI') ) 00350 // LOG( "PAWN ="@p@"FROM GENNMI"@Speakers[i].Pawn ); 00351 // else 00352 // LOG( "PAWN ="@p ); 00353 // if ( p!=none ) 00354 // { 00355 // if ( p.bDeleteMe ) 00356 // LOG ( "bDeleteMe = TRUE" ); 00357 // if ( p.bIsDead ) 00358 // LOG ( "bIsDead = TRUE" ); 00359 // if ( p.Controller==none ) 00360 // LOG ( "HAS NO CONTROLLER !!" ); 00361 // else 00362 // { 00363 // if ( p.Controller.IsA( 'IAController' ) && ( p.controller.Enemy!=none ) ) 00364 // LOG ( "HAS AN ENEMY :"@p.controller.Enemy ); 00365 // } 00366 // } 00367 // else 00368 // LOG ( "PAWN IS NONE" ); 00369 // LOG ("--------------------------------------------------------"); 00370 00371 00372 // DebugLog("MUST BE STOPPED !!!"); 00373 return true; 00374 } 00375 } 00376 } 00377 return false; 00378 } 00379 00380 event Destroyed( ) 00381 { 00382 local int i, Dialind; 00383 00384 StopVoice( ); 00385 XIIIBaseHud( PC.MyHud ).HudDlg.RemoveMe(); 00386 } 00387 00388 FUNCTION bool IsSpeaking() 00389 { 00390 return bDialoguePlaying; 00391 } 00392 00393 STATE STA_HeadAnimation 00394 { 00395 EVENT BeginState( ) 00396 { 00397 bSpeaking = true; 00398 00399 Machoire.Alpha = 0; 00400 Machoire.bStop = false; 00401 Levre.Alpha = 0; 00402 Levre.bStop = false; 00403 bPaused = false; 00404 enable( 'Tick' ); 00405 } 00406 /* 00407 EVENT Untrigger( actor a, pawn p ) 00408 { 00409 StopVoice( ); 00410 } 00411 */ 00412 EVENT EndOfVoice( ) 00413 { 00414 // Log( "DIALOGMANAGER ENDOFVOICE ~~~"@self); 00415 Machoire.bStop = true; 00416 Levre.bStop = true; 00417 bSpeaking = false; 00418 } 00419 00420 EVENT PauseVoice( ) 00421 { 00422 // Log( "DIALOGMANAGER PAUSE ~~~"@self); 00423 bPaused = true; 00424 } 00425 00426 EVENT UnpauseVoice( ) 00427 { 00428 // Log( "DIALOGMANAGER UNPAUSE ~~~"@self); 00429 bPaused = false; 00430 } 00431 00432 EVENT Tick( float dt ) 00433 { 00434 LOCAL int i; 00435 00436 if ( MustBeStop( ) ) 00437 { 00438 StopVoice( ); 00439 XIIIBaseHud( PC.MyHud ).HudDlg.RemoveMe(); 00440 00441 if ( BreathSteam ) 00442 for ( i = 0; i < BSE.length; ++i ) 00443 { 00444 if ( BSE[ i ]!=none ) 00445 { 00446 BSE[i].AutoDestroy = true; 00447 // to work, AutoDestroy require the particles emitters not to be disabled 00448 BSE[i].Emitters[0].Disabled = false; // it would be nicer to ask the emitter to enable its own emitters (whatever their number) 00449 } 00450 } 00451 00452 if ( CurrentSpeakerPawn!=none ) 00453 { 00454 CurrentSpeakerPawn.SetBoneDirection( Machoire.Bone, rot( 0, 0, 0 ), vect( 0, 0, 0 ), 0.0 ); 00455 CurrentSpeakerPawn.SetBoneScale( 0 ); 00456 } 00457 // Beurk 00458 XIIIBaseHud( PC.MyHud ).HudDlg.MyMessage.EndOfLife = Level.TimeSeconds; 00459 XIIIBaseHud( PC.MyHud ).HudDlg.MyMessage.LifeTime = 1.0; 00460 00461 Destroy( ); 00462 } 00463 00464 if ( !( bSpeaking || Machoire.Alpha!=0 || Levre.Alpha!=0 ) ) 00465 { 00466 // if (CurrentSpeakerPawn!=none) 00467 // { 00468 if ( CurrentSpeakerPawn!=none ) 00469 { 00470 CurrentSpeakerPawn.SetBoneDirection( Machoire.Bone, rot( 0, 0, 0 ), vect( 0, 0, 0 ), 0.0 ); 00471 CurrentSpeakerPawn.SetBoneScale( 0 ); 00472 } 00473 // } 00474 // sfx window display is no more 00475 if ( bAfficheVignette ) 00476 { 00477 bAfficheVignette = false; 00478 TriggerEvent('DeadVignAlpha',self,none); 00479 } 00480 00481 GotoState( 'STA_PlayingDialogue', 'EOL' ); 00482 return; 00483 } 00484 00485 if ( CurrentSpeakerPawn!=none ) 00486 { 00487 if ( Levre.alpha==0 ) 00488 { 00489 if ( bPaused ) 00490 { 00491 Levre.Temps = 0; 00492 Levre.TempsPauseFerme = 0; 00493 // Levre.TempsPauseOuvert = 0; 00494 } 00495 else 00496 { 00497 Levre.Temps = FRand() * 0.100 + 0.200;// 0.250; //(FRand()*0.2+0.1)*0.85; // TEST POUR ALKIS 0.0; // 00498 Levre.TempsPauseFerme = FRand( ) * 0.17; //0.2 * 0.85; // TEST POUR ALKIS 1.0; // 00499 // Levre.TempsPauseOuvert = 0.0; //FRand()*0.1*0.85; // TEST POUR ALKIS 1.0; // 00500 } 00501 } 00502 InterpolTick( Levre, dt ); 00503 if ( !Levre.bStop ) 00504 CurrentSpeakerPawn.SetBoneScalePerAxis( 0, ( 1.0 - 0.80 * Levre.Alpha ), , , Levre.Bone ); 00505 00506 if ( Machoire.alpha==0 ) 00507 { 00508 if ( bPaused ) 00509 { 00510 Machoire.Temps = 0; 00511 Machoire.TempsPauseFerme = 0; 00512 // Machoire.TempsPauseOuvert = 0; 00513 JawRotator = rot( 0, 0, 0 ); 00514 } 00515 else 00516 { 00517 if ( BreathSteam && BSE[ Lines[ LineIndex ].SpeakerIndex ]!=none ) 00518 BSE[ Lines[ LineIndex ].SpeakerIndex ].Trigger( none, none ); 00519 Machoire.Temps = FRand() * 0.100 + 0.200; //0.250; //(FRand()*0.0625+0.0625)*0.85; // TEST POUR ALKIS 0.0; // 00520 Machoire.TempsPauseFerme = FRand( ) * 0.1; //053125; //0.0625*0.85; // TEST POUR ALKIS 1.0; // 00521 // Machoire.TempsPauseOuvert = 0.0; //FRand()*0.0625*0.85; // TEST POUR ALKIS 1.0; // 00522 JawRotator = -( FRand( ) * 500 + 750 ) * rot( 0, 0, 1 ); // TEST POUR ALKIS -1200;// 00523 } 00524 } 00525 InterpolTick( Machoire, dt ); 00526 CurrentSpeakerPawn.SetBoneRotation( Machoire.Bone, JawRotator, , Machoire.Alpha ); 00527 } 00528 } 00529 00530 EVENT Timer( ) 00531 { 00532 EndOfVoice( ); 00533 } 00534 NoSound: 00535 SetTimer( NoSoundTime, false ); 00536 } 00537 00538 STATE STA_PlayingDialogue 00539 { 00540 EVENT BeginState( ) 00541 { 00542 LOCAL int i; 00543 if ( !bDialoguePlaying ) 00544 { 00545 Disable( 'Trigger' ); 00546 if ( Lines[LineIndex].TimeBeforeSentence!=0 ) 00547 SetTimer( Lines[LineIndex].TimeBeforeSentence, false ); 00548 else 00549 Speak( ); 00550 bDialoguePlaying = true; 00551 } 00552 } 00553 00554 EVENT Timer( ) 00555 { 00556 if ( MustBeStop( ) ) 00557 { 00558 Destroy( ); 00559 return; 00560 } 00561 Speak( ); 00562 } 00563 00564 EVENT Trigger( actor Other, pawn EventInstigator ) 00565 { 00566 Disable( 'Trigger' ); 00567 tag = ''; 00568 NextSentence( ); 00569 } 00570 00571 FUNCTION EndOfLine( ) 00572 { 00573 LOCAL string strTemp,strTemp2; 00574 LOCAL int index; 00575 00576 strTemp = Lines[ LineIndex ].SpeakersToWarnAtTheEndOfThisLine; 00577 00578 while( strTemp != "" ) 00579 { 00580 index = InStr( strTemp, " " ); 00581 if ( index == -1 ) { strTemp2 = ""; } 00582 else { strTemp2 = Mid( strTemp, index + 1 ); strTemp = Left( strTemp, index ); } 00583 00584 // Log( "DIALOGMANAGER"@self@"Warn Actor"@Speakers[ int( strTemp ) ].Pawn ); 00585 00586 if ( Cine2( Speakers[ int( strTemp ) ].Pawn )!=none ) 00587 Cine2( Speakers[ int( strTemp ) ].Pawn ).CineController.CineWarn( self ); 00588 strTemp = strTemp2; 00589 } 00590 00591 if ( Lines[ LineIndex ].ExpectedEventBeforeNext != '' ) 00592 { 00593 tag = Lines[ LineIndex ].ExpectedEventBeforeNext; 00594 if ( !RestoreCineEvents( ) ) 00595 { 00596 // Log( "DIALOGMANAGER::Waiting event"@tag ); 00597 Enable( 'Trigger' ); 00598 } 00599 else 00600 NextSentence( ); 00601 } 00602 else 00603 NextSentence( ); 00604 00605 } 00606 00607 FUNCTION bool RestoreCineEvents( ) 00608 { 00609 LOCAL int i, n; 00610 LOCAL CineController2 C; 00611 00612 ForEach DynamicActors( class 'CineController2', C ) 00613 { 00614 for ( i=0; i<8 /*MAX_EVENT*/; i++ ) 00615 { 00616 if ( C.EventNamesTab[i]==Tag ) 00617 { 00618 // Log( "DIALOGMANAGER::RESTORING CINE EVENT"@tag ); 00619 // Trigger( C.EventOthersTab[i], C.EventInstigatorsTab[i] ); 00620 return true; 00621 } 00622 00623 } 00624 } 00625 return false; 00626 } 00627 EOL: 00628 EndOfLine( ); 00629 stop; 00630 } 00631 00632 FUNCTION NextSentence() 00633 { 00634 LOCAL int i; 00635 00636 LineIndex++; 00637 00638 if ( LineIndex < Lines.length ) 00639 { 00640 if ( Lines[LineIndex].TimeBeforeSentence!=0 ) 00641 { 00642 // Log( "DIALOGMANAGER::Waiting time"@Lines[LineIndex].TimeBeforeSentence ); 00643 SetTimer( Lines[LineIndex].TimeBeforeSentence, false ); 00644 } 00645 else 00646 Speak( ); 00647 } 00648 else 00649 { 00650 // Log( "DIALOGMANAGER::Warn ENDOFDIALOG" ); 00651 for ( i = 0; i < Speakers.Length; ++i ) 00652 { 00653 if ( Speakers[i].Pawn!=none && Speakers[i].Pawn.IsA('Cine2') ) 00654 Cine2( Speakers[i].Pawn ).CineController.EndOfDial( self ); 00655 if ( BreathSteam && BSE[ i ]!=none ) 00656 { 00657 BSE[ i ].AutoDestroy = true; 00658 // to work, AutoDestroy require the particles emitters not to be disabled 00659 BSE[ i ].Emitters[ 0 ].Disabled = false; // it would be nicer to ask the emitter to enable its own emitters (whatever their number) 00660 } 00661 } 00662 bDialoguePlaying = false; 00663 if ( event != '' ) 00664 TriggerEvent( event, self, none ); 00665 GotoState( '' ); 00666 } 00667 } 00668 00669 00670 00671 defaultproperties 00672 { 00673 Machoire=(Bone="X Jaw") 00674 Levre=(Bone="X Lips") 00675 Texture=Texture'XIDCine.DialMan_ico' 00676 }