434 lines
10 KiB
C++
434 lines
10 KiB
C++
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// $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 <qcommon/gameplaymanager.h>
|
||
|
|
||
|
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 );
|
||
|
}
|
||
|
|
||
|
|