mirror of
https://github.com/UberGames/EF2GameSource.git
synced 2024-11-10 06:31:42 +00:00
330 lines
8.2 KiB
C++
330 lines
8.2 KiB
C++
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// $Logfile:: /EF2/Code/DLLs/game/doAttack.cpp $
|
||
|
// $Revision:: 11 $
|
||
|
// $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:
|
||
|
// DoAttack Behavior Implementation
|
||
|
// -- DoAttack will rotate the actor to face his current enemy, after the
|
||
|
// the rotation( with optional animation ) has completed, it will check
|
||
|
// if the actor is able to hit its current enemy with an attack. If that
|
||
|
// check is successful, then it will play its specified attack animation.
|
||
|
//
|
||
|
// Currently, you must put the attack commands inside the animation.
|
||
|
//
|
||
|
// ANIMATIONS:
|
||
|
// Attack Animation : Parameter
|
||
|
// Rotation Animation : Optional
|
||
|
//--------------------------------------------------------------------------------
|
||
|
|
||
|
#include "actor.h"
|
||
|
#include "doAttack.hpp"
|
||
|
#include <qcommon/gameplaymanager.h>
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Class Declaration and Event Registration
|
||
|
//
|
||
|
//--------------------------------------------------------------
|
||
|
CLASS_DECLARATION( Behavior, DoAttack, NULL )
|
||
|
{
|
||
|
{ &EV_Behavior_Args, &DoAttack::SetArgs },
|
||
|
{ &EV_Behavior_AnimDone, &DoAttack::AnimDone },
|
||
|
{ NULL, NULL }
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Name: SetArgs()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
// Parameters: Event *ev -- Event containing the string
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
//--------------------------------------------------------------
|
||
|
void DoAttack::SetArgs( Event *ev )
|
||
|
{
|
||
|
_anim = ev->GetString( 1 );
|
||
|
if ( ev->NumArgs() > 1 )
|
||
|
_turnspeed = ev->GetFloat( 2 );
|
||
|
else
|
||
|
_turnspeed = 30.0f;
|
||
|
|
||
|
if ( ev->NumArgs() > 2 )
|
||
|
_forceAttack = ev->GetBoolean( 3 );
|
||
|
else
|
||
|
_forceAttack = false;
|
||
|
|
||
|
if ( ev->NumArgs() > 3 )
|
||
|
_rotateAnim = ev->GetString( 4 );
|
||
|
else
|
||
|
_rotateAnim = "";
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// Name: AnimDone()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: AnimDone Event Handler
|
||
|
//
|
||
|
// Parameters: Event *ev -- The AnimDone event
|
||
|
//
|
||
|
// Returns: None
|
||
|
//--------------------------------------------------------------
|
||
|
void DoAttack::AnimDone( Event *ev )
|
||
|
{
|
||
|
_state = ATTACK_STATE_COMPLETE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Name: Begin()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: Initializes the behavior
|
||
|
//
|
||
|
// Parameters: Actor &self -- The actor executing this behavior
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
//--------------------------------------------------------------
|
||
|
void DoAttack::Begin( Actor &self )
|
||
|
{
|
||
|
init ( self );
|
||
|
_setupRotate( self );
|
||
|
_state = ATTACK_STATE_ROTATE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Name: Evaluate()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: Update for this behavior -- called every server frame
|
||
|
//
|
||
|
// Parameters: Actor &self -- Actor executing this behavior
|
||
|
//
|
||
|
// Returns: BehaviorReturnCode_t
|
||
|
//
|
||
|
//--------------------------------------------------------------
|
||
|
BehaviorReturnCode_t DoAttack::Evaluate( Actor &self )
|
||
|
{
|
||
|
if ( _state != ATTACK_STATE_ANIMATING )
|
||
|
_rotate( self );
|
||
|
|
||
|
if ( _state == ATTACK_STATE_START_ANIM )
|
||
|
{
|
||
|
_playAttackAnim( self );
|
||
|
_state = ATTACK_STATE_ANIMATING;
|
||
|
}
|
||
|
|
||
|
if ( _state == ATTACK_STATE_FAILED )
|
||
|
return BEHAVIOR_FAILED;
|
||
|
|
||
|
if ( _state == ATTACK_STATE_COMPLETE )
|
||
|
return BEHAVIOR_SUCCESS;
|
||
|
|
||
|
return BEHAVIOR_EVALUATING;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Name: End()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: Ends this behavior -- cleans things up
|
||
|
//
|
||
|
// Parameters: Actor &self -- Actor executing this behavior
|
||
|
//
|
||
|
// Returns: None
|
||
|
//
|
||
|
//--------------------------------------------------------------
|
||
|
void DoAttack::End(Actor &self)
|
||
|
{
|
||
|
_rotateBehavior.End(self);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// Name: _setupRotate()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: Sets up the Rotate Component Behavior
|
||
|
//
|
||
|
// Parameters: Actor &self -- Actor executing this behavior
|
||
|
//
|
||
|
// Returns: None
|
||
|
//--------------------------------------------------------------
|
||
|
void DoAttack::_setupRotate( Actor &self )
|
||
|
{
|
||
|
Entity *currentEnemy;
|
||
|
currentEnemy = self.enemyManager->GetCurrentEnemy();
|
||
|
|
||
|
if ( currentEnemy )
|
||
|
{
|
||
|
_rotateBehavior.SetEntity( currentEnemy );
|
||
|
_rotateBehavior.SetTurnSpeed( _turnspeed );
|
||
|
if ( _rotateAnim.length() )
|
||
|
_rotateBehavior.SetAnim( _rotateAnim );
|
||
|
|
||
|
_rotateBehavior.Begin( self );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// Name: _rotate()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: Evaluates the Rotate Component Behavior
|
||
|
//
|
||
|
// Parameters: Actor &self -- Actor executing this behavior
|
||
|
//
|
||
|
// Returns: None
|
||
|
//--------------------------------------------------------------
|
||
|
void DoAttack::_rotate( Actor &self )
|
||
|
{
|
||
|
BehaviorReturnCode_t result;
|
||
|
|
||
|
result = _rotateBehavior.Evaluate( self );
|
||
|
|
||
|
// If we get a failure from rotate, chances are it didn't have
|
||
|
// an entity to rotate to... Let's give it one more shot.
|
||
|
if ( result == BEHAVIOR_FAILED )
|
||
|
{
|
||
|
_setupRotate( self );
|
||
|
result = _rotateBehavior.Evaluate( self );
|
||
|
|
||
|
// If we have a failure again, then we DO have a serious
|
||
|
// problem
|
||
|
if ( result == BEHAVIOR_FAILED )
|
||
|
{
|
||
|
str failureReason;
|
||
|
failureReason = "Rotate Component Failed: Returned -- ";
|
||
|
failureReason += _rotateBehavior.GetFailureReason();
|
||
|
SetFailureReason( failureReason );
|
||
|
_state = ATTACK_STATE_FAILED;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( result == BEHAVIOR_SUCCESS )
|
||
|
{
|
||
|
if ( _canAttack( self ) )
|
||
|
{
|
||
|
if ( _state != ATTACK_STATE_ANIMATING && _state != ATTACK_STATE_COMPLETE )
|
||
|
{
|
||
|
_state = ATTACK_STATE_START_ANIM;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
_state = ATTACK_STATE_FAILED;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// Name: _playAttackAnim()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: Plays the specified attack animation
|
||
|
//
|
||
|
// Parameters: Actor &self -- Actor executing this behavior
|
||
|
//
|
||
|
// Returns: None
|
||
|
//--------------------------------------------------------------
|
||
|
void DoAttack::_playAttackAnim( Actor &self )
|
||
|
{
|
||
|
self.ClearTorsoAnim();
|
||
|
self.SetAnim( _anim , EV_Actor_NotifyBehavior);
|
||
|
_state = ATTACK_STATE_ANIMATING;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// Name: _canAttack()
|
||
|
// Class: DoAttack
|
||
|
//
|
||
|
// Description: Checks if the actor can attack
|
||
|
//
|
||
|
// Parameters: Actor &self -- Actor executing this behavior
|
||
|
//
|
||
|
// Returns: None
|
||
|
//--------------------------------------------------------------
|
||
|
bool DoAttack::_canAttack( Actor &self )
|
||
|
{
|
||
|
Entity *currentEnemy;
|
||
|
currentEnemy = self.enemyManager->GetCurrentEnemy();
|
||
|
|
||
|
if ( _forceAttack )
|
||
|
return true;
|
||
|
|
||
|
if ( !currentEnemy)
|
||
|
return false;
|
||
|
|
||
|
if ( self.combatSubsystem->CanAttackTarget( currentEnemy ) )
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void DoAttack::init( Actor &self )
|
||
|
{
|
||
|
GameplayManager *gpm = GameplayManager::getTheGameplayManager();
|
||
|
if ( !gpm->hasObject(self.getArchetype()) )
|
||
|
return;
|
||
|
|
||
|
if ( !self.combatSubsystem->HaveWeapon() )
|
||
|
return;
|
||
|
|
||
|
str objname = self.combatSubsystem->GetActiveWeaponArchetype();
|
||
|
objname = "Hold" + objname;
|
||
|
|
||
|
if ( gpm->hasProperty(objname, "Melee") )
|
||
|
_anim = gpm->getStringValue( objname , "Melee" );
|
||
|
else
|
||
|
{
|
||
|
str weaponName = self.combatSubsystem->GetActiveWeaponName();
|
||
|
|
||
|
if ( !weaponName.length() )
|
||
|
{
|
||
|
weaponName = "UNSPECIFIED";
|
||
|
}
|
||
|
|
||
|
gi.WDPrintf( "\n\n\nDoAttack: TargetName %s ( Entnum %i ) has a weapon, but does not have a MeleeProperty ( Trying Weapon: %s ) in the GPD, Please notify a programmer of this error\n\n\n" , self.TargetName() , self.entnum, weaponName.c_str() );
|
||
|
//gi.Error( ERR_DROP , "\n\n\nDoAttack: TargetName %s ( Entnum %i ) has a weapon, but does not have a MeleeProperty ( Trying Weapon: %s ) in the GPD, Please notify a programmer of this error\n\n\n" , self.TargetName() , self.entnum, weaponName.c_str() );
|
||
|
}
|
||
|
|
||
|
}
|