/* =========================================================================== Return to Castle Wolfenstein single player GPL Source Code Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company. This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”). RTCW SP Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. RTCW SP Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with RTCW SP Source Code. If not, see . In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ //=========================================================================== // // Name: ai_cast.h // Function: Wolfenstein AI Character Routines // Programmer: Ridah // Tab Size: 4 (real tabs) //=========================================================================== #include "../botai/ai_main.h" // just so we can use the structures #include "../botai/ai_dmq3.h" // just so we can use the structures #include "ai_cast_fight.h" // // constants/defines // #define MAX_AIFUNCS 15 // if we go over this per frame, likely to have an infinite loop // #define SIGHT_PER_SEC 50 // do this many sight iterations per second // // Cast AI specific action flags (get translated into ucmd's #define CASTACTION_WALK 1 // #define MAX_SCRIPT_ACCUM_BUFFERS 8 // #define AICAST_PRT_ALWAYS 0 #define AICAST_PRT_DEBUG 1 // #define DEBUG_FOLLOW_DIST 96 // #define MAX_LEADER_DIST 256 // #define AASWORLD_STANDARD 0 #define AASWORLD_LARGE 1 // // use this for returning the length of an anim #define ANIMLENGTH( frames,fps ) ( ( frames * 1000 ) / fps ) // #define AICAST_TFL_DEFAULT TFL_DEFAULT & ~( TFL_JUMPPAD | TFL_ROCKETJUMP | TFL_BFGJUMP | TFL_GRAPPLEHOOK | TFL_DOUBLEJUMP | TFL_RAMPJUMP | TFL_STRAFEJUMP | TFL_LAVA ) //----(SA) modified since slime is no longer deadly //#define AICAST_TFL_DEFAULT TFL_DEFAULT & ~(TFL_JUMPPAD|TFL_ROCKETJUMP|TFL_BFGJUMP|TFL_GRAPPLEHOOK|TFL_DOUBLEJUMP|TFL_RAMPJUMP|TFL_STRAFEJUMP|TFL_SLIME|TFL_LAVA) // // AI flags #define AIFL_CATCH_GRENADE 0x1 #define AIFL_NO_FLAME_DAMAGE 0x2 #define AIFL_FIRED 0x4 #define AIFL_LAND_ANIM_PLAYED 0x8 #define AIFL_ROLL_ANIM 0x10 #define AIFL_FLIP_ANIM 0x20 #define AIFL_STAND_IDLE2 0x40 #define AIFL_NOAVOID 0x80 // if set, this AI will ignore requests for us to move out the way #define AIFL_NOPAIN 0x100 // don't stop for pain anims #define AIFL_WALKFORWARD 0x200 // only walk forward #define AIFL_DENYACTION 0x400 // used by scripting to prevent dynamic code from executing certain behaviour #define AIFL_VIEWLOCKED 0x800 // prevent anything outside movement routines from changing view #define AIFL_CORPSESIGHTING 0x1000 // share information through friendly corpses #define AIFL_WAITINGTOSPAWN 0x2000 // waiting until space is clear to spawn in to the game #define AIFL_JUST_SPAWNED 0x4000 #define AIFL_NO_RELOAD 0x8000 // this character doesn't need to reload #define AIFL_TALKING 0x10000 #define AIFL_NO_HEADLOOK 0x20000 #define AIFL_ATTACK_CROUCH 0x40000 #define AIFL_MISCFLAG1 0x80000 // used various bits of code, temporarily #define AIFL_MISCFLAG2 0x100000 // used various bits of code, temporarily #define AIFL_ZOOMING 0x200000 #define AIFL_NO_HEADSHOT_DMG 0x400000 #define AIFL_DIVE_ANIM 0x800000 // able to dive to cover #define AIFL_NO_TESLA_DAMAGE 0x1000000 #define AIFL_EXPLICIT_ROUTING 0x2000000 // direct routing towards ai_markers, rather than using AAS #define AIFL_DISMOUNTING 0x4000000 #define AIFL_SPECIAL_FUNC 0x8000000 // prevent external interuption of current think func // // predict events typedef enum { PREDICTSTOP_NONE, PREDICTSTOP_HITENT, PREDICTSTOP_HITCLIENT } predictStop_t; // typedef enum { AITEAM_NAZI, AITEAM_ALLIES, AITEAM_MONSTER, AITEAM_SPARE1, AITEAM_SPARE2, AITEAM_SPARE3, AITEAM_SPARE4, AITEAM_NEUTRAL } AITeam_t; // typedef enum { BBOX_SMALL, BBOX_LARGE } BBoxType_t; // // attributes // !!! NOTE: any changes to this must be reflected in the attributeStrings in ai_cast.c typedef enum { RUNNING_SPEED, // max = 300 (running speed) WALKING_SPEED, // max = 300 (walking speed) CROUCHING_SPEED, // max = 300 (crouching speed) FOV, // max = 360 (field of view) YAW_SPEED, // max = 300 (yaw speed, so we can make zombie's turn slowly) LEADER, // max = 1.0 (ability to lead an AI squadron) AIM_SKILL, // max = 1.0 (skill while aiming) AIM_ACCURACY, // max = 1.0 (accuracy of firing) ATTACK_SKILL, // max = 1.0 (ability to attack and do other things, like retreat) REACTION_TIME, // max = 1.0 (upon seeing enemy, wait this long before reaction) ATTACK_CROUCH, // max = 1.0 (likely to crouch while firing) IDLE_CROUCH, // max = 1.0 (likely to crouch while idling) AGGRESSION, // max = 1.0 (willingness to fight till the death) TACTICAL, // max = 1.0 (ability to use strategy to their advantage, also behaviour whilst hunting enemy, more likely to creep around) CAMPER, // max = 1.0 (set this to make them stay in the spot they are spawned) ALERTNESS, // max = 1.0 (ability to notice enemies at long range) STARTING_HEALTH, // MAX = 999 (starting health) HEARING_SCALE, // max = 999 (multiply default hearing ranges by this) HEARING_SCALE_NOT_PVS, // max = 999 (multiply hearing range by this if outside PVS) INNER_DETECTION_RADIUS, // default = 512 (enemies within this range trigger immediate combat mode PAIN_THRESHOLD_SCALE, // default = 1.0 AICAST_MAX_ATTRIBUTES } castAttributes_t; // typedef enum { SIGHTSOUNDSCRIPT, ATTACKSOUNDSCRIPT, ORDERSSOUNDSCRIPT, DEATHSOUNDSCRIPT, QUIETDEATHSOUNDSCRIPT, //----(SA) ADDED FOR SILENT DEATHS (SNIPER/KNIFE) FLAMEDEATHSOUNDSCRIPT, //----(SA) ADDED FOR FLAMING PAINSOUNDSCRIPT, STAYSOUNDSCRIPT, FOLLOWSOUNDSCRIPT, ORDERSDENYSOUNDSCRIPT, MISC1SOUNDSCRIPT, MAX_AI_EVENT_SOUNDS } AIEventSounds_t; // typedef struct { char *name; float attributes[AICAST_MAX_ATTRIBUTES]; char *soundScripts[MAX_AI_EVENT_SOUNDS]; int aiTeam; char *skin; int weapons[8]; int bboxType; vec2_t crouchstandZ; int aiFlags; char *( *aifuncAttack1 )( struct cast_state_s *cs ); //use this battle aifunc for monster_attack1 char *( *aifuncAttack2 )( struct cast_state_s *cs ); //use this battle aifunc for monster_attack2 char *( *aifuncAttack3 )( struct cast_state_s *cs ); //use this battle aifunc for monster_attack2 char *loopingSound; // play this sound constantly while alive aistateEnum_t aiState; } AICharacterDefaults_t; // // script flags #define SFL_NOCHANGEWEAPON 0x1 #define SFL_NOAIDAMAGE 0x2 #define SFL_FRIENDLYSIGHTCORPSE_TRIGGERED 0x4 #define SFL_WAITING_RESTORE 0x8 #define SFL_FIRST_CALL 0x10 // // attributes strings (used for per-entity attribute definitions) // NOTE: these must match the attributes above) extern char *castAttributeStrings[]; extern AICharacterDefaults_t aiDefaults[NUM_CHARACTERS]; // // structure defines // #define AIVIS_ENEMY 1 #define AIVIS_INSPECTED 2 // we have inspected them once already #define AIVIS_INSPECT 4 // we should inspect them when we get a chance #define AIVIS_PROCESS_SIGHTING 8 // so we know if we have or haven't processed the sighting since they were last seen #define AIVIS_SIGHT_SCRIPT_CALLED 0x10 // set once sight script has been called.. only call once // // share range #define AIVIS_SHARE_RANGE 384 // if we are within this range of a friendly, share their vis info // #define MAX_CHASE_MARKERS 3 #define CHASE_MARKER_INTERVAL 1000 // #define COMBAT_TIMEOUT 8000 // sight info typedef struct { int flags; int lastcheck_timestamp; int real_visible_timestamp; int real_update_timestamp; int real_notvisible_timestamp; int visible_timestamp; // time we last recorded a sighting vec3_t visible_pos; // position we last knew of them being at (could be hearing, etc) vec3_t real_visible_pos; // position we last physically saw them vec3_t visible_vel; // velocity during last sighting int notvisible_timestamp; // last time we didn't see the entity (used for reaction delay) vec3_t chase_marker[MAX_CHASE_MARKERS]; int chase_marker_count; int lastcheck_health; } cast_visibility_t; // // starting weapons, ammo, etc typedef struct { int startingWeapons[MAX_WEAPONS / ( sizeof( int ) * 8 )]; int startingAmmo[MAX_WEAPONS]; // starting ammo values for each weapon (set to 999 for unlimited) } cast_weapon_info_t; // // scripting typedef struct { char *actionString; qboolean ( *actionFunc )( struct cast_state_s *cs, char *params ); } cast_script_stack_action_t; // typedef struct { // // set during script parsing cast_script_stack_action_t *action; // points to an action to perform char *params; } cast_script_stack_item_t; // #define AICAST_MAX_SCRIPT_STACK_ITEMS 64 // typedef struct { cast_script_stack_item_t items[AICAST_MAX_SCRIPT_STACK_ITEMS]; int numItems; } cast_script_stack_t; // typedef struct { int eventNum; // index in scriptEvents[] char *params; // trigger targetname, etc cast_script_stack_t stack; } cast_script_event_t; // typedef struct { char *eventStr; qboolean ( *eventMatch )( cast_script_event_t *event, char *eventParm ); } cast_script_event_define_t; // typedef struct { int castScriptStackHead, castScriptStackChangeTime; int castScriptEventIndex; // current event containing stack of actions to perform // scripting system AI variables (set by scripting system, used directly by AI) int scriptId; // incremented each time the script changes int scriptFlags; int scriptNoAttackTime; int scriptNoMoveTime; int playAnimViewlockTime; int scriptGotoEnt; // just goto them, then resume normal behaviour (don't follow) int scriptGotoId; vec3_t scriptWaitPos; int scriptWaitMovetime; vec3_t scriptWaitHidePos; int scriptWaitHideTime; int scriptNoSightTime; int scriptAttackEnt; // we should always attack this AI if they are alive vec3_t playanim_viewangles; } cast_script_status_t; // typedef struct { aistateEnum_t currentState; aistateEnum_t nextState; int nextStateTimer; // time left until "newState" is reached } aistate_t; // typedef enum { MS_DEFAULT, MS_WALK, MS_RUN, MS_CROUCH } movestate_t; // typedef enum { MSTYPE_NONE, MSTYPE_TEMPORARY, MSTYPE_PERMANENT } movestateType_t; // // typedef struct aicast_checkattack_cache_s { int enemy; qboolean allowHitWorld; int time; int weapon; qboolean result; } aicast_checkattack_cache_t; // // -------------------------------------------------------------------------------- // the main cast structure typedef struct cast_state_s { bot_state_t *bs; int entityNum; int aasWorldIndex; // set this according to our bounding box type // Cast specific information follows. Add to this as needed, this way the bot_state_t structure // remains untouched. int aiCharacter; int aiFlags; int lastThink; // time they last thinked, so we can vary the think times int actionFlags; // cast AI specific movement flags int lastPain, lastPainDamage; int travelflags; int thinkFuncChangeTime; aistateEnum_t aiState; movestate_t movestate; // walk, run, crouch etc (can be specified in a script) movestateType_t movestateType; // temporary, permanent, etc float attributes[AICAST_MAX_ATTRIBUTES]; // these define the abilities of each cast AI // scripting system int numCastScriptEvents; cast_script_event_t *castScriptEvents; // contains a list of actions to perform for each event type cast_script_status_t castScriptStatus; // current status of scripting cast_script_status_t castScriptStatusCurrent; // scripting status to use for backups cast_script_status_t castScriptStatusBackup; // perm backup of status of scripting, only used by backup and restore commands int scriptCallIndex; // inc'd each time a script is called int scriptAnimTime, scriptAnimNum; // last time an anim was played using scripting // the accumulation buffer int scriptAccumBuffer[MAX_SCRIPT_ACCUM_BUFFERS]; // cast_weapon_info_t *weaponInfo; // FIXME: make this a list, so they can have multiple weapons? cast_visibility_t vislist[MAX_CLIENTS]; // array of all other client entities, allocated at level start-up int weaponFireTimes[MAX_WEAPONS]; char *( *aifunc )( struct cast_state_s *cs ); //current AI function char *( *oldAifunc )( struct cast_state_s *cs ); // just so we can restore the last aiFunc if required char *( *aifuncAttack1 )( struct cast_state_s *cs ); //use this battle aifunc for monster_attack1 char *( *aifuncAttack2 )( struct cast_state_s *cs ); //use this battle aifunc for monster_attack2 char *( *aifuncAttack3 )( struct cast_state_s *cs ); //use this battle aifunc for monster_attack2 void ( *painfunc )( gentity_t *ent, gentity_t *attacker, int damage, vec3_t point ); void ( *deathfunc )( gentity_t *ent, gentity_t *attacker, int damage, int mod ); //----(SA) added mod void ( *sightfunc )( gentity_t *ent, gentity_t *other, int lastSight ); //int (*getDeathAnim)(gentity_t *ent, gentity_t *attacker, int damage); void ( *sightEnemy )( gentity_t *ent, gentity_t *other ); void ( *sightFriend )( gentity_t *ent, gentity_t *other ); void ( *activate )( int entNum, int activatorNum ); // // !!! NOTE: make sure any entityNum type variables get initialized // to -1 in AICast_CreateCharacter(), or they'll be defaulting to // the player (index 0) // // goal/AI stuff int followEntity; float followDist; qboolean followIsGoto; // we are really just going to the entity, but should wait until scripting tells us we can stop int followTime; // if this runs out, the scripting has probably been interupted qboolean followSlowApproach; int leaderNum; // entnum of player we are following float speedScale; // so we can vary movement speed float combatGoalTime; vec3_t combatGoalOrigin; int lastGetHidePos; int startAttackCount; // incremented each time we start a standing attack // used to make sure we only find a combat spot once per attack int combatSpotAttackCount; int combatSpotDelayTime; int startBattleChaseTime; int blockedTime; // time they were last blocked by a solid entity int obstructingTime; // time that we should move so we are not obstructing someone else vec3_t obstructingPos; int blockedAvoidTime; float blockedAvoidYaw; int deathTime; int rebirthTime, revivingTime; // battle values int enemyHeight; int enemyDist; vec3_t takeCoverPos, takeCoverEnemyPos; int takeCoverTime; int attackSpotTime; int triggerReleaseTime; int lastWeaponFired; // set each time a weapon is fired. used to detect when a weapon has been fired from within scripting vec3_t lastWeaponFiredPos; int lastWeaponFiredWeaponNum; // idle behaviour stuff int lastEnemy, nextIdleAngleChange; float idleYawChange, idleYaw; qboolean crouchHideFlag; int doorMarker, doorEntNum; // Rafael int attackSNDtime; int attacksnd; int painSoundTime; int firstSightTime; qboolean secondDeadTime; // done int startGrenadeFlushTime; int lockViewAnglesTime; int grenadeFlushEndTime; int grenadeFlushFiring; int dangerEntity; int dangerEntityValidTime; // dangerEntity is valid until this time expires vec3_t dangerEntityPos; // dangerEntity is predicted to end up here int dangerEntityTimestamp; // time this danger was recorded float dangerDist; int mountedEntity; // mg42, etc that we have mounted int inspectBodyTime; vec3_t startOrigin; int damageQuota; int damageQuotaTime; int dangerLastGetAvoid; int lastAvoid; int doorMarkerTime, doorMarkerNum, doorMarkerDoor; int pauseTime; // absolutely don't move move while this is > level.time aicast_checkattack_cache_t checkAttackCache; int secretsFound; int attempts; qboolean grenadeGrabFlag; // if this is set, we need to play the anim before we can grab it vec3_t lastMoveToPosGoalOrg; // if this changes, we should reset the Bot Avoid Reach int noAttackTime; // used by dynamic AI to stop attacking for set time int lastRollMove; int lastFlipMove; vec3_t stimFlyAttackPos; int lastDodgeRoll; // last time we rolled to get out of our enemies direct aim int battleRollTime; vec3_t viewlock_viewangles; int grenadeKickWeapon; int animHitCount; // for stepping through the frames on which to inflict damage int totalPlayTime, lastLoadTime; int queryStartTime, queryCountValidTime, queryCount, queryAlertSightTime; int lastScriptSound; int inspectNum; int scriptPauseTime; int bulletImpactEntity; int bulletImpactTime; // last time we heard/saw a bullet impact int bulletImpactIgnoreTime; vec3_t bulletImpactStart, bulletImpactEnd; int audibleEventTime; vec3_t audibleEventOrg; int audibleEventEnt; int battleChaseMarker, battleChaseMarkerDir; int lastBattleHunted; // last time an enemy decided to hunt us int battleHuntPauseTime, battleHuntViewTime; int lastAttackCrouch; int lastMoveThink; // last time we ran our ClientThink() int numEnemies; // last count of enemies that are currently pursuing us int noReloadTime; // dont reload prematurely until this time has expired int lastValidAreaNum[2]; // last valid area within each AAS world int lastValidAreaTime[2]; // time we last got the area int weaponNum; // our current weapon int enemyNum; // our current enemy vec3_t ideal_viewangles, viewangles; usercmd_t lastucmd; int attackcrouch_time; int bFlags; int deadSinkStartTime; int lastActivate; vec3_t loperLeapVel; // ------------------------------------------------------------------------------------------- // if working on a post release patch, new variables should ONLY be inserted after this point // ------------------------------------------------------------------------------------------- } cast_state_t; // #define CSFOFS( x ) ( (int)&( ( (cast_state_t *)0 )->x ) ) // typedef struct aicast_predictmove_s { vec3_t endpos; //position at the end of movement prediction vec3_t velocity; //velocity at the end of movement prediction int presencetype; //presence type at end of movement prediction int stopevent; //event that made the prediction stop float time; //time predicted ahead int frames; //number of frames predicted ahead int numtouch; int touchents[MAXTOUCH]; int groundEntityNum; } aicast_predictmove_t; // // variables/globals // //cast states extern cast_state_t *caststates; //number of characters extern int numcast; // // minimum time between thinks (maximum is double this) extern int aicast_thinktime; // maximum number of character thinks at once extern int aicast_maxthink; // maximum clients extern int aicast_maxclients; // skill scale extern float aicast_skillscale; // // cvar to enable aicast debugging, set higher for more levels of debugging extern vmCvar_t aicast_debug; extern vmCvar_t aicast_debugname; extern vmCvar_t aicast_scripts; // // // procedure defines // // ai_cast.c void AIChar_SetBBox( gentity_t *ent, cast_state_t *cs, qboolean useHeadTag ); void AICast_Printf( int type, const char *fmt, ... ); gentity_t *AICast_CreateCharacter( gentity_t *ent, float *attributes, cast_weapon_info_t *weaponInfo, char *castname, char *model, char *head, char *sex, char *color, char *handicap ); void AICast_Init( void ); void AICast_DelayedSpawnCast( gentity_t *ent, int castType ); qboolean AICast_SolidsInBBox( vec3_t pos, vec3_t mins, vec3_t maxs, int entnum, int mask ); void AICast_CheckLevelAttributes( cast_state_t *cs, gentity_t *ent, char **ppStr ); // // ai_cast_sight.c void AICast_SightUpdate( int numchecks ); qboolean AICast_VisibleFromPos( vec3_t srcpos, int srcnum, vec3_t destpos, int destnum, qboolean updateVisPos ); void AICast_UpdateVisibility( gentity_t *srcent, gentity_t *destent, qboolean shareVis, qboolean directview ); qboolean AICast_CheckVisibility( gentity_t *srcent, gentity_t *destent ); // // ai_cast_debug.c void AICast_DBG_InitAIFuncs( void ); void AICast_DBG_AddAIFunc( cast_state_t *cs, char *funcname ); void AICast_DBG_ListAIFuncs( cast_state_t *cs, int numprint ); void AICast_DBG_RouteTable_f( vec3_t org, char *param ); int Sys_MilliSeconds( void ); void AICast_DebugFrame( cast_state_t *cs ); // // ai_cast_funcs.c void AICast_SpecialFunc( cast_state_t *cs ); bot_moveresult_t *AICast_MoveToPos( cast_state_t *cs, vec3_t pos, int entnum ); float AICast_SpeedScaleForDistance( cast_state_t *cs, float startdist, float idealDist ); char *AIFunc_DefaultStart( cast_state_t *cs ); char *AIFunc_IdleStart( cast_state_t *cs ); char *AIFunc_ChaseGoalIdleStart( cast_state_t *cs, int entitynum, float reachdist ); char *AIFunc_ChaseGoalStart( cast_state_t *cs, int entitynum, float reachdist, qboolean slowApproach ); char *AIFunc_BattleChaseStart( cast_state_t *cs ); char *AIFunc_BattleStart( cast_state_t *cs ); char *AIFunc_DoorMarkerStart( cast_state_t *cs, int doornum, int markernum ); char *AIFunc_DoorMarker( cast_state_t *cs ); char *AIFunc_BattleTakeCoverStart( cast_state_t *cs ); char *AIFunc_GrenadeFlushStart( cast_state_t *cs ); char *AIFunc_AvoidDangerStart( cast_state_t *cs ); char *AIFunc_BattleMG42Start( cast_state_t *cs ); char *AIFunc_InspectBodyStart( cast_state_t *cs ); char *AIFunc_GrenadeKickStart( cast_state_t *cs ); char *AIFunc_InspectFriendlyStart( cast_state_t *cs, int entnum ); char *AIFunc_InspectBulletImpactStart( cast_state_t *cs ); char *AIFunc_InspectAudibleEventStart( cast_state_t *cs, int entnum ); char *AIFunc_BattleAmbushStart( cast_state_t *cs ); char *AIFunc_BattleHuntStart( cast_state_t *cs ); // // ai_cast_func_attack.c char *AIFunc_ZombieFlameAttackStart( cast_state_t *cs ); char *AIFunc_ZombieAttack2Start( cast_state_t *cs ); char *AIFunc_ZombieMeleeStart( cast_state_t *cs ); char *AIFunc_LoperAttack1Start( cast_state_t *cs ); char *AIFunc_LoperAttack2Start( cast_state_t *cs ); char *AIFunc_LoperAttack3Start( cast_state_t *cs ); char *AIFunc_StimSoldierAttack1Start( cast_state_t *cs ); char *AIFunc_StimSoldierAttack2Start( cast_state_t *cs ); char *AIFunc_BlackGuardAttack1Start( cast_state_t *cs ); char *AIFunc_RejectAttack1Start( cast_state_t *cs ); //----(SA) char *AIFunc_WarriorZombieMeleeStart( cast_state_t *cs ); char *AIFunc_WarriorZombieSightStart( cast_state_t *cs ); char *AIFunc_WarriorZombieDefenseStart( cast_state_t *cs ); // // ai_cast_func_boss1.c char *AIFunc_Helga_SpiritAttack_Start( cast_state_t *cs ); char *AIFunc_Helga_MeleeStart( cast_state_t *cs ); char *AIFunc_FlameZombie_PortalStart( cast_state_t *cs ); char *AIFunc_Heinrich_MeleeStart( cast_state_t *cs ); char *AIFunc_Heinrich_RaiseDeadStart( cast_state_t *cs ); char *AIFunc_Heinrich_SpawnSpiritsStart( cast_state_t *cs ); void AICast_Heinrich_SoundPrecache( void ); // // ai_cast_fight.c qboolean AICast_StateChange( cast_state_t *cs, aistateEnum_t newaistate ); void AICast_WeaponSway( cast_state_t *cs, vec3_t ofs ); int AICast_ScanForEnemies( cast_state_t *cs, int *enemies ); void AICast_UpdateBattleInventory( cast_state_t *cs, int enemy ); float AICast_Aggression( cast_state_t *cs ); int AICast_WantsToChase( cast_state_t *cs ); int AICast_WantsToTakeCover( cast_state_t *cs, qboolean attacking ); qboolean AICast_EntityVisible( cast_state_t *cs, int enemynum, qboolean directview ); bot_moveresult_t AICast_CombatMove( cast_state_t *cs, int tfl ); qboolean AICast_AimAtEnemy( cast_state_t *cs ); qboolean AICast_CheckAttackAtPos( int entnum, int enemy, vec3_t pos, qboolean ducking, qboolean allowHitWorld ); qboolean AICast_CheckAttack( cast_state_t *cs, int enemy, qboolean allowHitWorld ); void AICast_ProcessAttack( cast_state_t *cs ); void AICast_ChooseWeapon( cast_state_t *cs, qboolean battleFunc ); qboolean AICast_GetTakeCoverPos( cast_state_t *cs, int enemyNum, vec3_t enemyPos, vec3_t returnPos ); qboolean AICast_CanMoveWhileFiringWeapon( int weaponnum ); float AICast_GetWeaponSoundRange( int weapon ); qboolean AICast_StopAndAttack( cast_state_t *cs ); qboolean AICast_WantToRetreat( cast_state_t *cs ); int AICast_SafeMissileFire( gentity_t *ent, int duration, int enemyNum, vec3_t enemyPos, int selfNum, vec3_t endPos ); void AIChar_AttackSound( cast_state_t *cs ); qboolean AICast_GotEnoughAmmoForWeapon( cast_state_t *cs, int weapon ); qboolean AICast_HostileEnemy( cast_state_t *cs, int enemynum ); qboolean AICast_QueryEnemy( cast_state_t *cs, int enemynum ); void AICast_AudibleEvent( int srcnum, vec3_t pos, float range ); qboolean AICast_WeaponUsable( cast_state_t *cs, int weaponNum ); float AICast_WeaponRange( cast_state_t *cs, int weaponnum ); // // ai_cast_events.c void AICast_Pain( gentity_t *targ, gentity_t *attacker, int damage, vec3_t point ); void AICast_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ); void AICast_Sight( gentity_t *ent, gentity_t *other, int lastSight ); void AICast_EndChase( cast_state_t *cs ); void AICast_ProcessActivate( int entNum, int activatorNum ); // // ai_cast_think.c void AICast_Think( int client, float thinktime ); void AICast_UpdateInput( cast_state_t *cs, int time ); void AICast_InputToUserCommand( cast_state_t * cs, bot_input_t * bi, usercmd_t * ucmd, int delta_angles[3] ); void AICast_PredictMovement( cast_state_t *cs, int numframes, float frametime, aicast_predictmove_t *move, usercmd_t *ucmd, int checkHitEnt ); void AICast_Blocked( cast_state_t *cs, bot_moveresult_t *moveresult, int activate, bot_goal_t *goal ); qboolean AICast_RequestCrouchAttack( cast_state_t *cs, vec3_t org, float time ); qboolean AICast_GetAvoid( cast_state_t *cs, bot_goal_t *goal, vec3_t outpos, qboolean reverse, int blockEnt ); void AICast_QueryThink( cast_state_t *cs ); void AICast_DeadClipWalls( cast_state_t *cs ); void AICast_IdleReload( cast_state_t *cs ); // // ai_cast_script.c qboolean AICast_ScriptRun( cast_state_t *cs, qboolean force ); // // ai_cast_soldier.c void AIChar_spawn( gentity_t *ent ); // // other/external defines void BotCheckAir( bot_state_t *bs ); void BotUpdateInput( bot_state_t *bs, int time ); float AngleDifference( float ang1, float ang2 ); float BotChangeViewAngle( float angle, float ideal_angle, float speed ); void BotInputToUserCommand( bot_input_t * bi, usercmd_t * ucmd, int delta_angles[3] ); void GibEntity( gentity_t *self, int killer ); void GibHead( gentity_t *self, int killer ); // extern bot_state_t *botstates[MAX_CLIENTS];