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 .
*
*/
2015-01-12 00:26:04 +00:00
# pragma once
2006-03-20 17:12:09 +00:00
2013-12-28 18:47:17 +00:00
# include <cstddef>
2013-06-27 02:35:22 +00:00
# include "dxxsconf.h"
2016-03-19 19:08:10 +00:00
# include "dsx-ns.h"
2013-12-08 23:37:40 +00:00
# include "fmtcheck.h"
2015-07-25 23:10:45 +00:00
# include "vecmat.h"
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
2014-11-17 04:02:25 +00:00
# include "pstypes.h"
2015-10-10 03:44:14 +00:00
# include "fwd-object.h"
2015-10-10 03:44:14 +00:00
# include "fwd-segment.h"
2015-04-19 04:18:51 +00:00
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
2013-12-26 04:18:28 +00:00
# include "countarray.h"
2014-11-23 04:36:58 +00:00
# include "aistruct.h"
2015-04-19 04:18:51 +00:00
# endif
2012-11-11 22:12:51 +00:00
2015-12-13 18:00:49 +00:00
namespace dcx {
2013-12-21 23:16:19 +00:00
struct point_seg ;
2015-12-22 04:18:50 +00:00
extern sbyte Boss_hit_this_frame ;
2015-12-13 18:00:48 +00:00
}
2014-11-17 04:02:25 +00:00
struct PHYSFS_File ;
2013-12-21 23:16:19 +00:00
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 ROBOT_BRAIN 7
# define ROBOT_BOSS1 17
# define ROBOT_FIRE_AGITATION 94
2016-01-09 16:38:15 +00:00
# ifdef dsx
2015-02-08 06:06:01 +00:00
# define BOSS_D1 1
# define BOSS_SUPER 2
# if defined(DXX_BUILD_DESCENT_II)
2016-10-02 00:34:42 +00:00
# include "player-flags.h"
2015-12-22 04:18:50 +00:00
namespace dsx {
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
2015-04-02 02:36:52 +00:00
typedef array < ubyte , NUM_D2_BOSSES > boss_flags_t ;
2015-04-02 02:36:52 +00:00
extern const boss_flags_t Boss_teleports ; // Set byte if this boss can teleport
extern const boss_flags_t Boss_spew_more ; // 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
2015-04-02 02:36:52 +00:00
extern const boss_flags_t Boss_spews_bots_energy ; // Set byte if boss spews bots when hit by energy weapon.
extern const boss_flags_t Boss_spews_bots_matter ; // Set byte if boss spews bots when hit by matter weapon.
extern const boss_flags_t Boss_invulnerable_energy ; // Set byte if boss is invulnerable to energy weapons.
extern const boss_flags_t Boss_invulnerable_matter ; // Set byte if boss is invulnerable to matter weapons.
extern const boss_flags_t Boss_invulnerable_spot ; // 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 ;
2015-05-13 03:20:28 +00:00
extern object * Ai_last_missile_camera ;
2015-12-22 04:18:50 +00:00
}
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2015-12-22 04:18:50 +00:00
namespace dcx {
2016-07-10 04:11:34 +00:00
struct boss_special_segment_array_t : public count_array_t < segnum_t , 100 > { } ;
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 { } ;
2015-07-25 23:10:45 +00:00
extern boss_teleport_segment_array_t Boss_teleport_segs ;
2015-12-22 04:18:50 +00:00
}
namespace dsx {
void create_awareness_event ( vobjptr_t objp , player_awareness_type_t type ) ; // object *objp can create awareness of player, amount based on "type"
2015-07-25 23:10:45 +00:00
ai_mode ai_behavior_to_mode ( ai_behavior behavior ) ;
void do_ai_robot_hit ( vobjptridx_t robot , player_awareness_type_t type ) ;
2016-04-23 17:59:47 +00:00
void init_ai_object ( object & objp , ai_behavior initial_mode , segnum_t hide_segment ) ;
2015-12-22 04:18:50 +00:00
}
2013-12-11 23:59:36 +00:00
2015-12-22 04:18:50 +00:00
namespace dcx {
2015-11-19 03:23:34 +00:00
extern fix64 Boss_cloak_start_time ;
2010-12-22 00:17:59 +00:00
extern fix64 Last_teleport_time ;
2015-11-19 03:23:34 +00:00
constexpr fix Boss_cloak_duration = F1_0 * 7 ;
2015-02-08 06:06:01 +00:00
extern sbyte Boss_dying ;
2006-03-20 17:12:09 +00:00
extern vms_vector Believed_player_pos ;
2015-12-22 04:18:50 +00:00
}
2006-03-20 17:12:09 +00:00
2015-12-22 04:18:50 +00:00
namespace dsx {
2014-10-02 03:02:34 +00:00
void move_towards_segment_center ( vobjptr_t objp ) ;
2015-05-28 03:08:39 +00:00
objptridx_t gate_in_robot ( int type , vsegptridx_t segnum ) ;
2014-08-16 23:18:17 +00:00
void do_ai_frame ( vobjptridx_t objp ) ;
2015-12-22 04:18:50 +00:00
void do_ai_frame_all ( ) ;
}
2006-03-20 17:12:09 +00:00
extern void create_all_paths ( void ) ;
2015-12-22 04:18:50 +00:00
namespace dsx {
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 ) ;
2016-04-09 21:40:27 +00:00
void ai_turn_towards_vector ( const vms_vector & vec_to_player , object_base & obj , fix rate ) ;
2006-03-20 17:12:09 +00:00
extern void init_ai_objects ( void ) ;
2014-08-23 23:53:56 +00:00
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 ) ;
2015-12-22 04:18:50 +00:00
}
2015-11-26 02:56:55 +00:00
# endif
2015-12-22 04:18:50 +00:00
namespace dcx {
2014-10-02 03:02:38 +00:00
void make_random_vector ( vms_vector & vec ) ;
2015-07-25 23:10:45 +00:00
__attribute_warn_unused_result
2014-11-04 01:33:45 +00:00
static inline vms_vector make_random_vector ( )
{
vms_vector v ;
return make_random_vector ( v ) , v ;
}
2015-12-22 04:18:50 +00:00
}
2016-01-09 16:38:15 +00:00
# ifdef dsx
2015-12-22 04:18:50 +00:00
namespace dsx {
void init_robots_for_level ( ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2014-10-02 03:02:34 +00:00
void create_path_to_segment ( vobjptridx_t 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:34 +00:00
void move_towards_player ( vobjptr_t 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-12-23 04:20:27 +00:00
void do_ai_robot_hit_attack ( vobjptridx_t robot , vobjptridx_t player , const vms_vector & collision_point ) ;
2016-10-02 00:34:42 +00:00
int ai_door_is_openable (
2014-10-02 03:02:34 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2016-10-02 00:34:42 +00:00
vobjptr_t ,
2014-10-02 03:02:34 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2016-10-02 00:34:42 +00:00
objptr_t , player_flags ,
2014-10-02 03:02:34 +00:00
# endif
2016-10-02 00:34:42 +00:00
vcsegptr_t segp , int sidenum ) ;
2014-10-02 03:02:38 +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
2016-10-02 00:34:41 +00:00
void do_escort_frame ( vobjptridx_t objp , const object & plrobj , fix dist_to_player , int player_visibility ) ;
2014-10-28 01:45:53 +00:00
void do_snipe_frame ( vobjptridx_t objp , fix dist_to_player , int player_visibility , const 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
2015-12-22 04:18:50 +00:00
}
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
2015-12-22 04:18:50 +00:00
namespace dsx {
2014-10-02 03:02:34 +00:00
void start_boss_death_sequence ( vobjptr_t objp ) ;
2006-03-20 17:12:09 +00:00
extern void ai_init_boss_for_ship ( void ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
extern vms_vector Last_fired_upon_player_pos ;
2015-06-13 22:42:15 +00:00
enum escort_goal_t
{
ESCORT_GOAL_UNSPECIFIED = - 1 ,
ESCORT_GOAL_BLUE_KEY = 1 ,
ESCORT_GOAL_GOLD_KEY = 2 ,
ESCORT_GOAL_RED_KEY = 3 ,
ESCORT_GOAL_CONTROLCEN = 4 ,
ESCORT_GOAL_EXIT = 5 ,
2006-03-20 17:12:09 +00:00
// Custom escort goals.
2015-06-13 22:42:15 +00:00
ESCORT_GOAL_ENERGY = 6 ,
ESCORT_GOAL_ENERGYCEN = 7 ,
ESCORT_GOAL_SHIELD = 8 ,
ESCORT_GOAL_POWERUP = 9 ,
ESCORT_GOAL_ROBOT = 10 ,
ESCORT_GOAL_HOSTAGE = 11 ,
ESCORT_GOAL_PLAYER_SPEW = 12 ,
ESCORT_GOAL_SCRAM = 13 ,
ESCORT_GOAL_BOSS = 15 ,
ESCORT_GOAL_MARKER1 = 16 ,
ESCORT_GOAL_MARKER2 = 17 ,
ESCORT_GOAL_MARKER3 = 18 ,
ESCORT_GOAL_MARKER4 = 19 ,
ESCORT_GOAL_MARKER5 = 20 ,
ESCORT_GOAL_MARKER6 = 21 ,
ESCORT_GOAL_MARKER7 = 22 ,
ESCORT_GOAL_MARKER8 = 23 ,
ESCORT_GOAL_MARKER9 = 24 ,
} ;
2006-03-20 17:12:09 +00:00
2015-06-13 22:42:15 +00:00
# define MIN_ESCORT_DISTANCE (F1_0*40)
2006-03-20 17:12:09 +00:00
2010-12-22 00:17:59 +00:00
extern fix64 Escort_last_path_created ;
2015-06-13 22:42:15 +00:00
extern escort_goal_t Escort_goal_object , Escort_special_goal ;
2013-12-29 04:28:07 +00:00
extern objnum_t Escort_goal_index ;
2006-03-20 17:12:09 +00:00
# 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
extern int Escort_kill_object ;
2016-07-10 04:11:34 +00:00
// Maximum number kept track of, will keep stealing, causes stolen weapons to be lost!
struct stolen_items_t : public array < uint8_t , 10 > { } ;
2013-12-12 23:48:34 +00:00
extern stolen_items_t Stolen_items ;
2006-03-20 17:12:09 +00:00
extern void create_buddy_bot ( void ) ;
2016-04-23 17:59:47 +00:00
objptridx_t boss_spew_robot ( const object_base & objp , const 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. ---------
// ------ 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 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);
2016-10-02 00:34:48 +00:00
void init_ai_frame ( player_flags ) ;
2006-03-20 17:12:09 +00:00
2015-01-28 03:42:52 +00:00
__attribute_warn_unused_result
2016-10-08 03:34:17 +00:00
std : : size_t create_bfs_list ( vcsegidx_t start_seg , player_flags , segnum_t * bfs_list , std : : size_t max_segs ) ;
2014-08-13 02:59:21 +00:00
template < std : : size_t N >
2015-01-28 03:42:52 +00:00
__attribute_warn_unused_result
2016-10-08 03:34:17 +00:00
std : : size_t create_bfs_list ( const vcsegidx_t & start_seg , const player_flags powerup_flags , array < segnum_t , N > & bfs_list )
2014-08-13 02:59:21 +00:00
{
2016-10-02 00:34:47 +00:00
return create_bfs_list ( start_seg , powerup_flags , bfs_list . data ( ) , N ) ;
2014-08-13 02:59:21 +00:00
}
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
2016-04-06 03:34:15 +00:00
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
2015-12-22 04:18:50 +00:00
}
2013-03-03 01:03:33 +00:00
2015-12-13 18:00:49 +00:00
namespace dcx {
2015-12-22 04:18:50 +00:00
extern fix64 Last_gate_time ;
extern sbyte Boss_dying_sound_playing ;
extern fix Gate_interval ;
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 ) ;
}
2015-12-13 18:00:48 +00:00
}
2015-07-25 23:10:45 +00:00
2015-12-22 04:18:50 +00:00
namespace dsx {
# if defined(DXX_BUILD_DESCENT_II)
extern fix64 Boss_hit_time ;
# endif
2015-07-25 23:10:45 +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-09-24 01:59:09 +00:00
2014-11-17 04:02:25 +00:00
int ai_save_state ( PHYSFS_File * fp ) ;
int ai_restore_state ( PHYSFS_File * fp , int version , int swap ) ;
2006-03-20 17:12:09 +00:00
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2014-10-02 03:02:34 +00:00
void player_follow_path ( vobjptr_t objp ) ;
2015-12-22 04:18:50 +00:00
void check_create_player_path ( ) ;
2012-11-11 00:14:30 +00:00
# endif
2015-12-22 04:18:50 +00:00
}
2015-11-26 02:56:55 +00:00
# endif
2012-11-11 00:14:30 +00:00
2012-11-11 22:12:51 +00:00
# endif