1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "sound_man.hh"
|
---|
10 | #include "objs/model_id.hh"
|
---|
11 | #include "objs/model_draw.hh"
|
---|
12 | #include "objs/rocktank.hh"
|
---|
13 | #include "input.hh"
|
---|
14 | #include "math/pi.hh"
|
---|
15 | #include "math/trig.hh"
|
---|
16 | #include "math/angle.hh"
|
---|
17 | #include "g1_rand.hh"
|
---|
18 | #include "resources.hh"
|
---|
19 | #include "saver.hh"
|
---|
20 | #include "map_cell.hh"
|
---|
21 | #include "map.hh"
|
---|
22 | #include "objs/vehic_sounds.hh"
|
---|
23 | #include "sound/sfx_id.hh"
|
---|
24 | #include "object_definer.hh"
|
---|
25 | #include "objs/fire.hh"
|
---|
26 |
|
---|
27 |
|
---|
28 | S1_SFX(rumble, "rumble/missile_truck_lp.wav", S1_3D, 1);
|
---|
29 | S1_SFX(raising, "misc/missile_truck_raise.wav", S1_3D, 5);
|
---|
30 | S1_SFX(lowering, "misc/missile_truck_lower.wav", S1_3D, 5);
|
---|
31 |
|
---|
32 |
|
---|
33 | enum { DATA_VERSION=1 };
|
---|
34 |
|
---|
35 | enum eRackState
|
---|
36 | {
|
---|
37 | LOWERED,
|
---|
38 | RAISE,
|
---|
39 | RAISING,
|
---|
40 | RAISED,
|
---|
41 | LOWER,
|
---|
42 | LOWERING,
|
---|
43 | };
|
---|
44 |
|
---|
45 | static g1_model_ref model_ref("rocket_truck"),
|
---|
46 | shadow_ref("rocket_truck_shadow"),
|
---|
47 | rack_ref("rocket_truck_top"),
|
---|
48 | base_lod("rocket_truck_lod"),
|
---|
49 | top_lod("rocket_truck_top_lod");
|
---|
50 |
|
---|
51 |
|
---|
52 | static i4_3d_vector rack_attach, rack_offset;
|
---|
53 |
|
---|
54 | static void g1_rocket_tank_init()
|
---|
55 | {
|
---|
56 | rack_attach.set(0,0,0);
|
---|
57 | model_ref()->get_mount_point("Rack", rack_attach);
|
---|
58 | rack_offset.set(0,0,0);
|
---|
59 | rack_ref()->get_mount_point("Rack", rack_offset);
|
---|
60 | rack_offset.reverse();
|
---|
61 | }
|
---|
62 |
|
---|
63 | g1_object_definer<g1_rocket_tank_class>
|
---|
64 | g1_rocket_tank_def("rocket_tank",
|
---|
65 | g1_object_definition_class::TO_MAP_PIECE |
|
---|
66 | g1_object_definition_class::MOVABLE |
|
---|
67 | g1_object_definition_class::EDITOR_SELECTABLE,
|
---|
68 | g1_rocket_tank_init);
|
---|
69 |
|
---|
70 | static char *chunk_list[3]={"chunk_missiletruck_body", "chunk_missiletruck_launcher",
|
---|
71 | "chunk_missiletruck_tread"};
|
---|
72 |
|
---|
73 |
|
---|
74 | int g1_rocket_tank_class::get_chunk_names(char **&list) { list=chunk_list; return 3; }
|
---|
75 |
|
---|
76 | g1_rocket_tank_class::g1_rocket_tank_class(g1_object_type id,
|
---|
77 | g1_loader_class *fp)
|
---|
78 | : g1_map_piece_class(id, fp)
|
---|
79 | {
|
---|
80 | draw_params.setup(model_ref.id(), shadow_ref.id(), base_lod.id());
|
---|
81 |
|
---|
82 | allocate_mini_objects(2,"Rocket Tank Mini-objects");
|
---|
83 |
|
---|
84 | missile_rack = &mini_objects[0];
|
---|
85 | missile_rack->defmodeltype = rack_ref.id();
|
---|
86 | missile_rack->lod_model = top_lod.id();
|
---|
87 |
|
---|
88 |
|
---|
89 | missile_rack->position(rack_attach);
|
---|
90 | missile_rack->offset = rack_offset;
|
---|
91 |
|
---|
92 | w16 ver,data_size;
|
---|
93 | if (fp)
|
---|
94 | {
|
---|
95 | fp->get_version(ver,data_size);
|
---|
96 | switch (ver)
|
---|
97 | {
|
---|
98 | case DATA_VERSION:
|
---|
99 | fp->read_8();
|
---|
100 | fp->read_format("fff",
|
---|
101 | &missile_rack->rotation.x,
|
---|
102 | &missile_rack->rotation.y,
|
---|
103 | &missile_rack->rotation.z);
|
---|
104 |
|
---|
105 | missile_rack->grab_old();
|
---|
106 | break;
|
---|
107 | case 0:
|
---|
108 | fp->read_8();
|
---|
109 | fp->read_8();
|
---|
110 | fp->read_8();
|
---|
111 | fp->read_8();
|
---|
112 |
|
---|
113 | fp->read_16();
|
---|
114 |
|
---|
115 | missile_rack->rotation.x = fp->read_float();
|
---|
116 | missile_rack->rotation.y = fp->read_float();
|
---|
117 | missile_rack->rotation.z = fp->read_float();
|
---|
118 |
|
---|
119 | missile_rack->lrotation.x = fp->read_float();
|
---|
120 | missile_rack->lrotation.y = fp->read_float();
|
---|
121 | missile_rack->lrotation.z = fp->read_float();
|
---|
122 | break;
|
---|
123 | default:
|
---|
124 | fp->seek(fp->tell() + data_size);
|
---|
125 | missile_rack->rotation.x = 0;
|
---|
126 | missile_rack->rotation.y = 0;
|
---|
127 | missile_rack->rotation.z = 0;
|
---|
128 | missile_rack->lrotation = missile_rack->rotation;
|
---|
129 | fire_delay = 15;
|
---|
130 | break;
|
---|
131 | }
|
---|
132 | fp->end_version(I4_LF);
|
---|
133 | }
|
---|
134 | else
|
---|
135 | {
|
---|
136 | missile_rack->rotation.x = 0;
|
---|
137 | missile_rack->rotation.y = 0;
|
---|
138 | missile_rack->rotation.z = 0;
|
---|
139 | missile_rack->lrotation = missile_rack->rotation;
|
---|
140 | fire_delay = 15;
|
---|
141 | }
|
---|
142 |
|
---|
143 | init_rumble_sound(G1_RUMBLE_GROUND);
|
---|
144 |
|
---|
145 | guard_angle = 0;
|
---|
146 | guard_pitch = 0;
|
---|
147 | guard_time = 0;
|
---|
148 |
|
---|
149 | radar_type=G1_RADAR_VEHICLE;
|
---|
150 | set_flag(BLOCKING |
|
---|
151 | SELECTABLE |
|
---|
152 | TARGETABLE |
|
---|
153 | GROUND |
|
---|
154 | HIT_AERIAL |
|
---|
155 | HIT_GROUND |
|
---|
156 | DANGEROUS, 1);
|
---|
157 | }
|
---|
158 |
|
---|
159 | void g1_rocket_tank_class::save(g1_saver_class *fp)
|
---|
160 | {
|
---|
161 | g1_map_piece_class::save(fp);
|
---|
162 |
|
---|
163 | fp->start_version(DATA_VERSION);
|
---|
164 |
|
---|
165 | fp->write_8(0);
|
---|
166 | fp->write_format("fff",
|
---|
167 | &missile_rack->rotation.x,
|
---|
168 | &missile_rack->rotation.y,
|
---|
169 | &missile_rack->rotation.z);
|
---|
170 |
|
---|
171 | fp->end_version();
|
---|
172 | }
|
---|
173 |
|
---|
174 |
|
---|
175 | void g1_rocket_tank_class::fire()
|
---|
176 | {
|
---|
177 | g1_object_class *target=attack_target.get();
|
---|
178 | if (target)
|
---|
179 | {
|
---|
180 | i4_float bx,by,bz;
|
---|
181 |
|
---|
182 | i4_3d_vector pos, dir;
|
---|
183 |
|
---|
184 | i4_transform_class btrans,tmp1;
|
---|
185 |
|
---|
186 | btrans.translate(x,y,h);
|
---|
187 |
|
---|
188 | tmp1.rotate_x(groundroll);
|
---|
189 | btrans.multiply(tmp1);
|
---|
190 |
|
---|
191 | tmp1.rotate_y(groundpitch);
|
---|
192 | btrans.multiply(tmp1);
|
---|
193 |
|
---|
194 | tmp1.rotate_z(theta);
|
---|
195 | btrans.multiply(tmp1);
|
---|
196 |
|
---|
197 | tmp1.translate(missile_rack->x, missile_rack->y, missile_rack->h);
|
---|
198 | btrans.multiply(tmp1);
|
---|
199 |
|
---|
200 | tmp1.rotate_z(missile_rack->rotation.z);
|
---|
201 | btrans.multiply(tmp1);
|
---|
202 |
|
---|
203 | tmp1.rotate_y(missile_rack->rotation.y);
|
---|
204 | btrans.multiply(tmp1);
|
---|
205 |
|
---|
206 | btrans.transform(i4_3d_vector(0.1, 0, 0), pos);
|
---|
207 | btrans.transform(i4_3d_vector(1.0, 0, 0), dir);
|
---|
208 | dir-=pos;
|
---|
209 |
|
---|
210 | g1_fire(defaults->fire_type, this, target, pos, dir);
|
---|
211 | fire_delay = defaults->fire_delay;
|
---|
212 | }
|
---|
213 | }
|
---|
214 |
|
---|
215 | void g1_rocket_tank_class::think()
|
---|
216 | {
|
---|
217 | g1_map_piece_class::think();
|
---|
218 |
|
---|
219 | if (!alive())
|
---|
220 | return;
|
---|
221 |
|
---|
222 | //aim the missile rack
|
---|
223 | if (attack_target.valid())
|
---|
224 | {
|
---|
225 | request_think();
|
---|
226 |
|
---|
227 | i4_float dx,dy,dangle;
|
---|
228 |
|
---|
229 | //this will obviously only be true if attack_target.ref != NULL
|
---|
230 | dx = ((x+missile_rack->x) - attack_target->x);
|
---|
231 | dy = ((y+missile_rack->y) - attack_target->y);
|
---|
232 |
|
---|
233 | //aim the vehicle
|
---|
234 | guard_angle = i4_atan2(dy,dx) + i4_pi() - theta;
|
---|
235 | i4_normalize_angle(guard_angle);
|
---|
236 |
|
---|
237 | i4_float dist = dx*dx+dy*dy;
|
---|
238 | if (dist>25.0)
|
---|
239 | guard_pitch = -i4_pi()/8;
|
---|
240 | else if (dist>9.0)
|
---|
241 | guard_pitch = -(dist - 9.0)*i4_pi()/8/(25.0-9.0);
|
---|
242 | else
|
---|
243 | guard_pitch = 0;
|
---|
244 | i4_normalize_angle(guard_pitch);
|
---|
245 |
|
---|
246 | i4_bool aimed = i4_F;
|
---|
247 |
|
---|
248 | dangle = i4_rotate_to(missile_rack->rotation.z, guard_angle, 0.1);
|
---|
249 | aimed = (dangle<0.1 && dangle>-0.1);
|
---|
250 | dangle = i4_rotate_to(missile_rack->rotation.y, guard_pitch, 0.1);
|
---|
251 | aimed &= (dangle<0.1 && dangle>-0.1);
|
---|
252 |
|
---|
253 | if (aimed && !fire_delay)
|
---|
254 | fire();
|
---|
255 |
|
---|
256 | guard_time = 40;
|
---|
257 | }
|
---|
258 | else
|
---|
259 | {
|
---|
260 | guard_pitch = 0;
|
---|
261 | guard_angle = 0;
|
---|
262 |
|
---|
263 | request_think(); // move this to draw function
|
---|
264 |
|
---|
265 | i4_rotate_to(missile_rack->rotation.z, guard_angle, 0.1);
|
---|
266 | i4_rotate_to(missile_rack->rotation.y, guard_pitch, 0.1);
|
---|
267 | }
|
---|
268 | }
|
---|
269 |
|
---|