//----------------------------------------------------------------------------- // // $Logfile:: /EF2/Code/DLLs/game/talk.cpp $ // $Revision:: 16 $ // $Author:: Singlis $ // $Date:: 9/26/03 2:36p $ // // Copyright (C) 2002 by Ritual Entertainment, Inc. // All rights reserved. // // This source may not be distributed and/or modified without // expressly written permission by Ritual Entertainment, Inc. // // // DESCRIPTION: // Talk Implementation // // PARAMETERS: // // ANIMATIONS: //-------------------------------------------------------------------------------- #include "actor.h" #include "talk.hpp" #include Event EV_TalkBehavior_GreetingDone ( "greetingdone", EV_DEFAULT, NULL, NULL, "Notifies the talk behavior the greeting dialog is done" ); /**************************************************************************** Talk Class Definition ****************************************************************************/ CLASS_DECLARATION( Behavior, Talk, NULL ) { { &EV_TalkBehavior_GreetingDone, &Talk::GreetingDone }, { &EV_Behavior_AnimDone, &Talk::AnimDone }, { NULL, NULL } }; void Talk::SetUser ( Sentient *user ) { ent_listening = user; } void Talk::AnimDone ( Event *ev ) { turnto.ProcessEvent( EV_Behavior_AnimDone ); animDone = true; } void Talk::GreetingDone( Event *ev ) { mode = TALK_MODE_TURN_TO; } void Talk::Begin ( Actor &self ) { Vector dir; Vector angles; const char *anim_name; oldAnimName = ""; anim_name = self.animname; last_headwatch_target = self.headWatcher->GetWatchTarget(); animDone = true; move_allowed = true; turnto.SetUseTurnAnim( false ); /* if ( strncmp( anim_name, "sit_leanover", 12 ) == 0 ) { move_allowed = false; } else if ( strncmp( anim_name, "sit", 3 ) == 0 ) { move_allowed = false; self.SetAnim( "sit_talk" ); } else if ( strncmp( anim_name, "talk_sit_stunned", 15 ) == 0 ) { move_allowed = false; } else if ( strncmp( anim_name, "talk_headset", 12 ) == 0 ) { move_allowed = true; } else if ( strncmp( anim_name, "stand_hypnotized", 16 ) == 0 ) { move_allowed = false; } else if ( strncmp( anim_name, "talk_hipnotic", 13 ) == 0 ) { move_allowed = false; } else if ( strncmp( anim_name, "rope", 4 ) == 0 ) { move_allowed = false; } else { move_allowed = true; self.SetAnim( "talk" ); }*/ if ( self.talkMode == TALK_IGNORE ) { move_allowed = false; } if ( self.talkMode == TALK_HEADWATCH ) { move_allowed = false; oldAnimName = self.animname; } if ( self.talkMode != TALK_IGNORE ) { if ( ent_listening ) self.headWatcher->SetWatchTarget( ent_listening ); } mode = TALK_MODE_PLAY_GREETING; Entity *currentEnemy = NULL; currentEnemy = self.enemyManager->GetCurrentEnemy(); if ( currentEnemy ) mode = TALK_MODE_COMBAT; original_yaw = self.angles[YAW]; if ( ent_listening ) { dir = ent_listening->centroid - self.centroid; angles = dir.toAngles(); yaw = angles[YAW]; } /*if ( !self.GetActorFlag(ACTOR_FLAG_PLAYING_DIALOG_ANIM) ) { self.SetAnim( "conv" , EV_Actor_NotifyBehavior ); self.SetActorFlag( ACTOR_FLAG_PLAYING_DIALOG_ANIM , true ); } */ } BehaviorReturnCode_t Talk::Evaluate ( Actor &self ) { Vector dir; Vector angles; str greetingDialog; str combatDialog; float greetingDialogLength; Event *greetingEvent; char localizedDialogName[MAX_QPATH]; //Event *event; if ( !ent_listening ) mode = TALK_MODE_TURN_BACK; if ( !self.GetActorFlag(ACTOR_FLAG_PLAYING_DIALOG_ANIM) && animDone && self.GetActorFlag(ACTOR_FLAG_DIALOG_PLAYING) ) { if ( self.useConvAnims ) { //self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , true); self.SetAnim( "talk" , EV_Actor_NotifyBehavior ); self.SetActorFlag( ACTOR_FLAG_PLAYING_DIALOG_ANIM , true ); self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , false ); animDone = false; } } if ( self.useConvAnims && animDone && mode != TALK_MODE_WAIT && mode != TALK_MODE_TURN_TO ) { self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , true); self.SetAnim( "conv-idle" , EV_Actor_NotifyBehavior ); //self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , false ); //self.SetAnim( "idle" ); animDone = false; } if ( self.useConvAnims && /*animDone &&*/ mode == TALK_MODE_WAIT ) { self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , true); if ( oldAnimName.length() ) self.SetAnim( oldAnimName ); else self.SetAnim( "idle" ); animDone = false; } if ( !self.GetActorFlag(ACTOR_FLAG_PLAYING_DIALOG_ANIM) && !self.GetActorFlag(ACTOR_FLAG_DIALOG_PLAYING) && !self.talkMode == TALK_HEADWATCH ) { self.SetAnim( "idle" ); animDone = true; } if ( self.GetActorFlag(ACTOR_FLAG_PLAYING_DIALOG_ANIM) && animDone ) { if ( oldAnimName.length() ) { self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , true ); self.SetAnim( oldAnimName ); self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , false ); if ( mode != TALK_MODE_TURN_BACK ) mode = TALK_MODE_WAIT; } } switch( mode ) { case TALK_MODE_COMBAT: combatDialog = self.FindDialog( ent_listening, DIALOG_TYPE_COMBAT ); if ( !combatDialog.length() ) return BEHAVIOR_SUCCESS; self.PlayDialog( ent_listening , -1.0f, -1.0f, combatDialog.c_str() ); return BEHAVIOR_SUCCESS; break; case TALK_MODE_PLAY_GREETING: greetingDialog = self.FindDialog( ent_listening, DIALOG_TYPE_GREETING ); if ( !greetingDialog.length() ) { mode = TALK_MODE_TURN_TO; return BEHAVIOR_EVALUATING; } gi.LocalizeFilePath( greetingDialog.c_str(), localizedDialogName ); greetingDialogLength = gi.SoundLength( localizedDialogName ); if ( greetingDialogLength > 0 ) { greetingEvent = new Event(EV_TalkBehavior_GreetingDone); PostEvent(greetingEvent , greetingDialogLength ); Event *dialogEvent = new Event( EV_SimplePlayDialog ); dialogEvent->AddString( greetingDialog.c_str() ); ent_listening->ProcessEvent( dialogEvent ); //ent_listening->Sound( greetingDialog ); mode = TALK_MODE_WAIT_FOR_GREETING; } else { mode = TALK_MODE_TURN_TO; } break; case TALK_MODE_WAIT_FOR_GREETING: //Waiting on the Greeting Done Event Here break; case TALK_MODE_TURN_TO : if ( move_allowed ) { turnto.SetDirection( yaw ); if ( !turnto.Evaluate( self ) ) { mode = TALK_MODE_TALK; self.PlayDialog( ent_listening ); /* event = new Event( EV_Player_WatchActor ); event->AddEntity( &self ); ent_listening->PostEvent( event, 0.05 ); */ } } else { mode = TALK_MODE_TALK; self.PlayDialog( ent_listening ); /* event = new Event( EV_Player_WatchActor ); event->AddEntity( &self ); ent_listening->PostEvent( event, 0.05 ); */ } break; case TALK_MODE_TALK : if ( move_allowed ) { dir = ent_listening->centroid - self.centroid; angles = dir.toAngles(); turnto.SetDirection( angles[YAW] ); turnto.Evaluate( self ); } if ( !self.GetActorFlag( ACTOR_FLAG_DIALOG_PLAYING ) ) { mode = TALK_MODE_WAIT; self.state_flags &= ~STATE_FLAG_USED; // Tell player to stop watching us /* event = new Event( EV_Player_StopWatchingActor ); event->AddEntity( &self ); ent_listening->PostEvent( event, 0 ); */ //ent_listening->CancelEventsOfType( EV_Player_WatchActor ); } else if ( !self.GetActorFlag( ACTOR_FLAG_RADIUS_DIALOG_PLAYING ) ) { if ( !self.WithinDistance( ent_listening, self.radiusDialogRange ) ) { self.PlayRadiusDialog( ent_listening ); /* int postive_response = true; str check_alias; if (postive_response) { check_alias = self.GetRandomAlias("radiusdialog_positive"); if(check_alias.length()) { self.PlayRadiusDialog(ent_listening, "radiusdialog_positive"); } } else { check_alias = self.GetRandomAlias("radiusdialog_negative"); if(check_alias.length()) { self.PlayRadiusDialog(ent_listening, "radiusdialog_negative"); } } */ } } break; case TALK_MODE_WAIT : if ( move_allowed ) { dir = ent_listening->centroid - self.centroid; angles = dir.toAngles(); turnto.SetDirection( angles[YAW] ); turnto.Evaluate( self ); } if ( !self.WithinDistance( ent_listening, 100.0f ) ) mode = TALK_MODE_TURN_BACK; if ( self.state_flags & STATE_FLAG_USED ) { mode = TALK_MODE_TURN_TO; self.SetActorFlag(ACTOR_FLAG_PLAYING_DIALOG_ANIM, false ); dir = ent_listening->centroid - self.centroid; angles = dir.toAngles(); yaw = angles[YAW]; self.state_flags &= ~STATE_FLAG_USED; /* event = new Event( EV_Player_WatchActor ); event->AddEntity( &self ); ent_listening->PostEvent( event, 0.05 ); */ } break; case TALK_MODE_TURN_BACK : if ( move_allowed ) { turnto.SetDirection( original_yaw ); if ( !turnto.Evaluate( self ) ) return BEHAVIOR_SUCCESS; } else { return BEHAVIOR_SUCCESS; } break; } return BEHAVIOR_EVALUATING; } void Talk::End( Actor &self ) { self.SetActorFlag( ACTOR_FLAG_PLAYING_DIALOG_ANIM , false ); self.SetActorFlag(ACTOR_FLAG_CAN_CHANGE_ANIM , true ); self.ClearLegAnim(); self.ClearTorsoAnim(); if ( oldAnimName.length() ) { self.SetAnim( oldAnimName ); } else { self.SetAnim( "idle" ); } if ( last_headwatch_target ) self.headWatcher->SetWatchTarget( last_headwatch_target ); else self.headWatcher->SetWatchTarget( NULL ); }