## XIDCine
Class DialogueManager

source: C:\XIII\XIDCine\Classes\DialogueManager.uc

    Core.Object
       |
       +--Engine.Actor
          |
          +--Engine.Info
             |
             +--XIDCine.DialogueManager

Direct Known Subclasses:DialogueManagerRandom, DialogueManagerFight

class DialogueManager
extends Engine.Info

    //-----------------------------------------------------------
    // DialogueManager
    // Created by iKi
    //-----------------------------------------------------------

Variables
`float` | `Alpha`
`name` | `Bone` TOREMOVE !!!
`Pawn` | `CurrentSpeakerPawn`
`rotator` | `JawRotator` TOREMOVE !!!
`Machoire,` | `Levre` TOREMOVE !!!
`name` | `OriginalTag`
`rotator` | `Ouverture` TOREMOVE !!!
`XIIIPlayerController` | `PC`
`float` | `Pause` TOREMOVE !!!
`float` | `Temps`
`float` | `TempsPauseFerme`
`bool` | `bAfficheVignette` TOREMOVE !!!
`bool` | `bStop` TOREMOVE !!!

States
STA_PlayingDialogue, STA_HeadAnimation

Function Summary
`void` | `EndOfLine( )`
`void` | `ForceLine(int line)`
`void` | `InterpolTick(out structInterpol, float dt)`
    //##############################################################################
`bool` | `IsSpeaking()`
`bool` | `MustBeStop( )`
    //##############################################################################
`void` | `Speak( )`
`void` | `StartDialogue(optional int)`
`bool` | `WarnIfAVoiceIsAlreadyRunning()`

State STA_PlayingDialogue Function Summary
`void` | `NextSentence()`
`bool` | `RestoreCineEvents( )`
`void` | `EndOfLine( )`

State STA_HeadAnimation Function Summary

Source Code

    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 }

End Source Code