ef2-sdk/dlls/game/rotateToEntity.cpp
2003-11-05 00:00:00 +00:00

240 lines
6.5 KiB
C++

//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/rotateToEntity.cpp $
// $Revision:: 12 $
// $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:
// RotateToEntity Behavior Implementation.
// -- Rotates the actor to face an entity. If no entity or entityType is specified, then it
// will rotate the actor to face its currentEnemy
//
// PARAMETERS:
// Optional turnspeed
// Optional entityType to turn to, either "enemy" (default) or "player"
//
// ANIMATIONS:
// Rotation Animation : Optional
//--------------------------------------------------------------------------------
#include "actor.h"
#include "rotateToEntity.hpp"
//--------------------------------------------------------------
//
// Class Declaration and Event Registration
//
//--------------------------------------------------------------
CLASS_DECLARATION( Behavior, RotateToEntity, NULL )
{
{ &EV_Behavior_Args, &RotateToEntity::SetArgs },
{ NULL, NULL }
};
//--------------------------------------------------------------
// Name: RotateToEntity()
// Class: RotateToEntity
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
RotateToEntity::RotateToEntity()
{
_anim = "";
_turnspeed = 10.0f;
_ent = NULL;
_entityType = "enemy";
}
//--------------------------------------------------------------
// Name: ~RotateToEntity()
// Class: RotateToEntity
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
RotateToEntity::~RotateToEntity()
{
}
//--------------------------------------------------------------
//
// Name: SetArgs()
// Class: RotateToEntity
//
// Description: Sets Variables based on arguments inside the event
//
// Parameters: Event *ev -- Event containing the string
//
// Returns: None
//
//--------------------------------------------------------------
void RotateToEntity::SetArgs( Event *ev )
{
// The Parmeters we're catching now are for turn speed
// and Animation ( both of which are optional ). We do not
// catch an entity here, because, I don't think there's a way
// to pass in an entity from the state machine. However, other
// behaviors CAN set the entity, so the functionality is here
// We also now take an entityType to turn to ("player" or "enemy")
int parmCount= ev->NumArgs();
if ( parmCount > 0 ) // Grab the turnSpeed
_turnspeed = ev->GetFloat( 1 );
if ( parmCount > 1 ) // Grab the animation
_anim = ev->GetString( 2 );
if ( parmCount > 2 ) // Grab the type of entity to find
_entityType = ev->GetString( 3 );
}
//--------------------------------------------------------------
//
// Name: Begin()
// Class: RotateToEntity
//
// Description: Initializes the behavior
//
// Parameters: Actor &self -- The actor executing this behavior
//
// Returns: None
//
//--------------------------------------------------------------
void RotateToEntity::Begin( Actor &self )
{
// Parameters should be set BEFORE we call begin, either through
// the SetArgs() or explicitly set through accessors
if ( !_ent )
{
if ( _entityType == "enemy" )
{
self.enemyManager->FindHighestHateEnemy();
_ent = self.enemyManager->GetCurrentEnemy();
}
else
{
Entity *player = (Entity*)GetPlayer(0);
if ( player && !(player->flags & FL_NOTARGET) )
{
_ent = player;
}
}
}
// Set our Animation if Appropriate
if ( _anim.length() && self.animate->HasAnim( _anim.c_str() ) )
self.SetAnim( _anim );
// Set up our turnSpeed
_oldTurnSpeed = self.movementSubsystem->getTurnSpeed();
self.movementSubsystem->setTurnSpeed( _turnspeed );
}
//--------------------------------------------------------------
//
// Name: Evaluate()
// Class: RotateToEntity
//
// Description: Update for this behavior -- called every server frame
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: BehaviorReturnCode_t
//
//--------------------------------------------------------------
BehaviorReturnCode_t RotateToEntity::Evaluate( Actor &self )
{
Vector dir;
Vector selfToEntity;
float yawDiff;
if ( !_ent )
{
SetFailureReason( "RotateToEntity: Has no Entity to Rotate To" );
//self.SetAnim( "idle" );
return BEHAVIOR_FAILED;
}
//
// Previously, we were just steering towards _ent->centroid. This worked,
// however it also has the unfortunate side-effect of pitching the actor
// if the entity it is rotating to is above it. This, of course, looks
// like poo... So, for an interim fix, we're going to set our target
// destination's z value to the actor's centroid z value, this, should
// prevent the pitch problem
//
Vector entityPos;
entityPos = _ent->centroid;
entityPos.z = self.centroid.z;
if ( self.IsEntityAlive( _ent ) )
{
dir = self.movementSubsystem->getMoveDir();
self.movementSubsystem->Accelerate(
self.movementSubsystem->SteerTowardsPoint( entityPos, vec_zero, dir, 1.0f)
);
}
//
// Here, again, I replaced the _ent->centroid with the z-value modified entityPos
//
selfToEntity = entityPos - self.centroid;
selfToEntity = selfToEntity.toAngles();
yawDiff = selfToEntity[YAW] - self.angles[YAW];
yawDiff = AngleNormalize180(yawDiff);
if ( yawDiff > -1.5 && yawDiff < 1.5 )
return BEHAVIOR_SUCCESS;
return BEHAVIOR_EVALUATING;
}
//--------------------------------------------------------------
//
// Name: End()
// Class: RotateToEntity
//
// Description: Ends this behavior -- cleans things up
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: None
//
//--------------------------------------------------------------
void RotateToEntity::End(Actor &self)
{
self.movementSubsystem->setTurnSpeed( _oldTurnSpeed );
}