2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
2006-03-20 17:12:09 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* Header file for AI system .
*
*/
# ifndef _AI_H
# define _AI_H
2013-12-28 18:47:17 +00:00
# include <cstddef>
2013-06-27 02:35:22 +00:00
# include "dxxsconf.h"
2013-12-08 23:37:40 +00:00
# include "fmtcheck.h"
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# include "fvi.h"
2013-12-12 23:48:34 +00:00
# include "compiler-array.h"
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2013-10-27 22:01:11 +00:00
# define PARALLAX 0 // If !0, then special debugging info for Parallax eyes only enabled.
2012-11-11 22:12:51 +00:00
# ifdef __cplusplus
2013-12-26 04:18:28 +00:00
# include "countarray.h"
2012-11-11 22:12:51 +00:00
2013-12-26 04:18:28 +00:00
struct object ;
2013-12-21 23:16:19 +00:00
struct point_seg ;
2006-03-20 17:12:09 +00:00
# define PLAYER_AWARENESS_INITIAL_TIME (3*F1_0)
# define MAX_PATH_LENGTH 30 // Maximum length of path in ai path following.
# define MAX_DEPTH_TO_SEARCH_FOR_PLAYER 10
# define BOSS_GATE_MATCEN_NUM -1
# define MAX_BOSS_TELEPORT_SEGS 100
# define ROBOT_BRAIN 7
# define ROBOT_BOSS1 17
# define ROBOT_FIRE_AGITATION 94
2013-12-21 23:16:19 +00:00
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
extern int Boss_hit_this_frame ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# define BOSS_D2 21 // Minimum D2 boss value.
# define BOSS_COOL 21
# define BOSS_WATER 22
# define BOSS_FIRE 23
# define BOSS_ICE 24
# define BOSS_ALIEN1 25
# define BOSS_ALIEN2 26
# define NUM_D2_BOSSES 8
2012-07-22 23:17:54 +00:00
extern const ubyte Boss_teleports [ NUM_D2_BOSSES ] ; // Set byte if this boss can teleport
extern const ubyte Boss_spew_more [ NUM_D2_BOSSES ] ; // Set byte if this boss can teleport
2006-03-20 17:12:09 +00:00
//extern ubyte Boss_cloaks[NUM_D2_BOSSES]; // Set byte if this boss can cloak
2012-07-22 23:17:54 +00:00
extern const ubyte Boss_spews_bots_energy [ NUM_D2_BOSSES ] ; // Set byte if boss spews bots when hit by energy weapon.
extern const ubyte Boss_spews_bots_matter [ NUM_D2_BOSSES ] ; // Set byte if boss spews bots when hit by matter weapon.
extern const ubyte Boss_invulnerable_energy [ NUM_D2_BOSSES ] ; // Set byte if boss is invulnerable to energy weapons.
extern const ubyte Boss_invulnerable_matter [ NUM_D2_BOSSES ] ; // Set byte if boss is invulnerable to matter weapons.
extern const ubyte Boss_invulnerable_spot [ NUM_D2_BOSSES ] ; // Set byte if boss is invulnerable in all but a certain spot. (Dot product fvec|vec_to_collision < BOSS_INVULNERABLE_DOT)
2013-12-29 04:28:07 +00:00
extern segnum_t Believed_player_seg ;
extern objnum_t Ai_last_missile_camera ;
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2013-12-21 23:16:19 +00:00
extern void create_awareness_event ( object * objp , enum player_awareness_type_t type ) ; // object *objp can create awareness of player, amount based on "type"
# endif
2013-12-29 04:28:07 +00:00
struct boss_special_segment_array_t : public count_array_t < segnum_t , MAX_BOSS_TELEPORT_SEGS > { } ;
2013-12-11 23:59:36 +00:00
struct boss_teleport_segment_array_t : public boss_special_segment_array_t { } ;
struct boss_gate_segment_array_t : public boss_special_segment_array_t { } ;
2010-12-22 00:17:59 +00:00
extern fix64 Boss_cloak_start_time , Boss_cloak_end_time ;
2013-12-11 23:59:36 +00:00
extern boss_teleport_segment_array_t Boss_teleport_segs ;
2010-12-22 00:17:59 +00:00
extern fix64 Last_teleport_time ;
2006-03-20 17:12:09 +00:00
extern fix Boss_cloak_duration ;
2013-05-26 01:48:55 +00:00
extern int Boss_dying ;
2006-03-20 17:12:09 +00:00
extern vms_vector Believed_player_pos ;
extern void move_towards_segment_center ( object * objp ) ;
2013-12-29 04:28:07 +00:00
extern objptridx_t gate_in_robot ( int type , segnum_t segnum ) ;
2006-03-20 17:12:09 +00:00
extern void do_ai_movement ( object * objp ) ;
2013-12-29 04:28:07 +00:00
extern void ai_move_to_new_segment ( object * obj , segnum_t newseg , int first_time ) ;
2006-03-20 17:12:09 +00:00
extern void ai_move_one ( object * objp ) ;
2014-08-16 23:18:17 +00:00
void do_ai_frame ( vobjptridx_t objp ) ;
2013-12-29 04:28:07 +00:00
void init_ai_object ( object * objp , int initial_mode , segnum_t hide_segment ) ;
2006-03-20 17:12:09 +00:00
extern void update_player_awareness ( object * objp , fix new_awareness ) ;
extern void do_ai_frame_all ( void ) ;
extern void reset_ai_states ( object * objp ) ;
extern void create_all_paths ( void ) ;
2014-08-23 23:53:56 +00:00
void create_path_to_station ( vobjptridx_t objp , int max_length ) ;
2014-10-02 03:02:36 +00:00
void ai_follow_path ( vobjptridx_t objp , int player_visibility , const vms_vector * vec_to_player ) ;
2014-10-02 03:02:36 +00:00
void ai_turn_towards_vector ( const vms_vector & vec_to_player , object * obj , fix rate ) ;
2006-03-20 17:12:09 +00:00
extern void ai_turn_towards_vel_vec ( object * objp , fix rate ) ;
extern void init_ai_objects ( void ) ;
2014-08-23 23:53:56 +00:00
void do_ai_robot_hit ( vobjptridx_t robot , int type ) ;
void create_n_segment_path ( vobjptridx_t objp , int path_length , segnum_t avoid_seg ) ;
void create_n_segment_path_to_door ( vobjptridx_t objp , int path_length , segnum_t avoid_seg ) ;
2006-03-20 17:12:09 +00:00
extern void make_random_vector ( vms_vector * vec ) ;
extern void init_robots_for_level ( void ) ;
extern int ai_behavior_to_mode ( int behavior ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2013-12-29 04:28:07 +00:00
void create_path_to_segment ( object * objp , segnum_t goalseg , int max_length , int safety_flag ) ;
2014-08-23 23:53:56 +00:00
int polish_path ( vobjptridx_t objp , point_seg * psegs , int num_points ) ;
2014-10-02 03:02:36 +00:00
void move_towards_player ( object * objp , const vms_vector & vec_to_player ) ;
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
// max_length is maximum depth of path to create.
// If -1, use default: MAX_DEPTH_TO_SEARCH_FOR_PLAYER
2014-08-23 23:53:56 +00:00
void create_path_to_player ( vobjptridx_t objp , int max_length , int safety_flag ) ;
void attempt_to_resume_path ( vobjptridx_t objp ) ;
2006-03-20 17:12:09 +00:00
// When a robot and a player collide, some robots attack!
2014-08-23 23:53:56 +00:00
void do_ai_robot_hit_attack ( vobjptridx_t robot , objptridx_t player , vms_vector * collision_point ) ;
2006-03-20 17:12:09 +00:00
extern void ai_open_doors_in_segment ( object * robot ) ;
extern int ai_door_is_openable ( object * objp , segment * segp , int sidenum ) ;
2014-10-02 03:02:37 +00:00
int player_is_visible_from_object ( vobjptridx_t objp , vms_vector * pos , fix field_of_view , const vms_vector & vec_to_player ) ;
2006-03-20 17:12:09 +00:00
extern void ai_reset_all_paths ( void ) ; // Reset all paths. Call at the start of a level.
2014-08-16 23:18:17 +00:00
int ai_multiplayer_awareness ( vobjptridx_t objp , int awareness_level ) ;
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
// In escort.c
2014-08-23 23:53:56 +00:00
void do_escort_frame ( vobjptridx_t objp , fix dist_to_player , int player_visibility ) ;
void do_snipe_frame ( vobjptridx_t objp , fix dist_to_player , int player_visibility , vms_vector * vec_to_player ) ;
2014-10-02 03:02:36 +00:00
void do_thief_frame ( vobjptridx_t objp , fix dist_to_player , int player_visibility , const vms_vector & vec_to_player ) ;
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2013-10-27 22:01:11 +00:00
# if PARALLAX
2013-06-08 22:24:17 +00:00
extern void force_dump_ai_objects_all ( const char * msg ) ;
2006-03-20 17:12:09 +00:00
# else
2013-10-27 22:01:11 +00:00
static inline void force_dump_ai_objects_all ( const char * msg )
{
( void ) msg ;
}
2006-03-20 17:12:09 +00:00
# endif
extern void start_boss_death_sequence ( object * objp ) ;
extern void ai_init_boss_for_ship ( void ) ;
extern int Boss_been_hit ;
extern fix AI_proc_time ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
extern fix Dist_to_last_fired_upon_player_pos ;
extern vms_vector Last_fired_upon_player_pos ;
# define ESCORT_GOAL_UNSPECIFIED -1
# define ESCORT_GOAL_UNSPECIFIED -1
# define ESCORT_GOAL_BLUE_KEY 1
# define ESCORT_GOAL_GOLD_KEY 2
# define ESCORT_GOAL_RED_KEY 3
# define ESCORT_GOAL_CONTROLCEN 4
# define ESCORT_GOAL_EXIT 5
// Custom escort goals.
# define ESCORT_GOAL_ENERGY 6
# define ESCORT_GOAL_ENERGYCEN 7
# define ESCORT_GOAL_SHIELD 8
# define ESCORT_GOAL_POWERUP 9
# define ESCORT_GOAL_ROBOT 10
# define ESCORT_GOAL_HOSTAGE 11
# define ESCORT_GOAL_PLAYER_SPEW 12
# define ESCORT_GOAL_SCRAM 13
# define ESCORT_GOAL_BOSS 15
# define ESCORT_GOAL_MARKER1 16
# define ESCORT_GOAL_MARKER2 17
# define ESCORT_GOAL_MARKER3 18
# define ESCORT_GOAL_MARKER4 19
# define ESCORT_GOAL_MARKER5 20
# define ESCORT_GOAL_MARKER6 21
# define ESCORT_GOAL_MARKER7 22
# define ESCORT_GOAL_MARKER8 23
# define ESCORT_GOAL_MARKER9 24
# define MAX_ESCORT_GOALS 25
# define MAX_ESCORT_DISTANCE (F1_0*80)
# define MIN_ESCORT_DISTANCE (F1_0*40)
# define FUELCEN_CHECK 1000
2010-12-22 00:17:59 +00:00
extern fix64 Escort_last_path_created ;
2013-12-29 04:28:07 +00:00
extern int Escort_goal_object , Escort_special_goal ;
extern objnum_t Escort_goal_index ;
2006-03-20 17:12:09 +00:00
# define GOAL_WIDTH 11
# define SNIPE_RETREAT_TIME (F1_0*5)
# define SNIPE_ABORT_RETREAT_TIME (SNIPE_RETREAT_TIME / 2) // Can abort a retreat with this amount of time left in retreat
# define SNIPE_ATTACK_TIME (F1_0*10)
# define SNIPE_WAIT_TIME (F1_0*5)
# define SNIPE_FIRE_TIME (F1_0*2)
# define THIEF_PROBABILITY 16384 // 50% chance of stealing an item at each attempt
# define MAX_STOLEN_ITEMS 10 // Maximum number kept track of, will keep stealing, causes stolen weapons to be lost!
extern int Max_escort_length ;
extern int Escort_kill_object ;
2013-12-12 23:48:34 +00:00
struct stolen_items_t : public array < ubyte , MAX_STOLEN_ITEMS > { } ;
extern stolen_items_t Stolen_items ;
2006-03-20 17:12:09 +00:00
extern void create_buddy_bot ( void ) ;
2013-12-29 04:28:07 +00:00
objnum_t boss_spew_robot ( object * objp , vms_vector * pos ) ;
2012-11-11 00:14:30 +00:00
void init_ai_for_ship ( void ) ;
2006-03-20 17:12:09 +00:00
// Amount of time since the current robot was last processed for things such as movement.
// It is not valid to use FrameTime because robots do not get moved every frame.
// --------- John: These variables must be saved as part of gamesave. ---------
extern int Ai_initialized ;
extern int Overall_agitation ;
extern fix Boss_teleport_interval ;
extern fix Boss_cloak_interval ; // Time between cloaks
2010-12-22 00:17:59 +00:00
extern fix64 Last_gate_time ;
2006-03-20 17:12:09 +00:00
extern fix Gate_interval ;
2010-12-22 00:17:59 +00:00
extern fix64 Boss_dying_start_time ;
2013-05-26 01:48:55 +00:00
extern sbyte Boss_dying_sound_playing ;
2010-12-22 00:17:59 +00:00
extern fix64 Boss_hit_time ;
2006-03-20 17:12:09 +00:00
// -- extern int Boss_been_hit;
// ------ John: End of variables which must be saved as part of gamesave. -----
// These globals are set by a call to find_vector_intersection, which is a slow routine,
// so we don't want to call it again (for this object) unless we have to.
extern vms_vector Hit_pos ;
2013-12-29 04:28:07 +00:00
extern int Hit_type ;
2006-03-20 17:12:09 +00:00
extern fvi_info Hit_data ;
# ifndef NDEBUG
// Index into this array with ailp->mode
// Index into this array with aip->behavior
// Index into this array with aip->GOAL_STATE or aip->CURRENT_STATE
2013-12-26 22:21:16 +00:00
extern int Do_ai_flag ;
2013-12-29 04:28:07 +00:00
extern objnum_t Break_on_object ;
2006-03-20 17:12:09 +00:00
# endif //ifndef NDEBUG
extern int Stolen_item_index ; // Used in ai.c for controlling rate of Thief flare firing.
// -- unused, 08/07/95 -- extern void ai_turn_randomly(vms_vector *vec_to_player, object *obj, fix rate, int previous_visibility);
extern void init_ai_frame ( void ) ;
2014-09-20 23:47:27 +00:00
void create_bfs_list ( segnum_t start_seg , segnum_t bfs_list [ ] , unsigned & length , unsigned max_segs ) ;
2014-08-13 02:59:21 +00:00
template < std : : size_t N >
2014-09-20 23:47:27 +00:00
void create_bfs_list ( segnum_t start_seg , segnum_t ( & bfs_list ) [ N ] , unsigned & length )
2014-08-13 02:59:21 +00:00
{
create_bfs_list ( start_seg , bfs_list , length , N ) ;
}
2006-03-20 17:12:09 +00:00
extern void init_thief_for_level ( ) ;
2013-12-29 04:28:07 +00:00
extern objnum_t Buddy_objnum ;
extern int Buddy_allowed_to_talk ;
2006-03-20 17:12:09 +00:00
extern void start_robot_death_sequence ( object * objp ) ;
2013-12-08 23:37:40 +00:00
void buddy_message_str ( const char * str ) __attribute_nonnull ( ) ;
void buddy_message ( const char * format , . . . ) __attribute_format_printf ( 1 , 2 ) ;
# define buddy_message(F,...) dxx_call_printf_checked(buddy_message,buddy_message_str,(),(F),##__VA_ARGS__)
2006-03-20 17:12:09 +00:00
# define SPECIAL_REACTOR_ROBOT 65
extern void special_reactor_stuff ( void ) ;
2013-03-03 01:03:33 +00:00
# endif
2013-12-21 23:16:19 +00:00
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
2013-12-28 18:47:17 +00:00
struct point_seg_array_t : public array < point_seg , MAX_POINT_SEGS > { } ;
extern point_seg_array_t Point_segs ;
extern point_seg_array_t : : iterator Point_segs_free_ptr ;
static inline std : : size_t operator - ( point_seg_array_t : : iterator i , point_seg_array_t & p )
{
return std : : distance ( p . begin ( ) , i ) ;
}
2013-12-21 23:16:19 +00:00
# endif
2013-09-24 01:59:09 +00:00
2013-03-03 01:03:33 +00:00
extern int ai_save_state ( PHYSFS_file * fp ) ;
extern int ai_restore_state ( PHYSFS_file * fp , int version , int swap ) ;
2006-03-20 17:12:09 +00:00
2014-08-16 23:18:17 +00:00
int create_path_points ( vobjptridx_t objp , segnum_t start_seg , segnum_t end_seg , point_seg_array_t : : iterator point_segs , short * num_points , int max_depth , int random_flag , int safety_flag , segnum_t avoid_seg ) ;
2013-12-28 18:47:17 +00:00
2012-11-11 00:14:30 +00:00
# ifdef EDITOR
void player_follow_path ( struct object * objp ) ;
void check_create_player_path ( void ) ;
# endif
2012-11-11 22:12:51 +00:00
# endif
2006-03-20 17:12:09 +00:00
# endif /* _AI_H */