1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #ifndef __ASTEROID_H__
13 #define __ASTEROID_H__
14 
15 #include "globalincs/pstypes.h"
16 #include "globalincs/globals.h"		// for NAME_LENGTH
17 
18 
19 class object;
20 class polymodel;
21 struct collision_info_struct;
22 
23 #define	MAX_ASTEROIDS			512
24 
25 #define NUM_DEBRIS_SIZES		3
26 #define	NUM_DEBRIS_POFS			3				// Number of POFs per debris size
27 
28 #define	ASTEROID_TYPE_SMALL		0
29 #define	ASTEROID_TYPE_MEDIUM	1
30 #define	ASTEROID_TYPE_LARGE		2
31 
32 // these should always be equal for the benefit of generic asteroids (c.f. asteroid_page_in)
33 #define	MAX_ACTIVE_DEBRIS_TYPES		NUM_DEBRIS_SIZES
34 
35 // Goober5000 - currently same as MAX_SHIP_DETAIL_LEVELS (put here to avoid an #include)
36 #define MAX_ASTEROID_DETAIL_LEVELS	5
37 
38 
39 // Data structure to track the active asteroids
40 typedef struct asteroid_obj {
41 	asteroid_obj *next, *prev;
42 	int flags, objnum;
43 } asteroid_obj;
44 extern asteroid_obj Asteroid_obj_list;
45 
46 
47 // Data structure for determining a type and amount of other asteroids an
48 // asteroid will split to when destroyed.
49 typedef struct asteroid_split_info {
50 	int		asteroid_type;
51 	int		min;
52 	int		max;
53 } asteroid_split_info;
54 
55 class asteroid_info
56 {
57 public:
58 	char		name[NAME_LENGTH];								// name for the asteroid
59 	char		pof_files[NUM_DEBRIS_POFS][MAX_FILENAME_LEN];	// POF files to load/associate with ship
60 	int			num_detail_levels;								// number of detail levels for this ship
61 	int			detail_distance[MAX_ASTEROID_DETAIL_LEVELS];	// distance to change detail levels at
62 	float		max_speed;										// cap on speed for asteroid
63 	int			damage_type_idx;								//Damage type of the asteroid
64 	int			damage_type_idx_sav;							// stored value from table used to reset damage_type_idx
65 	float		inner_rad;										// radius within which maximum area effect damage is applied
66 	float		outer_rad;										// radius at which no area effect damage is applied
67 	float		damage;											// maximum damage applied from area effect explosion
68 	float		blast;											// maximum blast impulse from area effect explosion
69 	float		initial_asteroid_strength;						// starting strength of asteroid
70 	SCP_vector< asteroid_split_info > split_info;
71 	polymodel	*modelp[NUM_DEBRIS_POFS];
72 	int			model_num[NUM_DEBRIS_POFS];
73 	SCP_vector<int> explosion_bitmap_anims;
74 	float		fireball_radius_multiplier;						// the model radius is multiplied by this to determine the fireball size
75 
asteroid_info()76 	asteroid_info( )
77 		: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( 0 ),
78 		  damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
79 		  damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 ),
80 		  fireball_radius_multiplier( -1 )
81 	{
82 		name[ 0 ] = 0;
83 		memset( detail_distance, 0, sizeof( detail_distance ) );
84 
85 		for (int i = 0; i < NUM_DEBRIS_POFS; i++)
86 		{
87 			modelp[i] = NULL;
88 			model_num[i] = -1;
89 			pof_files[i][0] = 0;
90 		}
91 	}
92 };
93 
94 
95 #define	AF_USED					(1<<0)			// Set means used.
96 
97 typedef	struct asteroid {
98 	int		flags;
99 	int		objnum;
100 	int		asteroid_type;		// 0..MAX_DEBRIS_TYPES
101 	int		asteroid_subtype;	// Index in asteroid_info for modelnum and modelp
102 	int		check_for_wrap;		// timestamp to check for asteroid wrapping around field
103 	int		check_for_collide;	// timestamp to check for asteroid colliding with escort ships
104 	int		final_death_time;	// timestamp to swap in new models after explosion starts
105 	int		collide_objnum;		// set to objnum that asteroid will be impacting soon
106 	int		collide_objsig;		// object signature corresponding to collide_objnum
107 	vec3d	death_hit_pos;		// hit pos that caused death
108 	int		target_objnum;		// Yes, hah!  Asteroids can have targets.  See asteroid_aim_at_target().
109 } asteroid;
110 
111 
112 // TYPEDEF FOR DEBRIS TYPE
113 typedef enum {
114 	DG_ASTEROID,
115 	DG_SHIP
116 } debris_genre_t;
117 
118 // TYPEDEF FOR FIELD TYPE
119 typedef enum {
120 	FT_ACTIVE,
121 	FT_PASSIVE
122 } field_type_t;
123 
124 typedef	struct asteroid_field {
125 	vec3d	min_bound;					// Minimum range of field.
126 	vec3d	max_bound;					// Maximum range of field.
127 	int		has_inner_bound;
128 	vec3d	inner_min_bound;
129 	vec3d	inner_max_bound;
130 	vec3d	vel;						// Average asteroid moves at this velocity.
131 	float		speed;					// Average speed of field
132 	int		num_initial_asteroids;		// Number of asteroids at creation.
133 	field_type_t		field_type;		// active throws and wraps, passive does not
134 	debris_genre_t	debris_genre;		// type of debris (ship or asteroid)  [generic type]
135 	int				field_debris_type[MAX_ACTIVE_DEBRIS_TYPES];	// one of the debris type defines above
136 } asteroid_field;
137 
138 extern SCP_vector< asteroid_info > Asteroid_info;
139 extern asteroid Asteroids[MAX_ASTEROIDS];
140 extern asteroid_field	Asteroid_field;
141 
142 extern int	Num_asteroids;
143 extern int	Asteroids_enabled;
144 extern char		Asteroid_icon_closeup_model[NAME_LENGTH];	// model for asteroid field briefing icon rendering
145 extern vec3d	Asteroid_icon_closeup_position;  // closeup position for asteroid field briefing icon rendering
146 extern float	Asteroid_icon_closeup_zoom;		 // zoom position for asteroid field briefing icon rendering
147 
148 void	asteroid_init();
149 void	asteroid_level_init();
150 void	asteroid_level_close();
151 void	asteroid_create_all();
152 void	asteroid_render( object *asteroid_objp );
153 void	asteroid_delete( object *asteroid_objp );
154 void	asteroid_process_pre( object *asteroid_objp, float frame_time);
155 void	asteroid_process_post( object *asteroid_objp, float frame_time);
156 int	asteroid_check_collision( object *asteroid_objp, object * other_obj, vec3d * hitpos, collision_info_struct *asteroid_hit_info=NULL );
157 void	asteroid_hit( object *asteroid_objp, object *other_objp, vec3d *hitpos, float damage );
158 int	asteroid_count();
159 int	asteroid_collide_objnum(object *asteroid_objp);
160 float asteroid_time_to_impact(object *asteroid_objp);
161 void	asteroid_show_brackets();
162 void	asteroid_target_closest_danger();
163 int	asteroid_get_random_in_cone(vec3d *pos, vec3d *dir, float ang, int danger = 0);
164 
165 // need to extern for multiplayer
166 void asteroid_sub_create(object *parent_objp, int asteroid_type, vec3d *relvec);
167 
168 void asteroid_frame();
169 
170 #endif	// __ASTEROID_H__
171