📄 behavior.cpp
字号:
//-----------------------------------------------------------------------------
//
// $Logfile:: /Quake 2 Engine/Sin/code/game/behavior.cpp $
// $Revision:: 117 $
// $Author:: Markd $
// $Date:: 11/20/98 7:17p $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/behavior.cpp $
//
// 117 11/20/98 7:17p Markd
// Fixed Hide behavior
//
// 116 11/18/98 8:53p Markd
// Made nearestnode check for one without bounding box for thrall
//
// 115 11/18/98 7:47p Markd
// made it so FindNearEnemy doesn't use bounding box mainly for THrall
//
// 114 11/15/98 8:02p Jimdose
// Swimming monsters no longer choose random directions that are in air
// Flying monsters no longer choose random directions that are in water
// Actors using FindEnemy no longer get stuck when the nearest node to them is
// the same as the nearest node to the enemy.
//
// 113 11/15/98 1:24a Jimdose
// monsters don't play snd_sightenemy now unless DoAction( "sightenemy" )
// succeeds.
//
// 112 11/13/98 3:29p Markd
// Fixed some ChooseRandomDirection stuff
//
// 111 11/07/98 8:14p Jimdose
// Made it so Hide and FleeAndRemove ensure the guy either runs away or
// crouches down
//
// 110 10/27/98 7:48p Jimdose
// Added PlayAnimSeekEnemy
//
// 109 10/27/98 3:52a Markd
// put in state = 0 if can't resolve FindEnemy
//
// 108 10/27/98 12:42a Jimdose
// added animprefix to AimAndShoot
//
// 107 10/26/98 2:18p Markd
// Put in last_jump_time support
//
// 106 10/25/98 4:56a Jimdose
// Fixed bug with chase where guys would do a spin at the end of a path
// Changed wait time in opendoor
// made FindEnemy check if the enemy has moved far before doing another search
//
// 105 10/23/98 4:44a Markd
// made jump early exit if no land animation
//
// 104 10/23/98 12:30a Markd
// Fixed up Flee behavior
//
// 103 10/22/98 11:36p Jimdose
// Added GetCloseToEnemy
// Changed FindEnemy's seektime
//
// 102 10/20/98 11:29p Markd
// guys won't get stuck aiming anymore
//
// 101 10/20/98 4:05a Markd
// made snd_idle more frequent in wander
//
// 100 10/20/98 3:52a Markd
// Added idle chatter to Wander
//
// 99 10/20/98 2:37a Markd
// Put in ClearEnemies and JumpTo modifications
//
// 98 10/19/98 12:07a Jimdose
// made all code use fast checks for inheritance (no text lookups when
// possible)
// isSubclassOf no longer requires ::_classinfo()
//
// 97 10/18/98 4:11p Markd
// Made FindEnemy not use FindClosestSightNode
//
// 96 10/18/98 12:34a Markd
// Added randomness to AimAndShoot and AimAndMelee
//
// 95 10/17/98 11:01p Markd
// Added code to AimAndShoot
//
// 94 10/17/98 4:43p Markd
// Added curious time and xydist to Investigate
//
// 93 10/17/98 4:05p Markd
// replaced OpenDOor initial trace with vec_zero's again
//
// 92 10/17/98 3:30p Markd
// Fixed OpenDoor code not taking into account bounding boxes
//
// 91 10/17/98 12:34a Markd
// Commented out warning for the time being
//
// 90 10/16/98 7:20p Markd
// put in numshots for AimAndMelee, also tweaked PlayAnim warning reporting
//
// 89 10/14/98 11:53p Markd
// If PlayAnim doesn't resolve an anim, make sure and post and EndBehavior
//
// 88 10/14/98 9:02p Markd
// Made the Jump behavior more robust, and added landing
//
// 87 10/14/98 5:20p Markd
// Updated Jump behavior
//
// 86 10/14/98 2:17a Markd
// Took out can_melee code
//
// 85 10/14/98 1:27a Markd
// Put in can_melee in FindEnemy
//
// 84 10/13/98 11:13p Markd
// Scaled anim_deltas and fixed closeattacks not waiting long enough to reach
// player
//
// 83 10/13/98 9:11p Markd
// Fixed RandomChooseDirection bug
//
// 82 10/13/98 7:38p Markd
// Created behaviors for Wander, Fly, FLyCloseAttack, and WanderCloseAttack
//
// 81 10/13/98 12:25a Markd
// Fixed swimming creatures AGAIN!
//
// 80 10/10/98 6:08p Markd
// Added FleeAndRemove, FindFlee, fixed max_ainode bug
//
// 79 10/10/98 5:01p Markd
// Changed trace masks to edict->clipmasks
//
// 78 10/10/98 3:27p Markd
// Fixed FindEnemy behavior
//
// 77 10/09/98 11:57p Markd
// Fixed up melee close range attacks
//
// 76 10/06/98 5:25p Markd
// Added ForceAction, hopefully fixed some sightEnemy issues
//
// 75 10/05/98 10:32p Markd
// Made Strafe Attack use a random strafe direction, also tweaked
// SwimCloseAttack
//
// 74 10/05/98 4:36p Markd
// Clear out seenEnemy
//
// 73 10/05/98 3:04p Markd
// Added miss detection to AimAndShoot
//
// 72 10/05/98 12:29a Jimdose
// moved angledist to q_shared
//
// 71 10/04/98 7:49p Markd
// When done GotoPathNode, play the idle animation if no animation exists at
// the movegoal
//
// 70 10/04/98 5:32p Markd
// Fixed ChooseRandomDirection problems
//
// 69 10/04/98 3:47p Markd
// fixed swimming getting stuck
//
// 68 10/04/98 3:01p Markd
// fixed swimming behavior
//
// 67 10/03/98 7:19p Markd
// Added SwimCloseAttack and Melee behaviors
//
// 66 10/01/98 8:00p Markd
// Added AimAndMelee
//
// 65 10/01/98 4:14p Jimdose
// Improved Aim::Evaluate so that it properly targets partially obscured guys.
//
// 64 9/22/98 4:16a Jimdose
// Made GotoPathNode check new paths every 4 seconds instead of every 20.
//
// 63 9/22/98 1:54a Jimdose
// Completed ShowInfo for all behaviors
// Added StrafeTo
//
// 62 9/18/98 10:56p Jimdose
// Separated steering behaviors into their own file
// Made AimAndShoot exit when enemy is killed while aiming
//
// 61 9/14/98 5:29p Jimdose
// Added SetPathRate to Chase so that actors can choose how often they search
// for a new path.
// NearestNode now requires that you pass in the entity that is going to use
// the path.
//
// 60 8/31/98 7:48p Jimdose
// Removed unused variables from FollowPath
//
// 59 8/31/98 7:46p Jimdose
// Simplified FollowPath
//
// 58 8/29/98 9:39p Jimdose
// Added call info to G_Trace
//
// 57 8/26/98 11:13p Jimdose
// Added StrafeAttack
//
// 56 8/24/98 6:57p Jimdose
// Moved hueristics for path finding to actor
// Modified how closely actors follow paths
//
// 55 8/19/98 8:47p Jimdose
// Added Jump behavior
//
// 54 8/19/98 7:58p Jimdose
// took out debug print
// starting jump node support
//
// 53 8/19/98 4:00p Jimdose
// Made PickupAndThrow exit if it has a NULL pickup_target
//
// 52 8/19/98 2:31p Jimdose
// Changed Chase so that if the target is an entity, it ends when it touches
// that entity.
//
// 51 8/18/98 10:00p Jimdose
// Actors follow paths tighter when near doors
//
// 50 8/15/98 11:18p Jimdose
// Extended reach for opening doors
//
// 49 8/14/98 8:30p Jimdose
// TurnTo now doesn't return false when turning to ents. (need to change
// eventually).
// FindEnemy now searches based on CanShoot rather than CanSee
//
// 48 8/14/98 6:26p Jimdose
// Got rid of decelleration for steering
// Added GoalEnt to GotoPathNode
// Added check for arrival to seek. Reduces running in circles
//
// 47 8/12/98 2:12p Markd
// fixed initialization of bestnode parameter in FindWanderNode
//
// 46 8/10/98 6:51p Aldie
// Modified wander behavior a little to make it less intensive
//
// 45 8/09/98 5:49p Markd
// Rewrote ThrowObjects pickup and throw
//
// 44 8/08/98 8:39p Markd
// fixed throwing bug
//
// 43 8/08/98 8:41p Jimdose
// Fixed oscillating problem in Aim
//
// 42 8/08/98 8:24p Markd
// working on pickupandthrow behavior
//
// 41 8/07/98 8:47p Markd
// working on pickupandthrow
//
// 40 8/07/98 6:01p Jimdose
// Rewrote AimAndShoot
//
// 39 8/06/98 6:57p Jimdose
// Removed FireFromCover (now done in script)
// Added SetArgs to AimAndShoot
//
// 38 8/05/98 7:18p Jimdose
// Renamed states
//
// 37 8/03/98 7:58p Aldie
// Added a first attempt at wander behavior
//
// 36 7/26/98 11:43a Jimdose
// Tweaked hiding behavior
//
// 35 7/26/98 6:39a Jimdose
// Avoiding occupied nodes now works
//
// 34 7/26/98 3:48a Jimdose
// Modified aim based on skill
//
// 33 7/26/98 2:45a Jimdose
// Changed pathway_t structure
//
// 32 7/25/98 2:09a Jimdose
// FindCoverNode now uses the closest cover node to search from, rather than
// choosing a random node and letting the search algorithm find a closer one.
//
// 31 7/22/98 10:51p Jimdose
// Added repel behavior
//
// 30 7/21/98 4:14p Jimdose
// disabled the - operator on Vectors
//
// 29 7/19/98 9:19p Jimdose
// Fixed bug in FindCoverNode where the actor would try searching for a path
// to every cover node in the level.
//
// 28 7/08/98 9:00p Jimdose
// Made OpenDoor script callable
//
// 27 7/06/98 1:06p Jimdose
// working on ai
//
// 26 6/30/98 6:03p Jimdose
// Chase and GotoPathNode now can use vectors for goals
// Investigate no longer needs currentEnemy to be set
//
// 25 6/25/98 8:11p Jimdose
// Changed Idle stuff
//
// 24 6/24/98 4:26p Jimdose
// Fixed bugs in TurnTo
//
// 23 6/17/98 9:59p Jimdose
// Changed path radius
//
// 22 6/17/98 3:03p Markd
// Changed NumArgs back to previous behavior
//
// 21 6/17/98 1:19a Jimdose
// Removed TargetEnemies. Moved it back into actor
// Working on weapon firing and sighting enemies
//
// 20 6/15/98 10:47p Jimdose
// Added Hide, and CoverFire
//
// 19 6/13/98 8:23p Jimdose
// Added FindCover
//
// 18 6/11/98 12:44a Jimdose
// behaviors now get info from the script at startup
//
// 17 6/10/98 10:25p Jimdose
// Added priority based state system
//
// 16 6/09/98 5:34p Jimdose
// made flee better at finding a random node.
//
// 15 6/09/98 4:18p Jimdose
// worked on ai
//
// 14 6/04/98 10:48p Jimdose
// Fixed a bunch of things that got broken just in time for E3. Paths and
// scripting actually work now.
//
// 13 6/03/98 5:43p Jimdose
// Fixed spelling of behavior. :)
//
// 12 5/27/98 7:12a Jimdose
// ai ai ai
//
// 11 5/27/98 6:39a Jimdose
// working on ai
//
// 10 5/27/98 5:11a Jimdose
// working on ai
//
// 9 5/25/98 5:31p Jimdose
// Pathnodes are no longer a subclass of Entity. This was done to save on
// edicts
//
// 8 5/25/98 1:06a Jimdose
// Added chatter
//
// 7 5/24/98 1:02a Jimdose
// added Investigate
//
// 6 5/23/98 6:27p Jimdose
// improved steering code
//
// 5 5/22/98 9:45p Jimdose
// Disabled debug lines for forces
//
// 4 5/22/98 9:36p Jimdose
// AI Scripting works again (somewhat)
//
// 3 5/20/98 6:36p Jimdose
// Working on ai
//
// 2 5/18/98 8:15p Jimdose
// Created file
//
// DESCRIPTION:
// Behaviors used by the AI.
//
#include "g_local.h"
#include "behavior.h"
#include "actor.h"
#include "doors.h"
#include "object.h"
Event EV_Behavior_Args( "args" );
Event EV_Behavior_AnimDone( "animdone" );
/****************************************************************************
Behavior Class Definition
****************************************************************************/
CLASS_DECLARATION( Listener, Behavior, NULL );
ResponseDef Behavior::Responses[] =
{
{ NULL, NULL }
};
Behavior::Behavior()
{
}
void Behavior::ShowInfo
(
Actor &self
)
{
if ( movegoal )
{
gi.printf( "movegoal: ( %f, %f, %f ) - '%s'\n",
movegoal->worldorigin.x, movegoal->worldorigin.y, movegoal->worldorigin.z, movegoal->targetname.c_str() );
}
else
{
gi.printf( "movegoal: NULL\n" );
}
}
void Behavior::Begin
(
Actor &self
)
{
}
qboolean Behavior::Evaluate
(
Actor &self
)
{
return false;
}
void Behavior::End
(
Actor &self
)
{
}
/****************************************************************************
Idle Class Definition
****************************************************************************/
CLASS_DECLARATION( Behavior, Idle, NULL );
ResponseDef Idle::Responses[] =
{
{ &EV_Behavior_Args, ( Response )Idle::SetArgs },
{ NULL, NULL }
};
void Idle::SetArgs
(
Event *ev
)
{
anim = ev->GetString( 2 );
}
void Idle::ShowInfo
(
Actor &self
)
{
Behavior::ShowInfo( self );
gi.printf( "\nnexttwitch : %f\n", nexttwitch );
gi.printf( "anim : %s\n", anim.c_str() );
}
void Idle::Begin
(
Actor &self
)
{
self.currentEnemy = NULL;
self.seenEnemy = false;
nexttwitch = level.time + 10 + G_Random( 30 );
if ( anim.length() )
{
self.SetAnim( anim );
}
}
qboolean Idle::Evaluate
(
Actor &self
)
{
if ( self.currentEnemy )
{
if ( self.DoAction( "sightenemy" ) )
{
self.seenEnemy = true;
self.Chatter( "snd_sightenemy", 5 );
}
else
{
self.currentEnemy = NULL;
}
return true;
}
if ( nexttwitch < level.time )
{
self.chattime += 10;
self.DoAction( "twitch" );
return true;
}
else
{
self.Chatter( "snd_idle", 1 );
}
return true;
}
void Idle::End
(
Actor &self
)
{
}
/****************************************************************************
Aim Class Definition
****************************************************************************/
CLASS_DECLARATION( Behavior, Aim, NULL );
ResponseDef Aim::Responses[] =
{
{ NULL, NULL }
};
void Aim::SetTarget
(
Entity *ent
)
{
target = ent;
}
void Aim::ShowInfo
(
Actor &self
)
{
Behavior::ShowInfo( self );
gi.printf( "\nseek:\n" );
seek.ShowInfo( self );
if ( target )
{
gi.printf( "\ntarget : #%d '%s'\n", target->entnum, target->targetname.c_str() );
}
else
{
gi.printf( "\ntarget : NULL\n" );
}
}
void Aim::Begin
(
Actor &self
)
{
seek.Begin( self );
}
qboolean Aim::Evaluate
(
Actor &self
)
{
Vector dir;
Vector ang;
Vector pos;
if ( !target )
{
return false;
}
//
// get my gun pos
//
pos = self.GunPosition();
ang = self.MyGunAngles( pos, false );
//
// invert PITCH
//
ang[ PITCH ] = -ang[ PITCH ];
ang.AngleVectors( &dir, NULL, NULL );
seek.SetTargetPosition( target->centroid );
seek.SetTargetVelocity( target->velocity );
seek.SetPosition( self.centroid );
seek.SetDir( dir );
seek.SetMaxSpeed( 1400 + skill->value * 600 );
seek.Evaluate( self );
if ( ( fabs( seek.steeringforce.y ) > 5 ) && ( self.enemyRange > RANGE_MELEE ) )
{
seek.steeringforce.y *= 2;
}
self.Accelerate( seek.steeringforce );
if ( seek.steeringforce.y < 0.25f )
{
// dead on
return false;
}
return true;
}
void Aim::End
(
Actor &self
)
{
seek.End( self );
}
/****************************************************************************
FireOnSight Class Definition
****************************************************************************/
CLASS_DECLARATION( Behavior, FireOnSight, NULL );
ResponseDef FireOnSight::Responses[] =
{
{ &EV_Behavior_Args, ( Response )FireOnSight::SetArgs },
{ NULL, NULL }
};
void FireOnSight::SetArgs
(
Event *ev
)
{
if ( ev->NumArgs() > 1 )
{
anim = ev->GetString( 1 );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -