Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * Structs and constants for AI system.
  23.  * object.h depends on this.
  24.  * ai.h depends on object.h.
  25.  * Get it?
  26.  *
  27.  */
  28.  
  29. #pragma once
  30.  
  31. #include <physfs.h>
  32.  
  33. #ifdef __cplusplus
  34. #include "polyobj.h"
  35. #include "pack.h"
  36. #include "objnum.h"
  37. #include "fwd-segment.h"
  38.  
  39. #define GREEN_GUY   1
  40.  
  41. #define MAX_SEGMENTS_PER_PATH       20
  42.  
  43. namespace dcx {
  44.  
  45. enum class player_awareness_type_t : uint8_t
  46. {
  47.         PA_NONE,
  48.         PA_NEARBY_ROBOT_FIRED           = 1,  // Level of robot awareness after nearby robot fires a weapon
  49.         PA_WEAPON_WALL_COLLISION        = 2,  // Level of robot awareness after player weapon hits nearby wall
  50. //      PA_PLAYER_VISIBLE                       = 2,  // Level of robot awareness if robot is looking towards player, and player not hidden
  51.         PA_PLAYER_COLLISION                     = 3,  // Level of robot awareness after player bumps into robot
  52.         PA_WEAPON_ROBOT_COLLISION       = 4,  // Level of robot awareness after player weapon hits nearby robot
  53. };
  54.  
  55. enum class player_visibility_state : int8_t
  56. {
  57.         no_line_of_sight,
  58.         visible_not_in_field_of_view,
  59.         visible_and_in_field_of_view,
  60. };
  61.  
  62. static inline unsigned player_is_visible(const player_visibility_state s)
  63. {
  64.         return static_cast<unsigned>(s) > 0;
  65. }
  66.  
  67. }
  68.  
  69. // Constants indicating currently moving forward or backward through
  70. // path.  Note that you can add aip->direction to aip_path_index to
  71. // get next segment on path.
  72. #define AI_DIR_FORWARD  1
  73. #define AI_DIR_BACKWARD (-AI_DIR_FORWARD)
  74.  
  75. #ifdef dsx
  76. namespace dsx {
  77.  
  78. enum class ai_behavior : uint8_t
  79. {
  80. // Behaviors
  81.         AIB_STILL = 0x80,
  82.         AIB_NORMAL = 0x81,
  83.         AIB_RUN_FROM = 0x83,
  84.         AIB_STATION = 0x85,
  85. #if defined(DXX_BUILD_DESCENT_I)
  86.         AIB_HIDE = 0x82,
  87.         AIB_FOLLOW_PATH = 0x84,
  88. #elif defined(DXX_BUILD_DESCENT_II)
  89.         AIB_BEHIND = 0x82,
  90.         AIB_SNIPE = 0x84,
  91.         AIB_FOLLOW = 0x86,
  92. #endif
  93. };
  94.  
  95. #define MIN_BEHAVIOR    0x80
  96. #if defined(DXX_BUILD_DESCENT_I)
  97. #define MAX_BEHAVIOR    0x85
  98. #elif defined(DXX_BUILD_DESCENT_II)
  99. #define MAX_BEHAVIOR    0x86
  100. #endif
  101.  
  102. enum class ai_mode : uint8_t
  103. {
  104. //  Modes
  105.         AIM_STILL = 0,
  106.         AIM_WANDER = 1,
  107.         AIM_FOLLOW_PATH = 2,
  108.         AIM_CHASE_OBJECT = 3,
  109.         AIM_RUN_FROM_OBJECT = 4,
  110.         AIM_FOLLOW_PATH_2 = 6,
  111.         AIM_OPEN_DOOR = 7,
  112. #if defined(DXX_BUILD_DESCENT_I)
  113.         AIM_HIDE = 5,
  114. #elif defined(DXX_BUILD_DESCENT_II)
  115.         AIM_BEHIND = 5,
  116.         AIM_GOTO_PLAYER = 8,   //  Only for escort behavior
  117.         AIM_GOTO_OBJECT = 9,   //  Only for escort behavior
  118.  
  119.         AIM_SNIPE_ATTACK = 10,
  120.         AIM_SNIPE_FIRE = 11,
  121.         AIM_SNIPE_RETREAT = 12,
  122.         AIM_SNIPE_RETREAT_BACKWARDS = 13,
  123.         AIM_SNIPE_WAIT = 14,
  124.  
  125.         AIM_THIEF_ATTACK = 15,
  126.         AIM_THIEF_RETREAT = 16,
  127.         AIM_THIEF_WAIT = 17,
  128. #endif
  129. };
  130.  
  131. }
  132. #endif
  133.  
  134. #define AISM_GOHIDE                 0
  135. #define AISM_HIDING                 1
  136.  
  137. #define AI_MAX_STATE    7
  138. #define AI_MAX_EVENT    4
  139.  
  140. #define AIS_NONE        0
  141. #define AIS_REST        1
  142. #define AIS_SRCH        2
  143. #define AIS_LOCK        3
  144. #define AIS_FLIN        4
  145. #define AIS_FIRE        5
  146. #define AIS_RECO        6
  147. #define AIS_ERR_        7
  148.  
  149. #define AIE_FIRE        0
  150. #define AIE_HITT        1
  151. #define AIE_COLL        2
  152. #define AIE_HURT        3
  153.  
  154. //typedef struct opath {
  155. //      sbyte   path_index;     // current index of path
  156. //      sbyte   path_direction; // current path direction
  157. //      sbyte   path_length;    // length of current path
  158. //      sbyte   nothing;
  159. //      short   path[MAX_SEGMENTS_PER_PATH];
  160. //      short   always_0xabc;   // If this is ever not 0xabc, then someone overwrote
  161. //} opath;
  162. //
  163. //typedef struct oai_state {
  164. //      short   mode;               //
  165. //      short   counter;            // kind of a hack, frame countdown until switch modes
  166. //      opath   paths[2];
  167. //      vms_vector movement_vector; // movement vector for one second
  168. //} oai_state;
  169.  
  170. #if defined(DXX_BUILD_DESCENT_II)
  171. #define SUB_FLAGS_GUNSEG        0x01
  172. #define SUB_FLAGS_SPROX         0x02    // If set, then this bot drops a super prox, not a prox, when it's time to drop something
  173. #define SUB_FLAGS_CAMERA_AWAKE  0x04    // If set, a camera (on a missile) woke this robot up, so don't fire at player.  Can look real stupid!
  174. #endif
  175.  
  176. //  Constants defining meaning of flags in ai_state
  177. #define MAX_AI_FLAGS    11          // This MUST cause word (4 bytes) alignment in ai_static, allowing for one byte mode
  178.  
  179. #define CURRENT_GUN     flags[0]    // This is the last gun the object fired from
  180. #define CURRENT_STATE   flags[1]    // current behavioral state
  181. #define GOAL_STATE      flags[2]    // goal state
  182. #define PATH_DIR        flags[3]    // direction traveling path, 1 = forward, -1 = backward, other = error!
  183. #if defined(DXX_BUILD_DESCENT_I)
  184. #define SUBMODE                 flags[4]                        //      submode, eg AISM_HIDING if mode == AIM_HIDE
  185. #elif defined(DXX_BUILD_DESCENT_II)
  186. #define SUB_FLAGS       flags[4]    // bit 0: Set -> Robot's current gun in different segment than robot's center.
  187. #endif
  188. #define GOALSIDE        flags[5]    // for guys who open doors, this is the side they are going after.
  189. #define CLOAKED         flags[6]    // Cloaked now.
  190. #define SKIP_AI_COUNT   flags[7]    // Skip AI this frame, but decrement in do_ai_frame.
  191. #define  REMOTE_OWNER   flags[8]    // Who is controlling this remote AI object (multiplayer use only)
  192. #define  REMOTE_SLOT_NUM flags[9]   // What slot # is this robot in for remote control purposes (multiplayer use only)
  193.  
  194. // This is the stuff that is permanent for an AI object.
  195. #ifdef dsx
  196. namespace dsx {
  197.  
  198. // Rather temporal AI stuff.
  199. struct ai_local : public prohibit_void_ptr<ai_local>
  200. {
  201. // These used to be bytes, changed to ints so I could set watchpoints on them.
  202.         player_awareness_type_t player_awareness_type = player_awareness_type_t::PA_NONE;           // type of awareness of player
  203.         uint8_t retry_count = 0;                     // number of retries in physics last time this object got moved.
  204.         uint8_t consecutive_retries = 0;             // number of retries in consecutive frames (ie, without a retry_count of 0)
  205.         player_visibility_state previous_visibility{};             // Visibility of player last time we checked.
  206.         uint8_t rapidfire_count = 0;                 // number of shots fired rapidly
  207.         ai_mode mode{};                            // current mode within behavior
  208.         segnum_t      goal_segment{};                    // goal segment for current path
  209.         fix        next_action_time = 0;              // time in seconds until something happens, mode dependent
  210.         fix        next_fire = 0;                     // time in seconds until can fire again
  211. #if defined(DXX_BUILD_DESCENT_II)
  212.         fix        next_fire2 = 0;                    // time in seconds until can fire again from second weapon
  213. #endif
  214.         fix        player_awareness_time = 0;         // time in seconds robot will be aware of player, 0 means not aware of player
  215.         fix        time_since_processed = 0;          // time since this robot last processed in do_ai_frame
  216.         fix64      time_player_seen = 0;              // absolute time in seconds at which player was last seen, might cause to go into follow_path mode
  217.         fix64      time_player_sound_attacked = 0;    // absolute time in seconds at which player was last seen with visibility of 2.
  218.         fix64      next_misc_sound_time = 0;          // absolute time in seconds at which this robot last made an angry or lurking sound.
  219.         std::array<vms_angvec, MAX_SUBMODELS> goal_angles{};    // angles for each subobject
  220.         std::array<vms_angvec, MAX_SUBMODELS> delta_angles{};   // angles for each subobject
  221.         std::array<sbyte, MAX_SUBMODELS> goal_state{};     // Goal state for this sub-object
  222.         std::array<sbyte, MAX_SUBMODELS> achieved_state{}; // Last achieved state
  223. };
  224.  
  225. struct ai_static : public prohibit_void_ptr<ai_static>
  226. {
  227.         ai_behavior behavior = static_cast<ai_behavior>(0);               //
  228.         std::array<sbyte, MAX_AI_FLAGS> flags{};    // various flags, meaning defined by constants
  229.         segnum_t hide_segment{};           // Segment to go to for hiding.
  230.         short hide_index{};             // Index in Path_seg_points
  231.         short path_length{};            // Length of hide path.
  232. #if defined(DXX_BUILD_DESCENT_I)
  233.         short cur_path_index{};         // Current index in path.
  234. #elif defined(DXX_BUILD_DESCENT_II)
  235.         sbyte cur_path_index{};         // Current index in path.
  236.         sbyte dying_sound_playing{};    // !0 if this robot is playing its dying sound.
  237. #endif
  238.         objnum_t danger_laser_num{};
  239.         object_signature_t danger_laser_signature;
  240. #if defined(DXX_BUILD_DESCENT_II)
  241.         fix64 dying_start_time{};       // Time at which this robot started dying.
  242. #endif
  243.         ai_local ail;
  244. };
  245.  
  246. // Same as above but structure Savegames/Multiplayer objects expect
  247. struct ai_static_rw
  248. {
  249.         ubyte   behavior;               //
  250.         sbyte   flags[MAX_AI_FLAGS];    // various flags, meaning defined by constants
  251.         short   hide_segment;           // Segment to go to for hiding.
  252.         short   hide_index;             // Index in Path_seg_points
  253.         short   path_length;            // Length of hide path.
  254. #if defined(DXX_BUILD_DESCENT_I)
  255.         short   cur_path_index;         // Current index in path.
  256.         short   follow_path_start_seg;  // Start segment for robot which follows path.
  257.         short   follow_path_end_seg;    // End segment for robot which follows path.
  258.         int     danger_laser_signature;
  259.         short   danger_laser_num;
  260. #elif defined(DXX_BUILD_DESCENT_II)
  261.         sbyte   cur_path_index;         // Current index in path.
  262.         sbyte   dying_sound_playing;    // !0 if this robot is playing its dying sound.
  263.         short   danger_laser_num;
  264.         int     danger_laser_signature;
  265.         fix     dying_start_time;       // Time at which this robot started dying.
  266. #endif
  267. } __pack__;
  268.  
  269. // Same as above but structure Savegames expect
  270. struct ai_local_rw
  271. {
  272. // These used to be bytes, changed to ints so I could set watchpoints on them.
  273. #if defined(DXX_BUILD_DESCENT_I)
  274.         sbyte      player_awareness_type;           // type of awareness of player
  275.         sbyte      retry_count;                     // number of retries in physics last time this object got moved.
  276.         sbyte      consecutive_retries;             // number of retries in consecutive frames (ie, without a retry_count of 0)
  277.         sbyte      mode;                            // current mode within behavior
  278.         sbyte      previous_visibility;             // Visibility of player last time we checked.
  279.         sbyte      rapidfire_count;                 // number of shots fired rapidly
  280.         short      goal_segment;                    // goal segment for current path
  281.         fix        last_see_time, last_attack_time; // For sound effects, time at which player last seen, attacked
  282. #elif defined(DXX_BUILD_DESCENT_II)
  283.         int        player_awareness_type;         // type of awareness of player
  284.         int        retry_count;                   // number of retries in physics last time this object got moved.
  285.         int        consecutive_retries;           // number of retries in consecutive frames (ie, without a retry_count of 0)
  286.         int        mode;                          // current mode within behavior
  287.         int        previous_visibility;           // Visibility of player last time we checked.
  288.         int        rapidfire_count;               // number of shots fired rapidly
  289.         int        goal_segment;                  // goal segment for current path
  290. #endif
  291.         fix        next_action_time;              // time in seconds until something happens, mode dependent
  292.         fix        next_fire;                     // time in seconds until can fire again
  293. #if defined(DXX_BUILD_DESCENT_II)
  294.         fix        next_fire2;                    // time in seconds until can fire again from second weapon
  295. #endif
  296.         fix        player_awareness_time;         // time in seconds robot will be aware of player, 0 means not aware of player
  297.         fix        time_player_seen;              // absolute time in seconds at which player was last seen, might cause to go into follow_path mode
  298.         fix        time_player_sound_attacked;    // absolute time in seconds at which player was last seen with visibility of 2.
  299.         fix        next_misc_sound_time;          // absolute time in seconds at which this robot last made an angry or lurking sound.
  300.         fix        time_since_processed;          // time since this robot last processed in do_ai_frame
  301.         vms_angvec goal_angles[MAX_SUBMODELS];    // angles for each subobject
  302.         vms_angvec delta_angles[MAX_SUBMODELS];   // angles for each subobject
  303.         sbyte      goal_state[MAX_SUBMODELS];     // Goal state for this sub-object
  304.         sbyte      achieved_state[MAX_SUBMODELS]; // Last achieved state
  305. };
  306.  
  307. struct ai_cloak_info : public prohibit_void_ptr<ai_cloak_info>
  308. {
  309.         fix64       last_time;
  310. #if defined(DXX_BUILD_DESCENT_II)
  311.         segnum_t         last_segment;
  312. #endif
  313.         vms_vector  last_position;
  314. };
  315.  
  316. // Same as above but structure Savegames expect
  317. struct ai_cloak_info_rw
  318. {
  319.         fix         last_time;
  320. #if defined(DXX_BUILD_DESCENT_II)
  321.         int         last_segment;
  322. #endif
  323.         vms_vector  last_position;
  324. };
  325.  
  326. #if defined(DXX_BUILD_DESCENT_II)
  327.  
  328. // Maximum number kept track of, will keep stealing, causes stolen weapons to be lost!
  329. struct d_thief_unique_state
  330. {
  331.         unsigned Stolen_item_index;   // Used in ai.c for controlling rate of Thief flare firing.
  332.         std::array<uint8_t, 10> Stolen_items;
  333. };
  334.  
  335. #endif
  336. }
  337. #endif
  338.  
  339. namespace dcx {
  340.  
  341. struct point_seg : prohibit_void_ptr<point_seg> {
  342.         segnum_t         segnum;
  343.         vms_vector  point;
  344. };
  345.  
  346. struct seg_seg
  347. {
  348.         segnum_t       start, end;
  349. };
  350.  
  351. constexpr std::integral_constant<unsigned, 2500> MAX_POINT_SEGS{};
  352.  
  353. }
  354.  
  355. // These are the information for a robot describing the location of
  356. // the player last time he wasn't cloaked, and the time at which he
  357. // was uncloaked.  We should store this for each robot, but that's
  358. // memory expensive.
  359. //extern fix        Last_uncloaked_time;
  360. //extern vms_vector Last_uncloaked_position;
  361.  
  362. #ifdef dsx
  363. namespace dsx {
  364. extern void ai_do_cloak_stuff(void);
  365. }
  366. #endif
  367.  
  368. #endif
  369.