1 #ifndef __PROJECTILES_H
2 #define __PROJECTILES_H
3 
4 /*
5 PROJECTILES.H
6 
7 	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
8 	and the "Aleph One" developers.
9 
10 	This program is free software; you can redistribute it and/or modify
11 	it under the terms of the GNU General Public License as published by
12 	the Free Software Foundation; either version 3 of the License, or
13 	(at your option) any later version.
14 
15 	This program is distributed in the hope that it will be useful,
16 	but WITHOUT ANY WARRANTY; without even the implied warranty of
17 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 	GNU General Public License for more details.
19 
20 	This license is contained in the file "COPYING",
21 	which is included with this source code; it is available online at
22 	http://www.gnu.org/licenses/gpl.html
23 
24 Tuesday, June 28, 1994 7:12:00 PM
25 
26 Feb 4, 2000 (Loren Petrich):
27 	Added SMG bullet
28 
29 Feb 6, 2000 (Loren Petrich):
30 	Added access to size of projectile-definition structure
31 
32 Feb 10, 2000 (Loren Petrich):
33 	Added dynamic-limits setting of MAXIMUM_PROJECTILES_PER_MAP
34 
35 Aug 30, 2000 (Loren Petrich):
36 	Added stuff for unpacking and packing
37 
38 Jan 6, 2001 (Loren Petrich):
39 	Added accessor for "is guided" attribute of a projectile type.
40 */
41 
42 /* ---------- projectile structure */
43 
44 // LP addition:
45 #include "dynamic_limits.h"
46 #include "world.h" // for angle
47 
48 #include <vector>
49 
50 // LP change: made this settable from the resource fork
51 #define MAXIMUM_PROJECTILES_PER_MAP (get_dynamic_limit(_dynamic_limit_projectiles))
52 
53 enum /* projectile types */
54 {
55 	_projectile_rocket,
56 	_projectile_grenade,
57 	_projectile_pistol_bullet,
58 	_projectile_rifle_bullet,
59 	_projectile_shotgun_bullet,
60 	_projectile_staff,
61 	_projectile_staff_bolt,
62 	_projectile_flamethrower_burst,
63 	_projectile_compiler_bolt_minor,
64 	_projectile_compiler_bolt_major,
65 	_projectile_alien_weapon,
66 	_projectile_fusion_bolt_minor,
67 	_projectile_fusion_bolt_major,
68 	_projectile_hunter,
69 	_projectile_fist,
70 	_projectile_armageddon_sphere,
71 	_projectile_armageddon_electricity,
72 	_projectile_juggernaut_rocket,
73 	_projectile_trooper_bullet,
74 	_projectile_trooper_grenade,
75 	_projectile_minor_defender,
76 	_projectile_major_defender,
77 	_projectile_juggernaut_missile,
78 	_projectile_minor_energy_drain,
79 	_projectile_major_energy_drain,
80 	_projectile_oxygen_drain,
81 	_projectile_minor_hummer,
82 	_projectile_major_hummer,
83 	_projectile_durandal_hummer,
84 	_projectile_minor_cyborg_ball,
85 	_projectile_major_cyborg_ball,
86 	_projectile_ball,
87 	_projectile_minor_fusion_dispersal,
88 	_projectile_major_fusion_dispersal,
89 	_projectile_overloaded_fusion_dispersal,
90 	_projectile_yeti,
91 	_projectile_sewage_yeti,
92 	_projectile_lava_yeti,
93 	// LP additions:
94 	_projectile_smg_bullet,
95 	NUMBER_OF_PROJECTILE_TYPES
96 };
97 
98 #define PROJECTILE_HAS_MADE_A_FLYBY(p) ((p)->flags&(uint16)0x4000)
99 #define SET_PROJECTILE_FLYBY_STATUS(p,v) ((void)((v)?((p)->flags|=(uint16)0x4000):((p)->flags&=(uint16)~0x4000)))
100 
101 /* only used for persistent projectiles */
102 #define PROJECTILE_HAS_CAUSED_DAMAGE(p) ((p)->flags&(uint16)0x2000)
103 #define SET_PROJECTILE_DAMAGE_STATUS(p,v) ((void)((v)?((p)->flags|=(uint16)0x2000):((p)->flags&=(uint16)~0x2000)))
104 
105 #define PROJECTILE_HAS_CROSSED_MEDIA_BOUNDARY(p) ((p)->flags&(uint16)0x1000)
106 #define SET_PROJECTILE_CROSSED_MEDIA_BOUNDARY_STATUS(p,v) ((v)?((p)->flags|=(uint16)0x1000):((p)->flags&=(uint16)~0x1000))
107 
108 /* uses SLOT_IS_USED(), SLOT_IS_FREE(), MARK_SLOT_AS_FREE(), MARK_SLOT_AS_USED() macros (0x8000 bit) */
109 
110 struct projectile_data /* 32 bytes */
111 {
112 	short type;
113 
114 	short object_index;
115 
116 	short target_index; /* for guided projectiles, the current target index */
117 
118 	angle elevation; /* facing is stored in the projectile�s object */
119 
120 	short owner_index; /* ownerless if NONE */
121 	short owner_type; /* identical to the monster type which fired this projectile (valid even if owner==NONE) */
122 	uint16 flags; /* [slot_used.1] [played_flyby_sound.1] [has_caused_damage.1] [unused.13] */
123 
124 	/* some projectiles leave n contrails effects every m ticks */
125 	short ticks_since_last_contrail, contrail_count;
126 
127 	world_distance distance_travelled;
128 
129 	world_distance gravity; /* velocity due to gravity for projectiles affected by it */
130 
131 	_fixed damage_scale;
132 
133 	short permutation; /* item type if we create one */
134 
135 	short unused[2];
136 };
137 const int SIZEOF_projectile_data = 32;
138 
139 const int SIZEOF_projectile_definition = 48;
140 
141 
142 enum /* translate_projectile() flags */
143 {
144 	_flyby_of_current_player= 0x0001,
145 	_projectile_hit= 0x0002,
146 	_projectile_hit_monster= 0x0004, // monster_index in *obstruction_index
147 	_projectile_hit_floor= 0x0008, // polygon_index in *obstruction_index
148 	_projectile_hit_media= 0x0010, // polygon_index in *obstruction_index
149 	_projectile_hit_landscape= 0x0020,
150 	_projectile_hit_scenery= 0x0040
151 };
152 
153 /* ---------- globals */
154 
155 // Turned the list of active projectiles into a variable array
156 
157 extern std::vector<projectile_data> ProjectileList;
158 #define projectiles (ProjectileList.data())
159 
160 // extern struct projectile_data *projectiles;
161 
162 /* ---------- prototypes/PROJECTILES.C */
163 
164 bool preflight_projectile(world_point3d *origin, short polygon_index, world_point3d *_vector,
165 	angle delta_theta, short type, short owner, short owner_type, short *target_index);
166 short new_projectile(world_point3d *origin, short polygon_index, world_point3d *_vector,
167 	angle delta_theta, short type, short owner_index, short owner_type, short intended_target_index,
168 	_fixed damage_scale);
169 void detonate_projectile(world_point3d *origin, short polygon_index, short type,
170 	short owner_index, short owner_type, _fixed damage_scale);
171 
172 // LP change: added a location of hitting something;
173 // it may be different from the new location,
174 // as may happen for a "penetrates media boundary" projectile.
175 uint16 translate_projectile(short type, world_point3d *old_location, short old_polygon_index, world_point3d *new_location, short *new_polygon_index, short owner_index, short *obstruction_index, short *last_line_index, bool preflight, short projectile_indexx);
176 
177 void move_projectiles(void); /* assumes �t==1 tick */
178 
179 void remove_projectile(short projectile_index);
180 void remove_all_projectiles(void);
181 
182 void orphan_projectiles(short monster_index);
183 
184 void mark_projectile_collections(short type, bool loading);
185 void load_projectile_sounds(short type);
186 
187 void drop_the_ball(world_point3d *origin, short polygon_index, short owner_index,
188 	short owner_type, short item_type);
189 
190 // Indicates this feature of some type of projectile
191 bool ProjectileIsGuided(short Type);
192 
193 projectile_data *get_projectile_data(
194 	const short projectile_index);
195 
196 // LP: to pack and unpack this data;
197 // these do not make the definitions visible to the outside world
198 
199 uint8 *unpack_projectile_data(uint8 *Stream, projectile_data *Objects, size_t Count);
200 uint8 *pack_projectile_data(uint8 *Stream, projectile_data *Objects, size_t Count);
201 uint8 *unpack_projectile_definition(uint8 *Stream, size_t Count);
202 uint8 *pack_projectile_definition(uint8 *Stream, size_t Count);
203 uint8* unpack_m1_projectile_definition(uint8* Stream, size_t Count);
204 void init_projectile_definitions();
205 
206 #endif
207 
208