📄 actor.cpp
字号:
// Added EnemyCanSeeMeFrom
//
// 74 7/26/98 6:44a Jimdose
// Overrode the setsize event so that def files don't change the hardcoded size
// (need to fix these damn paths one day).
//
// 73 7/26/98 3:48a Jimdose
// Modified aim based on skill
//
// 72 7/25/98 4:39p Jimdose
// Guys shoot at vehicles and shoot out windows
//
// 71 7/25/98 2:07a Jimdose
// Fixed bug with trig being delete without being NULLed out when gibbing
// Guys now attack any enemy
//
// 70 7/24/98 9:59p Aldie
// Gib stuff
//
// 69 7/24/98 6:16p Aldie
// Check for inventory items before removing dead guys
//
// 68 7/24/98 4:14p Aldie
// Cancel useless checks
//
// 67 7/24/98 3:46p Aldie
// Increased gibs
//
// 66 7/23/98 10:16p Jimdose
// Removed ignoreenemies stuff
// Fixed a bunch of anim screwups when actor is killed
// fixed "big gib" bug
//
// 65 7/23/98 6:55p Aldie
// Fun with gibs.
//
// 64 7/23/98 6:19p Jimdose
// ignoreEnemies was being set when character was targeted
//
// 63 7/22/98 7:02p Aldie
// Added ability to remove useless bodies.
//
// 62 7/22/98 2:32p Jimdose
// fixed bug where guys wouldn't sight the enemy if the went into pain
//
// 61 7/21/98 9:34p Jimdose
// Chatter now checks if the alias exists before playing the sound, thereby not
// generating warnings of missing sounds.
//
// 60 7/19/98 9:20p Jimdose
// Improved support for overriding the default script
//
// 59 7/16/98 6:21p Jimdose
// Fixed crash when actorthread was null
//
// 58 7/14/98 11:50p Jimdose
// Made PopState return whether a new state was popped off the stack
// StateDoneEvent now kills the calling thread if no previous state exists on
// the stack
// DoAction creates a new thread if no actor thread exists
//
// 57 7/14/98 6:57p Aldie
// Moved setsize before setmodel
//
// 56 7/13/98 4:59p Aldie
// Added dead player bodies with gibbing
//
// 55 7/09/98 10:40p Aldie
// Moved bodyparts to game
//
// 54 7/08/98 8:59p Jimdose
// Moved opening door to script
//
// 53 7/08/98 1:00p Jimdose
// added crouchsize and standsize
//
// 52 7/07/98 11:37p Jimdose
// Replaced priority-based system with full script-based state system
//
// 51 7/06/98 1:06p Jimdose
// working on ai
//
// 50 6/30/98 6:47p Aldie
// Added Gib Event
//
// 49 6/30/98 6:00p Jimdose
// Added more states and state detection code.
// Added range detection
// added health level detection
//
// 48 6/25/98 8:46p Markd
// Removed rotating doors
//
// 47 6/25/98 8:29p Aldie
// Updated killed and death
//
// 46 6/25/98 8:10p Jimdose
// Disabled some prints
//
// 45 6/25/98 8:10p Jimdose
// Using global actor script
//
// 44 6/24/98 4:26p Jimdose
// Fixed bugs in TurnTo
//
// 43 6/23/98 5:59p Aldie
// Fixed dropWeapon stuff.
//
// 42 6/20/98 7:47p Markd
// Added location based pain and death support
//
// 41 6/19/98 9:27p Jimdose
// Added GetGunOrientation
//
// 40 6/19/98 4:44p Jimdose
// Added util functions InFOV, etc.
//
// 39 6/18/98 8:45p Jimdose
// Removed string based SetBehavior and PushState functions
// Added source info to events
//
// 38 6/18/98 2:00p Markd
// rewrote tesselation code
//
// 37 6/17/98 10:00p Jimdose
// Improved door opening code
// Moved phyics move into class
//
// 36 6/17/98 3:15p Markd
// fixed arg issue
//
// 35 6/17/98 3:03p Markd
// Changed NumArgs back to previous behavior
//
// 34 6/17/98 1:19a Jimdose
// Moved setOwner to Item.
// Added EV_Item_Pickup
//
// 33 6/15/98 10:46p Jimdose
// Made neutral allias become enemies with pain
// shurnk bounding box temporarily
//
// 32 6/13/98 8:25p Jimdose
// Added leaning into turns (alright already Tom!)
// Added enemy visibility tests for FindCover
//
// 31 6/11/98 12:44a Jimdose
// behaviors now get info from the script at startup
//
// 30 6/10/98 10:24p Jimdose
// added priority based state system
//
// 29 6/09/98 4:18p Jimdose
// worked on ai
//
// 28 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.
//
// 27 6/03/98 5:43p Jimdose
// Fixed spelling of behavior. :)
//
// 26 6/03/98 4:36p Markd
// Removed gun stuff from entity, it is now sent over as a separate object
//
// 25 6/02/98 7:46p Markd
// Took out currentweapon assignments for client-side stuff
//
// 24 5/28/98 6:01p Markd
// When actors die, they kill their dynamic light
//
// 23 5/28/98 2:11p Markd
// Made enemies drop weapons and only fire if their weapons are ready
//
// 22 5/28/98 1:50p Markd
// made actors drop weapons
//
// 21 5/27/98 4:56p Markd
// Only gib when inflictor is rocket
//
// 20 5/27/98 12:04p Jimdose
// fixed null pointer prob
//
// 19 5/27/98 11:59a Jimdose
// Gibbing is harder
//
// 18 5/27/98 11:50a Jimdose
// Added killtarget and target to killed
//
// 17 5/27/98 7:15a Jimdose
// took out dprintf
//
// 16 5/27/98 7:12a Jimdose
// ai ai ai
//
// 15 5/27/98 6:39a Jimdose
// working on ai
//
// 14 5/27/98 5:27a Aldie
// Added gibs
//
// 13 5/27/98 5:11a Jimdose
// working on ai
//
// 12 5/25/98 6:46p Jimdose
// Made animateframe, prethink and posthink into functions built into the base
// entity class
//
// 11 5/25/98 5:32p Jimdose
// Pathnodes are no longer a subclass of Entity. This was done to save on
// edicts
//
// 10 5/25/98 1:06a Jimdose
// Added chatter
//
// 9 5/24/98 8:46p Jimdose
// Made a lot of functions more str-friendly.
// Got rid of a lot of char * based strings
// Cleaned up get spawn arg functions and sound functions
// sound functions now use consistant syntax
//
// 8 5/24/98 1:02a Jimdose
// Added monster hearing
//
// 7 5/23/98 6:27p Jimdose
// Improved steering and opening doors
//
// 6 5/22/98 9:44p Jimdose
// Disabled debug lines when checking to shoot
//
// 5 5/22/98 9:38p Jimdose
// Commented out prints
//
// 4 5/22/98 9:36p Jimdose
// AI Scripting works again (somewhat)
//
// 3 5/20/98 6:36p Jimdose
// Rewrite
//
// 2 5/18/98 8:15p Jimdose
// Created file
//
// DESCRIPTION:
// Base class for character AI.
//
#include "g_local.h"
#include "actor.h"
#include "behavior.h"
#include "scriptmaster.h"
#include "doors.h"
#include "gibs.h"
#include "vehicle.h"
#include "misc.h"
#include "specialfx.h"
#include "object.h"
#include "scriptslave.h"
#include "explosion.h"
#include "misc.h"
//#define DEBUG_PRINT
CLASS_DECLARATION( Class, ActorState, NULL );
ResponseDef ActorState::Responses[] =
{
{ NULL, NULL }
};
cvar_t *ai_actorscript;
// used below for a slight movement tweak
// added as a global here to prevent constant re-allocation
const Vector movetweak = "0 0 2";
#define TURN_SPEED 30
CLASS_DECLARATION( Sentient, Actor, "monster_generic" );
Event EV_Actor_CrouchSize( "crouchsize" );
Event EV_Actor_Fov( "fov" );
Event EV_Actor_VisionDistance( "visiondistance" );
Event EV_Actor_Start( "start" );
Event EV_Actor_Dead( "dead" );
Event EV_Actor_ClearState( "clearstate" );
Event EV_Actor_SetState( "state" );
Event EV_Actor_SetBehavior( "behavior" );
Event EV_Actor_Friend( "friend" ); // Allied to player
Event EV_Actor_Civilian( "civilian" ); // Nuetral to all, runs from danger
Event EV_Actor_Enemy( "enemy" ); // Enemy to player
Event EV_Actor_Monster( "monster" ); // Enemy to player, civilians, and inanimate objects
Event EV_Actor_Animal( "animal" ); // neutral to all
Event EV_Actor_Inanimate( "inanimate" ); // Inanimate objects
Event EV_Actor_Swim( "swim" ); // specifies actor as being able to swim
Event EV_Actor_Fly( "fly" ); // specifies actor as being able to swim
Event EV_Actor_NotLand( "noland" ); // specifies actor as not being able to walk on land
Event EV_Actor_TargetEnemies( "targetenemies" );
// Scripting
Event EV_Actor_Script( "script" );
Event EV_Actor_Thread( "thread" );
Event EV_Actor_IfEnemyVisible( "ifenemyvisible" );
Event EV_Actor_IfNear( "ifnear" );
Event EV_Actor_ForwardSpeed( "forwardspeed" );
Event EV_Actor_Idle( "idle" );
Event EV_Actor_LookAt( "lookat" );
Event EV_Actor_TurnTo( "turnto" );
Event EV_Actor_FinishedBehavior( "finishedbehavior" );
Event EV_Actor_NotifyBehavior( "notifybehavior" );
Event EV_Actor_WalkTo( "walkto" );
Event EV_Actor_JumpTo( "jumpto" );
Event EV_Actor_RunTo( "runto" );
Event EV_Actor_Anim( "anim" );
Event EV_Actor_Attack( "attack" );
Event EV_Actor_AttackPlayer( "attackplayer" );
Event EV_Actor_ReserveNode( "reservenode" );
Event EV_Actor_ReleaseNode( "releasenode" );
Event EV_Actor_IfCanHideAt( "ifcanhideat" );
Event EV_Actor_IfCanStrafeAttack( "ifcanstrafeattack" );
Event EV_Actor_IfCanMeleeAttack( "ifcanmeleeattack" );
Event EV_Actor_IfCanShoot( "ifcanshoot" );
Event EV_Actor_IfEnemyWithin( "ifenemywithin" );
Event EV_Actor_IgnoreSounds( "ignoresounds" );
Event EV_Actor_RespondToSounds( "respondtosounds" );
Event EV_Actor_IgnoreAll( "ignoreall" );
Event EV_Actor_RespondToAll( "respondtoall" );
Event EV_Actor_RespondTo( "respondto" );
Event EV_Actor_Ignore( "ignore" );
Event EV_Actor_DefineState( "definestate" );
Event EV_Actor_CopyState( "copystate" );
Event EV_Actor_Remove( "remove_useless" );
Event EV_Actor_ForwardToBehavior( "forwardcommand" );
Event EV_Actor_Aim( "aim" );
Event EV_Actor_MeleeRange( "meleerange" );
Event EV_Actor_MeleeDamage( "meleedamage" );
Event EV_Actor_Melee( "melee" );
Event EV_Actor_AttackFinished( "attack_finished" );
Event EV_Actor_CanStrafe( "canstrafe" );
Event EV_Actor_NoStrafe( "nostrafe" );
Event EV_Actor_PainThreshold( "painthreshold" );
Event EV_Actor_SetKillThread( "killthread" );
Event EV_Actor_AttackRange( "attackrange" );
Event EV_Actor_ShotsPerAttack( "shotsperattack" );
Event EV_Actor_ClearEnemy( "clearenemy" );
Event EV_Actor_AttackMode( "attackmode" );
Event EV_Actor_EyePositionOffset( "eyeoffset" );
Event EV_Actor_NoDeathFade( "nodeathfade" );
Event EV_Actor_NoChatter( "nochatter" );
Event EV_Actor_TurnSpeed( "turnspeed" );
ResponseDef StateInfo::Responses[] =
{
{ NULL, NULL }
};
CLASS_DECLARATION( Class, StateInfo, NULL );
StateInfo::StateInfo()
{
ignore = true;
}
ResponseDef Actor::Responses[] =
{
{ &EV_Activate, ( Response )Actor::ActivateEvent },
{ &EV_Use, ( Response )Actor::UseEvent },
{ &EV_Actor_Start, ( Response )Actor::Start },
{ &EV_Pain, ( Response )Actor::Pain },
{ &EV_Killed, ( Response )Actor::Killed },
{ &EV_Actor_Dead, ( Response )Actor::Dead },
{ &EV_Actor_TargetEnemies, ( Response )Actor::TargetEnemies },
{ &EV_Actor_SetBehavior, ( Response )Actor::SetBehaviorEvent },
{ &EV_Actor_ForwardSpeed, ( Response )Actor::ForwardSpeedEvent },
{ &EV_Actor_CrouchSize, ( Response )Actor::CrouchSize },
{ &EV_Actor_Fov, ( Response )Actor::SetFov },
{ &EV_Actor_VisionDistance, ( Response )Actor::SetVisionDistance },
{ &EV_Actor_Friend, ( Response )Actor::FriendEvent },
{ &EV_Actor_Civilian, ( Response )Actor::CivilianEvent },
{ &EV_Actor_Enemy, ( Response )Actor::EnemyEvent },
{ &EV_Actor_Monster, ( Response )Actor::MonsterEvent },
{ &EV_Actor_Animal, ( Response )Actor::AnimalEvent },
{ &EV_Actor_Inanimate, ( Response )Actor::InanimateEvent },
{ &EV_Actor_Swim, ( Response )Actor::SwimEvent },
{ &EV_Actor_Fly, ( Response )Actor::FlyEvent },
{ &EV_Actor_NotLand, ( Response )Actor::NotLandEvent },
{ &EV_Gib, ( Response )Actor::GibEvent },
// Scripting
{ &EV_Actor_DefineState, ( Response )Actor::DefineStateEvent },
{ &EV_Actor_CopyState, ( Response )Actor::CopyStateEvent },
{ &EV_Actor_IgnoreAll, ( Response )Actor::IgnoreAllEvent },
{ &EV_Actor_RespondToAll, ( Response )Actor::RespondToAllEvent },
{ &EV_Actor_RespondTo, ( Response )Actor::RespondToEvent },
{ &EV_Actor_Ignore, ( Response )Actor::IgnoreEvent },
{ &EV_Actor_IgnoreSounds, ( Response )Actor::IgnoreSoundsEvent },
{ &EV_Actor_RespondToSounds, ( Response )Actor::RespondToSoundsEvent },
{ &EV_Actor_ClearState, ( Response )Actor::ClearStateEvent },
{ &EV_ScriptThread_End, ( Response )Actor::StateDoneEvent },
{ &EV_Actor_SetState, ( Response )Actor::SetStateEvent },
{ &EV_Actor_Script, ( Response )Actor::SetScript },
{ &EV_Actor_Thread, ( Response )Actor::SetThread },
{ &EV_Actor_IfEnemyVisible, ( Response )Actor::IfEnemyVisibleEvent },
{ &EV_Actor_IfNear, ( Response )Actor::IfNearEvent },
{ &EV_Actor_Idle, ( Response )Actor::IdleEvent },
{ &EV_ProcessCommands, ( Response )Actor::StartMove },
{ &EV_Actor_LookAt, ( Response )Actor::LookAt },
{ &EV_Actor_TurnTo, ( Response )Actor::TurnToEvent },
{ &EV_Actor_FinishedBehavior, ( Response )Actor::FinishedBehavior },
{ &EV_Actor_NotifyBehavior, ( Response )Actor::NotifyBehavior },
{ &EV_Actor_WalkTo, ( Response )Actor::WalkTo },
{ &EV_Actor_JumpTo, ( Response )Actor::JumpToEvent },
{ &EV_Actor_RunTo, ( Response )Actor::RunTo },
{ &EV_Actor_Anim, ( Response )Actor::Anim },
{ &EV_Actor_Attack, ( Response )Actor::AttackEntity },
{ &EV_Actor_AttackPlayer, ( Response )Actor::AttackPlayer },
{ &EV_Actor_Remove, ( Response )Actor::RemoveUselessBody },
{ &EV_Actor_ForwardToBehavior,( Response )Actor::ForwardBehaviorEvent },
{ &EV_Actor_ReserveNode, ( Response )Actor::ReserveNodeEvent },
{ &EV_Actor_ReleaseNode, ( Response )Actor::ReleaseNodeEvent },
{ &EV_Actor_IfCanHideAt, ( Response )Actor::IfCanHideAtEvent },
{ &EV_Actor_IfCanStrafeAttack,( Response )Actor::IfCanStrafeAttackEvent },
{ &EV_Actor_IfCanMeleeAttack, ( Response )Actor::IfCanMeleeAttackEvent },
{ &EV_Actor_IfCanShoot, ( Response )Actor::IfCanShootEvent },
{ &EV_Actor_IfEnemyWithin, ( Response )Actor::IfEnemyWithinEvent },
{ &EV_HeardWeapon, ( Response )Actor::InvestigateWeaponSound },
{ &EV_HeardMovement, ( Response )Actor::InvestigateMovementSound },
{ &EV_HeardPain, ( Response )Actor::InvestigatePainSound },
{ &EV_HeardDeath, ( Response )Actor::InvestigateDeathSound },
{ &EV_HeardBreaking, ( Response )Actor::InvestigateBreakingSound },
{ &EV_HeardDoor, ( Response )Actor::InvestigateDoorSound },
{ &EV_HeardMutant, ( Response )Actor::InvestigateMutantSound },
{ &EV_HeardVoice, ( Response )Actor::InvestigateVoiceSound },
{ &EV_HeardMachine, ( Response )Actor::InvestigateMachineSound },
{ &EV_HeardRadio, ( Response )Actor::InvestigateRadioSound },
{ &EV_Actor_Aim, ( Response )Actor::SetAim },
{ &EV_Actor_MeleeRange, ( Response )Actor::SetMeleeRange },
{ &EV_Actor_MeleeDamage, ( Response )Actor::SetMeleeDamage },
{ &EV_Actor_Melee, ( Response )Actor::MeleeEvent },
{ &EV_Actor_AttackFinished, ( Response )Actor::AttackFinishedEvent },
{ &EV_Actor_CanStrafe, ( Response )Actor::CanStrafeEvent },
{ &EV_Actor_NoStrafe, ( Response )Actor::NoStrafeEvent },
{ &EV_Actor_PainThreshold, ( Response )Actor::SetPainThresholdEvent },
{ &EV_Actor_SetKillThread, ( Response )Actor::SetKillThreadEvent },
{ &EV_Actor_AttackRange, ( Response )Actor::AttackRangeEvent },
{ &EV_Actor_ShotsPerAttack, ( Response )Actor::ShotsPerAttackEvent },
{ &EV_Actor_ClearEnemy, ( Response )Actor::ClearEnemyEvent },
{ &EV_Actor_AttackMode, ( Response )Actor::AttackModeEvent },
{ &EV_SetHealth, ( Response )Actor::SetHealth },
{ &EV_Actor_EyePositionOffset,( Response )Actor::EyeOffset },
{ &EV_Actor_NoDeathFade, ( Response )Actor::NoDeathFadeEvent },
{ &EV_Actor_NoChatter, ( Response )Actor::NoChatterEvent },
{ &EV_Actor_TurnSpeed, ( Response )Actor::TurnSpeedEvent },
{ &EV_ScriptThread_Goto, ( Response )Actor::GotoEvent },
{ NULL, NULL }
};
//***********************************************************************************************
//
// Initialization functions
//
//***********************************************************************************************
Actor::Actor()
{
const char *text;
str script;
const char * skinname;
Event *ev;
SpawnArgs args;
// don't spawn monsters in deathmatch
if ( deathmatch->value || nomonsters->value )
{
PostEvent( EV_Remove, 0 );
return;
}
actortype = IS_ENEMY;
setSolidType( SOLID_BBOX );
setMoveType( MOVETYPE_STEP );
health = G_GetFloatArg( "health", 100 );
max_health = health;
takedamage = DAMAGE_AIM;
mass = G_GetFloatArg( "mass", 200 );
deadflag = DEAD_NO;
edict->clipmask = MASK_MONSTERSOLID;
edict->svflags |= SVF_MONSTER;
forwardspeed = 0;
checkStrafe = true;
// No longer used
movement = AI_CANWALK;
lastmove = STEPMOVE_OK;
gunoffset = "0 0 44";
numonstack = 0;
behavior = NULL;
path = NULL;
newanimnum = -1;
newanim = "";
newanimevent = NULL;
text = G_GetSpawnArg( "weapon" );
if ( text )
{
giveWeapon( text );
}
spawngroup = G_GetStringArg( "spawngroup" );
attackmode = G_GetIntArg( "attackmode", 0 );
attack_range = G_GetFloatArg( "attackrange", 8192 );
fov = 150;
fovdot = cos( fov * 0.5 * M_PI / 180.0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -