ef2gamesource/dlls/game/stationaryFireCombat.cpp

604 lines
14 KiB
C++

//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/stationaryFireCombat.cpp $
// $Revision:: 7 $
// $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:
// StationaryFireCombat Implementation
//
// PARAMETERS:
//
// ANIMATIONS:
//--------------------------------------------------------------------------------
#include "actor.h"
#include "stationaryFireCombat.hpp"
//--------------------------------------------------------------
//
// Class Declaration and Event Registration
//
//--------------------------------------------------------------
CLASS_DECLARATION( Behavior, StationaryFireCombat, NULL )
{
{ &EV_Behavior_Args, &StationaryFireCombat::SetArgs },
{ &EV_Behavior_AnimDone, &StationaryFireCombat::AnimDone },
{ NULL, NULL }
};
//--------------------------------------------------------------
// Name: StationaryFireCombat()
// Class: StationaryFireCombat
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
StationaryFireCombat::StationaryFireCombat()
{
_endFireTime = 0.0f;
_endAimTime = 0.0f;
}
//--------------------------------------------------------------
// Name: ~StationaryFireCombat()
// Class: StationaryFireCombat
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
StationaryFireCombat::~StationaryFireCombat()
{
}
//--------------------------------------------------------------
// Name: SetArgs()
// Class: StationaryFireCombat
//
// Description: Sets Arguments for this behavior
//
// Parameters: Event *ev -- Event holding the arguments
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::SetArgs( Event *ev )
{
_aimAnim = ev->GetString( 1 );
_preFireAnim = ev->GetString( 2 );
_fireAnim = ev->GetString( 3 );
_postFireAnim = ev->GetString( 4 );
_stance = ev->GetString( 5 );
_aimTimeMin = ev->GetFloat( 6 );
_aimTimeMax = ev->GetFloat( 7 );
_fireTimeMin = ev->GetFloat( 8 );
_fireTimeMax = ev->GetFloat( 9 );
}
//--------------------------------------------------------------
// Name: AnimDone()
// Class: StationaryFireCombat
//
// Description: Handles an animation completion
//
// Parameters: Event *ev -- Event holding the completion notification
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::AnimDone( Event * )
{
_animDone = true;
}
//--------------------------------------------------------------
// Name: Begin()
// Class: StationaryFireCombat
//
// Description: Initializes the behavior
//
// Parameters: Actor &self -- The actor executing this behavior
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::Begin( Actor &self )
{
init( self );
transitionToState ( STATIONARY_FIRE_AIM );
}
//--------------------------------------------------------------
// Name: Evaluate()
// Class: StationaryFireCombat
//
// Description: Evaluates the behavior
//
// Parameters: Actor &self -- The actor executing this behavior
//
// Returns: BehaviorReturnCode_t
//--------------------------------------------------------------
BehaviorReturnCode_t StationaryFireCombat::Evaluate( Actor & )
{
BehaviorReturnCode_t stateResult;
think();
switch ( _state )
{
//---------------------------------------------------------------------
case STATIONARY_FIRE_AIM:
//---------------------------------------------------------------------
stateResult = evaluateStateAim();
if ( stateResult == BEHAVIOR_SUCCESS )
{
updateEnemy();
if ( _preFireAnim.length() )
transitionToState( STATIONARY_FIRE_PRE_FIRE );
else
transitionToState( STATIONARY_FIRE_ATTACK );
}
break;
//---------------------------------------------------------------------
case STATIONARY_FIRE_PRE_FIRE:
//---------------------------------------------------------------------
stateResult = evaluateStatePreFire();
if ( stateResult == BEHAVIOR_SUCCESS )
{
transitionToState( STATIONARY_FIRE_ATTACK );
}
if ( stateResult == BEHAVIOR_FAILED )
{
transitionToState( STATIONARY_FIRE_FAILED );
}
break;
//---------------------------------------------------------------------
case STATIONARY_FIRE_ATTACK:
//---------------------------------------------------------------------
stateResult = evaluateStateAttack();
if ( stateResult == BEHAVIOR_SUCCESS )
{
_fireWeapon.End( *_self );
if ( _postFireAnim.length() )
transitionToState( STATIONARY_FIRE_POST_FIRE );
else
transitionToState( STATIONARY_FIRE_SUCCESS );
}
if ( stateResult == BEHAVIOR_FAILED )
{
_fireWeapon.End( *_self );
if ( _postFireAnim.length() )
transitionToState( STATIONARY_FIRE_POST_FIRE );
else
transitionToState( STATIONARY_FIRE_SUCCESS );
}
break;
//---------------------------------------------------------------------
case STATIONARY_FIRE_POST_FIRE:
//---------------------------------------------------------------------
stateResult = evaluateStatePostFire();
if ( stateResult == BEHAVIOR_SUCCESS )
{
transitionToState( STATIONARY_FIRE_SUCCESS );
}
break;
//---------------------------------------------------------------------
case STATIONARY_FIRE_SUCCESS:
//---------------------------------------------------------------------
return BEHAVIOR_SUCCESS;
break;
//---------------------------------------------------------------------
case STATIONARY_FIRE_FAILED:
//---------------------------------------------------------------------
return BEHAVIOR_FAILED;
break;
}
return BEHAVIOR_EVALUATING;
}
//--------------------------------------------------------------
// Name: End()
// Class: StationaryFireCombat
//
// Description: Cleans Up the behavior
//
// Parameters: Actor &self -- The actor executing this behavior
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::End(Actor &)
{
if ( !_self )
return;
_fireWeapon.End(*_self);
_self->SetAnim( _aimAnim , NULL , torso );
_self->ClearTorsoAnim();
}
//--------------------------------------------------------------
// Name: transitionToState()
// Class: StationaryFireCombat
//
// Description: Transitions the behaviors state
//
// Parameters: coverCombatStates_t state -- The state to transition to
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::transitionToState( StationaryFireStates_t state )
{
switch ( state )
{
case STATIONARY_FIRE_AIM:
setupStateAim();
setInternalState( state , "STATIONARY_FIRE_AIM" );
break;
case STATIONARY_FIRE_PRE_FIRE:
setupStatePreFire();
setInternalState( state , "STATIONARY_FIRE_PRE_FIRE" );
break;
case STATIONARY_FIRE_ATTACK:
setupStateAttack();
setInternalState( state , "STATIONARY_FIRE_ATTACK" );
break;
case STATIONARY_FIRE_POST_FIRE:
setupStatePostFire();
setInternalState( state , "STATIONARY_FIRE_POST_FIRE" );
break;
case STATIONARY_FIRE_SUCCESS:
setInternalState( state , "STATIONARY_FIRE_SUCCESS" );
break;
case STATIONARY_FIRE_FAILED:
setInternalState( state , "SUPPRESSION_FIRE_FAILED" );
break;
}
}
//--------------------------------------------------------------
// Name: setInternalState()
// Class: StationaryFireCombat
//
// Description: Sets the internal state of the behavior
//
// Parameters: unsigned int state
// const str &stateName
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::setInternalState( StationaryFireStates_t state , const str &stateName )
{
_state = state;
SetInternalStateName( stateName );
}
//--------------------------------------------------------------
// Name: init()
// Class: StationaryFireCombat
//
// Description: Initializes the behavior
//
// Parameters: Actor &self
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::init( Actor &self )
{
_self = &self;
_animDone = false;
_canAttack = true;
updateEnemy();
}
//--------------------------------------------------------------
// Name: think()
// Class: StationaryFireCombat
//
// Description: Does any processing required before evaluating states
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::think()
{
}
//--------------------------------------------------------------
// Name: StationaryFireCombat()
// Class: setupStateAttack
//
// Description: Sets up our Attack State
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::setupStateAttack()
{
faceEnemy();
_endFireTime = level.time + G_Random(_fireTimeMax - _fireTimeMin) + _fireTimeMin;
if ( _self->combatSubsystem->CanAttackEnemy() )
{
_fireWeapon.SetAnim( _fireAnim );
_fireWeapon.Begin( *_self );
}
}
//--------------------------------------------------------------
// Name: evaluateStateAttack()
// Class: StationaryFireCombat
//
// Description: Evaluates our Attack State
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
BehaviorReturnCode_t StationaryFireCombat::evaluateStateAttack()
{
BehaviorReturnCode_t result;
_rotateToEntity.Evaluate( *_self );
if ( _self->combatSubsystem->CanAttackEnemy() )
result = _fireWeapon.Evaluate( *_self );
else
{
_fireWeapon.End( *_self );
result = BEHAVIOR_FAILED;
}
if ( result == BEHAVIOR_FAILED )
failureStateAttack( "StationaryFireCombat::evaluateStateAttack -- FAILED" );
if ( level.time > _endFireTime )
return BEHAVIOR_SUCCESS;
return BEHAVIOR_EVALUATING;
}
//--------------------------------------------------------------
// Name: failureStateAttack()
// Class: StationaryFireCombat
//
// Description: Failure Handler for Attack State
//
// Parameters: const str &failureReason
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::failureStateAttack( const str &failureReason )
{
SetFailureReason( failureReason );
_fireWeapon.End( *_self );
}
//--------------------------------------------------------------
// Name: setupStatePause()
// Class: StationaryFireCombat
//
// Description: Sets up our Pause State
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::setupStateAim()
{
faceEnemy();
_endAimTime = level.time + G_Random(_aimTimeMax - _aimTimeMin ) + _aimTimeMin;
_self->SetAnim( _aimAnim , NULL , torso );
_self->SetAnim( _stance , NULL , legs );
}
//--------------------------------------------------------------
// Name: evaluateStatePause()
// Class: StationaryFireCombat
//
// Description: Evaluates our Pause State
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
BehaviorReturnCode_t StationaryFireCombat::evaluateStateAim()
{
_rotateToEntity.Evaluate( *_self );
if ( level.time > _endAimTime )
return BEHAVIOR_SUCCESS;
return BEHAVIOR_EVALUATING;
}
//--------------------------------------------------------------
// Name: failureStatePause()
// Class: StationaryFireCombat
//
// Description: Failure Handler for our Pause State
//
// Parameters: const str &failureReason
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::failureStateAim( const str &failureReason )
{
SetFailureReason( failureReason );
}
void StationaryFireCombat::setupStatePreFire()
{
if ( _self->combatSubsystem->CanAttackEnemy() )
{
_animDone = false;
_self->SetAnim( _preFireAnim , EV_Actor_NotifyBehavior , torso );
}
else
_canAttack = false;
}
BehaviorReturnCode_t StationaryFireCombat::evaluateStatePreFire()
{
if ( _animDone )
return BEHAVIOR_SUCCESS;
if ( !_canAttack )
return BEHAVIOR_FAILED;
return BEHAVIOR_EVALUATING;
}
void StationaryFireCombat::failureStatePreFire( const str &failureReason )
{
Q_UNUSED(failureReason);
}
void StationaryFireCombat::setupStatePostFire()
{
_animDone = false;
_self->SetAnim( _postFireAnim , EV_Actor_NotifyBehavior , torso );
}
BehaviorReturnCode_t StationaryFireCombat::evaluateStatePostFire()
{
if ( _animDone )
return BEHAVIOR_SUCCESS;
return BEHAVIOR_FAILED;
}
void StationaryFireCombat::failureStatePostFire( const str &failureReason )
{
Q_UNUSED(failureReason);
}
//--------------------------------------------------------------
// Name: updateEnemy()
// Class: StationaryFireCombat
//
// Description: Sets our _currentEnemy
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::updateEnemy()
{
Entity *currentEnemy = _self->enemyManager->GetCurrentEnemy();
if ( !currentEnemy )
{
_self->enemyManager->FindHighestHateEnemy();
currentEnemy = _self->enemyManager->GetCurrentEnemy();
if ( !currentEnemy )
{
SetFailureReason( "STATIONARY_FIRE_FAILED::updateEnemy -- No Enemy" );
transitionToState( STATIONARY_FIRE_FAILED );
return;
}
}
_currentEnemy = currentEnemy;
//_self->turnTowardsEntity( _currentEnemy, 0.0f );
}
//--------------------------------------------------------------
// Name: faceEnemy()
// Class: StationaryFireCombat
//
// Description: Sets up the Rotate Component
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void StationaryFireCombat::faceEnemy()
{
_rotateToEntity.SetEntity( _currentEnemy );
_rotateToEntity.SetTurnSpeed( 30.0f );
_rotateToEntity.Begin( *_self );
}