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 "input.hh"
|
---|
13 | #include "math/pi.hh"
|
---|
14 | #include "math/angle.hh"
|
---|
15 | #include "math/trig.hh"
|
---|
16 | #include "g1_rand.hh"
|
---|
17 | #include "resources.hh"
|
---|
18 | #include "saver.hh"
|
---|
19 | #include "map_cell.hh"
|
---|
20 | #include "map.hh"
|
---|
21 | #include "map_man.hh"
|
---|
22 | #include "object_definer.hh"
|
---|
23 | #include "lisp/lisp.hh"
|
---|
24 | #include "objs/fire.hh"
|
---|
25 |
|
---|
26 | #include "sound/sound.hh"
|
---|
27 | #include "objs/map_piece.hh"
|
---|
28 |
|
---|
29 | #include "image_man.hh"
|
---|
30 | #include "player.hh"
|
---|
31 |
|
---|
32 | static g1_team_icon_ref radar_im("bitmaps/radar/tower_missile.tga");
|
---|
33 |
|
---|
34 | enum {DATA_VERSION=1};
|
---|
35 |
|
---|
36 | static g1_model_ref model_ref("tower_missile_base"),
|
---|
37 | launcher_ref("tower_missile_launcher"),
|
---|
38 | bottom_ref("tower_missile_bottom");
|
---|
39 |
|
---|
40 | static i4_3d_vector launcher_attach, launcher_offset, launch;
|
---|
41 |
|
---|
42 | S1_SFX(tower_secured, "narrative/turret_captured_22khz.wav", S1_STREAMED, 200);
|
---|
43 | S1_SFX(tower_lost, "narrative/turret_lost_22khz.wav", S1_STREAMED, 200);
|
---|
44 |
|
---|
45 | void g1_tower_missile_init()
|
---|
46 | {
|
---|
47 | launcher_attach.set(0,0,0);
|
---|
48 | model_ref()->get_mount_point("Mount", launcher_attach);
|
---|
49 |
|
---|
50 | launcher_offset.set(0,0,0);
|
---|
51 | launcher_ref()->get_mount_point("Mount", launcher_offset);
|
---|
52 | launcher_offset.reverse();
|
---|
53 |
|
---|
54 | launch.set(0,1.0,0);
|
---|
55 | launcher_ref()->get_mount_point("Missiles", launch);
|
---|
56 | }
|
---|
57 |
|
---|
58 | class g1_tower_missile_class : public g1_map_piece_class
|
---|
59 | {
|
---|
60 | protected:
|
---|
61 | g1_mini_object *launcher,*bottom;
|
---|
62 | i4_float guard_angle, guard_pitch;
|
---|
63 | int guard_time;
|
---|
64 | int missiles;
|
---|
65 | public:
|
---|
66 | g1_tower_missile_class(g1_object_type id, g1_loader_class *fp)
|
---|
67 | //{{{
|
---|
68 | : g1_map_piece_class(id,fp)
|
---|
69 | {
|
---|
70 | defaults = get_type()->defaults;
|
---|
71 | draw_params.setup(model_ref.id());
|
---|
72 |
|
---|
73 | allocate_mini_objects(2,"tower_missile mini objects");
|
---|
74 |
|
---|
75 | launcher = &mini_objects[0];
|
---|
76 | launcher->defmodeltype = launcher_ref.id();
|
---|
77 | launcher->position(launcher_attach);
|
---|
78 | launcher->offset = launcher_offset;
|
---|
79 | launcher->grab_old();
|
---|
80 |
|
---|
81 | bottom = &mini_objects[1];
|
---|
82 | bottom->defmodeltype = bottom_ref.id();
|
---|
83 | bottom->grab_old();
|
---|
84 |
|
---|
85 | fire_delay = 0;
|
---|
86 | guard_angle = 0;
|
---|
87 | guard_pitch = 0;
|
---|
88 | guard_time = 0;
|
---|
89 | missiles = 6;
|
---|
90 |
|
---|
91 | radar_type=G1_RADAR_BUILDING;
|
---|
92 | radar_image=&radar_im;
|
---|
93 | set_flag(BLOCKING |
|
---|
94 | SELECTABLE |
|
---|
95 | TARGETABLE |
|
---|
96 | GROUND |
|
---|
97 | HIT_GROUND |
|
---|
98 | HIT_AERIAL |
|
---|
99 | DANGEROUS, 1);
|
---|
100 | }
|
---|
101 | //}}}
|
---|
102 |
|
---|
103 | virtual void save(g1_saver_class *fp)
|
---|
104 | //{{{
|
---|
105 | {
|
---|
106 | g1_map_piece_class::save(fp);
|
---|
107 | }
|
---|
108 | //}}}
|
---|
109 |
|
---|
110 | virtual void fire()
|
---|
111 | //{{{
|
---|
112 | {
|
---|
113 | if (missiles==0)
|
---|
114 | return;
|
---|
115 |
|
---|
116 | fire_delay = defaults->fire_delay;
|
---|
117 |
|
---|
118 | missiles--;
|
---|
119 |
|
---|
120 | i4_3d_point_class p, pos, dir;
|
---|
121 |
|
---|
122 | i4_transform_class t, main, l2w;
|
---|
123 | launcher->calc_transform(1.0, &t);
|
---|
124 | calc_world_transform(1.0, &main);
|
---|
125 | l2w.multiply(main, t);
|
---|
126 |
|
---|
127 | static i4_float px[] = { 0, -0.05, +0.05, -0.05, +0.05, 0 };
|
---|
128 | static i4_float py[] = { -0.03, +0.03, +0.03, -0.03, -0.03, +0.03 };
|
---|
129 |
|
---|
130 | p = launch;
|
---|
131 | p.x += px[missiles];
|
---|
132 | p.y += py[missiles];
|
---|
133 |
|
---|
134 | l2w.transform(p,pos);
|
---|
135 | l2w.transform_3x3(i4_3d_point_class(0.4,px[missiles],py[missiles]),dir);
|
---|
136 |
|
---|
137 | g1_fire(defaults->fire_type, this, attack_target.get(), pos, dir);
|
---|
138 | }
|
---|
139 | //}}}
|
---|
140 |
|
---|
141 | virtual void change_player_num(int new_player_num)
|
---|
142 | //{{{
|
---|
143 | {
|
---|
144 | if (new_player_num==g1_player_man.local_player)
|
---|
145 | tower_secured.play();
|
---|
146 |
|
---|
147 | if (player_num==g1_player_man.local_player)
|
---|
148 | tower_lost.play();
|
---|
149 |
|
---|
150 | g1_object_class::change_player_num(new_player_num);
|
---|
151 | if (health<defaults->health)
|
---|
152 | health += defaults->health;
|
---|
153 | set_flag(DANGEROUS,1);
|
---|
154 | request_think();
|
---|
155 | }
|
---|
156 | //}}}
|
---|
157 |
|
---|
158 | virtual void think()
|
---|
159 | //{{{
|
---|
160 | {
|
---|
161 | if (health<=1)
|
---|
162 | return;
|
---|
163 |
|
---|
164 | find_target();
|
---|
165 |
|
---|
166 | if (fire_delay>0)
|
---|
167 | {
|
---|
168 | fire_delay--;
|
---|
169 | if (fire_delay==0)
|
---|
170 | missiles = 6;
|
---|
171 | }
|
---|
172 |
|
---|
173 | pitch = 0;//groundpitch*cos(theta) - groundroll *sin(theta);
|
---|
174 | roll = 0;//groundroll *cos(theta) + groundpitch*sin(theta);
|
---|
175 | h = terrain_height;
|
---|
176 |
|
---|
177 | //aim the turet
|
---|
178 | if (attack_target.valid())
|
---|
179 | {
|
---|
180 | request_think();
|
---|
181 |
|
---|
182 | i4_3d_point_class d,pos;
|
---|
183 |
|
---|
184 | lead_target(d);
|
---|
185 |
|
---|
186 | pos.set(x,y,h+launcher_attach.z);
|
---|
187 | d -= pos;
|
---|
188 |
|
---|
189 | //aim the turet
|
---|
190 |
|
---|
191 | guard_angle = i4_atan2(d.y,d.x);
|
---|
192 | guard_pitch = i4_atan2(-d.z,sqrt(d.x*d.x+d.y*d.y));
|
---|
193 |
|
---|
194 | i4_normalize_angle(guard_angle);
|
---|
195 | i4_normalize_angle(guard_pitch);
|
---|
196 |
|
---|
197 | int aimed=i4_F;
|
---|
198 | i4_float dangle;
|
---|
199 |
|
---|
200 | dangle = i4_rotate_to(theta,guard_angle,defaults->turn_speed);
|
---|
201 | aimed = (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
|
---|
202 | bottom->rotation.z = -theta;
|
---|
203 | dangle = i4_rotate_to(launcher->rotation.y,guard_pitch,defaults->turn_speed);
|
---|
204 | aimed &= (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
|
---|
205 | if (aimed)
|
---|
206 | fire();
|
---|
207 | guard_time = 30;
|
---|
208 | }
|
---|
209 | else
|
---|
210 | {
|
---|
211 | request_think(); // move this to draw function
|
---|
212 |
|
---|
213 | if (guard_time<=0)
|
---|
214 | {
|
---|
215 | guard_angle = g1_float_rand(1)*i4_2pi();
|
---|
216 | guard_pitch = (-g1_float_rand(2)*0.5 + 0.25)*i4_pi();
|
---|
217 | i4_normalize_angle(guard_pitch);
|
---|
218 | guard_time = 20;
|
---|
219 | }
|
---|
220 |
|
---|
221 | int aimed;
|
---|
222 |
|
---|
223 | aimed = (i4_rotate_to(theta,guard_angle,defaults->turn_speed)==0.0);
|
---|
224 | bottom->rotation.z = -theta;
|
---|
225 | aimed &= (i4_rotate_to(launcher->rotation.y,guard_pitch,defaults->turn_speed)==0.0);
|
---|
226 | if (aimed)
|
---|
227 | if (guard_time>0)
|
---|
228 | guard_time--;
|
---|
229 | }
|
---|
230 | }
|
---|
231 | //}}}
|
---|
232 |
|
---|
233 | virtual i4_bool check_collision(const i4_3d_vector &start, i4_3d_vector &ray)
|
---|
234 | //{{{
|
---|
235 | {
|
---|
236 | i4_3d_vector normal;
|
---|
237 | return g1_model_collide_polygonal(this, draw_params, start, ray, normal);
|
---|
238 | }
|
---|
239 | //}}}
|
---|
240 |
|
---|
241 | virtual void damage(g1_object_class *obj, int hp, i4_3d_vector _damage_dir)
|
---|
242 | //{{{
|
---|
243 | {
|
---|
244 | health -= hp;
|
---|
245 | if (health<1)
|
---|
246 | {
|
---|
247 | health=1;
|
---|
248 | set_flag(DANGEROUS,0);
|
---|
249 | }
|
---|
250 | request_think();
|
---|
251 | }
|
---|
252 | //}}}
|
---|
253 | };
|
---|
254 |
|
---|
255 | g1_object_definer<g1_tower_missile_class>
|
---|
256 | g1_tower_missile_def("tower_missile", g1_object_definition_class::EDITOR_SELECTABLE,
|
---|
257 | g1_tower_missile_init);
|
---|
258 |
|
---|
259 | //{{{ Emacs Locals
|
---|
260 | // Local Variables:
|
---|
261 | // folded-file: t
|
---|
262 | // End:
|
---|
263 | //}}}
|
---|