ef2-sdk/dlls/game/talk.cpp

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 );
}