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/popup_turret.hh"
|
---|
13 | #include "input.hh"
|
---|
14 | #include "math/pi.hh"
|
---|
15 | #include "math/angle.hh"
|
---|
16 | #include "math/trig.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 "map_man.hh"
|
---|
23 | #include "object_definer.hh"
|
---|
24 | #include "lisp/lisp.hh"
|
---|
25 | #include "objs/fire.hh"
|
---|
26 |
|
---|
27 | enum {DATA_VERSION=1};
|
---|
28 |
|
---|
29 | static g1_model_ref model_ref("popup_housing"),
|
---|
30 | mount_ref("popup_mount"),
|
---|
31 | barrel_ref("popup_barrel");
|
---|
32 |
|
---|
33 | static g1_object_type bullet;
|
---|
34 | static i4_3d_vector turret_attach, mount_offset, barrel_offset;
|
---|
35 |
|
---|
36 | //tunable variables
|
---|
37 | // burst of fire.
|
---|
38 | // rates of turning on, tracking
|
---|
39 | // angle ranges
|
---|
40 | // (weapons? maybe different objects)
|
---|
41 | // entry range to fire
|
---|
42 |
|
---|
43 | const i4_float POPUP_HEIGHT = 0.4;
|
---|
44 | const i4_float POPUP_SPEED = 0.1;
|
---|
45 | const i4_float POPDOWN_SPEED = 0.05;
|
---|
46 | const i4_float POPUP_ROTATESPEED = 0.3;
|
---|
47 |
|
---|
48 | void g1_popup_turret_init()
|
---|
49 | {
|
---|
50 | bullet = g1_get_object_type("bullet");
|
---|
51 |
|
---|
52 | turret_attach.set(0,0,0);
|
---|
53 | model_ref()->get_mount_point("Mount Point", turret_attach);
|
---|
54 |
|
---|
55 | mount_offset.set(0,0,0.15);
|
---|
56 | mount_ref()->get_mount_point("Mount Point", mount_offset);
|
---|
57 | mount_offset.reverse();
|
---|
58 | barrel_offset.set(0,0,0.15);
|
---|
59 | barrel_ref()->get_mount_point("Mount Point", barrel_offset);
|
---|
60 | barrel_offset.reverse();
|
---|
61 | }
|
---|
62 |
|
---|
63 | g1_object_definer<g1_popup_turret_class>
|
---|
64 | g1_popup_turret_def("popup_turret", g1_object_definition_class::EDITOR_SELECTABLE,
|
---|
65 | g1_popup_turret_init);
|
---|
66 |
|
---|
67 | void g1_popup_turret_class::setup(i4_float _x, i4_float _y, g1_object_class *creator)
|
---|
68 | {
|
---|
69 | x = x;
|
---|
70 | y = y;
|
---|
71 | player_num = creator->player_num;
|
---|
72 | occupy_location();
|
---|
73 | request_think();
|
---|
74 | grab_old();
|
---|
75 | }
|
---|
76 |
|
---|
77 | g1_popup_turret_class::g1_popup_turret_class(g1_object_type id,
|
---|
78 | g1_loader_class *fp)
|
---|
79 | : g1_map_piece_class(id,fp)
|
---|
80 | {
|
---|
81 |
|
---|
82 | radar_type=G1_RADAR_BUILDING;
|
---|
83 | set_flag(BLOCKING |
|
---|
84 | SELECTABLE |
|
---|
85 | TARGETABLE |
|
---|
86 | GROUND |
|
---|
87 | HIT_GROUND |
|
---|
88 | HIT_AERIAL |
|
---|
89 | DANGEROUS |
|
---|
90 | SHADOWED, 1);
|
---|
91 |
|
---|
92 | defaults = g1_popup_turret_def.defaults;
|
---|
93 | draw_params.setup(model_ref.id());
|
---|
94 |
|
---|
95 | allocate_mini_objects(2,"popup_turret mini objects");
|
---|
96 |
|
---|
97 | mount = &mini_objects[0];
|
---|
98 | mount->defmodeltype = mount_ref.id();
|
---|
99 | mount->position(turret_attach);
|
---|
100 | mount->rotation.set(0,0,0);
|
---|
101 | mount->offset = mount_offset;
|
---|
102 |
|
---|
103 | barrel = &mini_objects[1];
|
---|
104 | barrel->defmodeltype = barrel_ref.id();
|
---|
105 | barrel->position(turret_attach);
|
---|
106 | barrel->rotation.set(0,i4_pi()/2,0);
|
---|
107 | barrel->offset = barrel_offset;
|
---|
108 |
|
---|
109 | if (fp && fp->check_version(DATA_VERSION))
|
---|
110 | {
|
---|
111 | fp->read_format("f",
|
---|
112 | &mount->rotation.y);
|
---|
113 | barrel->rotation.y = mount->rotation.y;
|
---|
114 | fp->end_version(I4_LF);
|
---|
115 | }
|
---|
116 | else
|
---|
117 | {
|
---|
118 | health = defaults->health;
|
---|
119 | }
|
---|
120 |
|
---|
121 | mount->grab_old();
|
---|
122 | barrel->grab_old();
|
---|
123 | }
|
---|
124 |
|
---|
125 | void g1_popup_turret_class::save(g1_saver_class *fp)
|
---|
126 | {
|
---|
127 | g1_map_piece_class::save(fp);
|
---|
128 |
|
---|
129 | fp->start_version(DATA_VERSION);
|
---|
130 |
|
---|
131 | fp->write_format("f",
|
---|
132 | &mount->rotation.y);
|
---|
133 |
|
---|
134 | fp->end_version();
|
---|
135 | }
|
---|
136 |
|
---|
137 |
|
---|
138 | void g1_popup_turret_class::fire()
|
---|
139 | {
|
---|
140 | fire_delay = defaults->fire_delay;
|
---|
141 |
|
---|
142 | i4_3d_point_class tpos, bpos, bvel;
|
---|
143 |
|
---|
144 | i4_transform_class t, main, l2w;
|
---|
145 | barrel->calc_transform(1.0, &t);
|
---|
146 | calc_world_transform(1.0, &main);
|
---|
147 | l2w.multiply(main, t);
|
---|
148 |
|
---|
149 | main.transform(turret_attach, bpos);
|
---|
150 | l2w.transform_3x3(i4_3d_point_class(1.0, 0, 0), bvel);
|
---|
151 |
|
---|
152 | // spin the barrel
|
---|
153 | barrel->rotation.x += 0.7;
|
---|
154 | i4_normalize_angle(barrel->rotation.x);
|
---|
155 |
|
---|
156 | g1_fire(defaults->fire_type, this, attack_target.get(), bpos, bvel);
|
---|
157 | }
|
---|
158 |
|
---|
159 |
|
---|
160 | void g1_popup_turret_class::think()
|
---|
161 | {
|
---|
162 | find_target();
|
---|
163 |
|
---|
164 | if (health < defaults->health)
|
---|
165 | health++;
|
---|
166 |
|
---|
167 | if (fire_delay>0)
|
---|
168 | fire_delay--;
|
---|
169 |
|
---|
170 | //aim the turet
|
---|
171 | if (attack_target.valid())
|
---|
172 | {
|
---|
173 | request_think();
|
---|
174 |
|
---|
175 | if (h < terrain_height+POPUP_HEIGHT-0.001)
|
---|
176 | {
|
---|
177 | h += POPUP_SPEED;
|
---|
178 | if (h>terrain_height+POPUP_HEIGHT)
|
---|
179 | h = terrain_height+POPUP_HEIGHT;
|
---|
180 | }
|
---|
181 | else
|
---|
182 | {
|
---|
183 | i4_3d_point_class d,pos;
|
---|
184 |
|
---|
185 | lead_target(d);
|
---|
186 |
|
---|
187 | pos.set(x,y,h-POPUP_HEIGHT);
|
---|
188 | d -= pos;
|
---|
189 |
|
---|
190 | //aim the turet
|
---|
191 |
|
---|
192 | i4_float fire_angle,fire_pitch;
|
---|
193 |
|
---|
194 | fire_angle = i4_atan2(d.y,d.x);
|
---|
195 | fire_pitch = i4_atan2(-d.z,sqrt(d.x*d.x+d.y*d.y));
|
---|
196 |
|
---|
197 | i4_normalize_angle(fire_angle);
|
---|
198 | i4_normalize_angle(fire_pitch);
|
---|
199 |
|
---|
200 | int aimed=i4_F;
|
---|
201 | i4_float dangle;
|
---|
202 |
|
---|
203 | dangle = i4_rotate_to(theta,fire_angle,defaults->turn_speed);
|
---|
204 | aimed = (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
|
---|
205 | dangle = i4_rotate_to(mount->rotation.y,fire_pitch,POPUP_ROTATESPEED);
|
---|
206 | aimed &= (dangle<POPUP_ROTATESPEED && dangle>-POPUP_ROTATESPEED);
|
---|
207 | barrel->rotation.y = mount->rotation.y;
|
---|
208 | if (aimed)
|
---|
209 | if (!fire_delay)
|
---|
210 | fire();
|
---|
211 | }
|
---|
212 | }
|
---|
213 | else
|
---|
214 | {
|
---|
215 | request_think(); // move this to draw function
|
---|
216 |
|
---|
217 | int aimed = i4_rotate_to(mount->rotation.y, i4_pi()/2, POPUP_ROTATESPEED)==0.0;
|
---|
218 | barrel->rotation.y = mount->rotation.y;
|
---|
219 |
|
---|
220 | if (aimed && h>terrain_height)
|
---|
221 | {
|
---|
222 | h -= POPDOWN_SPEED;
|
---|
223 | if (h<terrain_height)
|
---|
224 | h = terrain_height;
|
---|
225 | }
|
---|
226 | }
|
---|
227 | }
|
---|