Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 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