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