source: golgotha/src/golg/objs/tower_electric.cc

Last change on this file was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 8.4 KB
Line 
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 "saver.hh"
18#include "map_cell.hh"
19#include "map.hh"
20#include "map_man.hh"
21#include "sfx_id.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#include "objs/bolt.hh"
29#include "sound/sfx_id.hh"
30#include "image_man.hh"
31#include "objs/light_o.hh"
32#include "player.hh"
33
34static g1_team_icon_ref radar_im("bitmaps/radar/tower_electric.tga");
35
36enum {DATA_VERSION=1};
37
38#define SPIN_ACCEL 0.02
39#define ATTACK_SPIN 0.8
40 
41static li_symbol_ref bolt_obj("bolt");
42
43static g1_model_ref model_ref("tower_electric_base"),
44  pod_ref("tower_electric_pod"), prod_ref("tower_electric_fingers"),
45  bottom_ref("tower_electric_bottom");
46
47static i4_3d_vector pod_attach, pod_offset, prod_offset, electric[4];
48
49S1_SFX(charge_sfx, "fire/electric_tower_charge_up_22khz.wav", S1_STREAMED | S1_3D, 70);
50S1_SFX(shutdown_sfx, "fire/electric_tower_power_down_22khz.wav", S1_STREAMED | S1_3D, 70);
51S1_SFX(tower_secured, "narrative/turret_captured_22khz.wav", S1_STREAMED, 200);
52S1_SFX(tower_lost, "narrative/turret_lost_22khz.wav", S1_STREAMED, 200);
53
54void g1_tower_electric_init()
55{
56  pod_attach.set(0,0,0);
57  model_ref()->get_mount_point("Axle", pod_attach);
58
59  pod_offset.set(0,0,0);
60  pod_ref()->get_mount_point("Axle", pod_offset);
61  pod_offset.reverse();
62
63  prod_offset.set(0,0,0);
64  prod_ref()->get_mount_point("Axle", prod_offset);
65  prod_offset.reverse();
66
67  prod_ref()->get_mount_point("Electric1", electric[0]);
68  prod_ref()->get_mount_point("Electric2", electric[1]);
69  prod_ref()->get_mount_point("Electric3", electric[2]);
70  prod_ref()->get_mount_point("Electric4", electric[3]);
71}
72
73class g1_tower_electric_class : public g1_map_piece_class
74{
75protected:
76  g1_mini_object        *pod, *prod, *bottom;
77  i4_float guard_angle, guard_pitch;
78  g1_typed_reference_class<g1_bolt_class> bolt[4];
79
80  i4_float spin_vel;
81  int charge;
82  int guard_time;
83public:
84  g1_tower_electric_class(g1_object_type id, g1_loader_class *fp)
85  //{{{
86    : g1_map_piece_class(id,fp)
87  {
88    defaults = get_type()->defaults;
89    draw_params.setup(model_ref.id());
90   
91    allocate_mini_objects(3,"tower_electric mini objects");
92
93    pod = &mini_objects[0];
94    pod->defmodeltype = pod_ref.id();
95    pod->position(pod_attach);
96    pod->offset = pod_offset;
97    pod->grab_old();
98 
99    prod = &mini_objects[1];
100    prod->defmodeltype = prod_ref.id();
101    prod->position(pod_attach);
102    prod->offset = prod_offset;
103    prod->grab_old();
104
105    bottom = &mini_objects[2];
106    bottom->defmodeltype = bottom_ref.id();
107    bottom->grab_old();
108
109    fire_delay = 0;
110    guard_angle = 0;
111    guard_pitch = 0;
112    guard_time = 0;
113    charge = 20;
114    spin_vel = 0;
115
116    grab_old();
117
118    radar_type=G1_RADAR_BUILDING;
119    radar_image=&radar_im;
120
121    set_flag(BLOCKING      |
122             SELECTABLE    |
123             TARGETABLE    |
124             GROUND        |
125             HIT_GROUND    |
126             HIT_AERIAL    |
127             DANGEROUS, 1);
128  }
129  //}}}
130
131  virtual void save(g1_saver_class *fp)
132  //{{{
133  {
134    g1_map_piece_class::save(fp);
135  }
136  //}}}
137
138  virtual void fire()
139  //{{{
140  {
141    if (spin_vel<ATTACK_SPIN)
142      return;
143
144    i4_3d_point_class pos, spot;
145    i4_transform_class t, main, l2w;
146    prod->calc_transform(1.0, &t);   
147    calc_world_transform(1.0, &main);
148    l2w.multiply(main, t);
149
150    pos = electric[3];
151
152    if (charge>0)
153    {
154      pos.x += 0.5;
155      l2w.transform(pos, spot);
156
157      if (!bolt[3].valid())
158        bolt[3] = (g1_bolt_class *)g1_create_object(g1_get_object_type(bolt_obj.get()));
159     
160      if (bolt[3].valid())
161      {
162        bolt[3]->setup_look(0.8, 0.05, 0.05, 0xff88ff, 0x8800ff, 1.0, 1.0, i4_T);
163        bolt[3]->setup(spot, i4_3d_point_class(0,0,0),this,attack_target.get());
164      }
165    }
166    else
167      l2w.transform(pos, spot);
168
169    for (int i=0; i<3; i++)
170    {
171      l2w.transform(electric[i], pos);
172     
173      if (!bolt[i].valid())
174        bolt[i] = (g1_bolt_class *)g1_create_object(g1_get_object_type(bolt_obj.get()));
175
176      if (bolt[i].valid())
177      {
178        bolt[i]->setup_look(0.2, 0.02, (charge>0)? 0.05:0.02, 0xffffff, 0xff88ff);
179        bolt[i]->setup(pos, spot, this,0);
180      }
181    }
182
183    if (charge>0)
184    {
185      fire_delay = defaults->fire_delay;
186      charge--;
187    }
188  }
189  //}}}
190
191  virtual void change_player_num(int new_player_num)
192  //{{{
193  {
194    if (new_player_num==g1_player_man.local_player)
195      tower_secured.play();
196     
197    if (player_num==g1_player_man.local_player)
198      tower_lost.play();
199
200    g1_object_class::change_player_num(new_player_num);
201    if (health<defaults->health)
202      health += defaults->health;
203    set_flag(DANGEROUS,1);
204    request_think();
205  }
206  //}}}
207
208  virtual void think()
209  //{{{
210  {
211    if (health<=1)
212      return;
213
214    find_target();
215   
216    if (fire_delay>0)
217    {
218      fire_delay--;
219      if (fire_delay==0)
220        charge = 20;
221    }
222   
223    pitch = 0;//groundpitch*cos(theta) - groundroll *sin(theta);
224    roll  = 0;//groundroll *cos(theta) + groundpitch*sin(theta);
225    h = terrain_height;
226
227    prod->rotation.x += spin_vel;
228 
229    //aim the turet
230    if (attack_target.valid())
231    {
232      request_think();
233     
234      i4_3d_point_class d,pos;
235
236      lead_target(d);
237
238      pos.set(x,y,h+pod_attach.z);
239      d -= pos;
240
241      //aim the turet
242   
243      guard_angle = i4_atan2(d.y,d.x);
244      guard_pitch = i4_atan2(-d.z,sqrt(d.x*d.x+d.y*d.y));
245   
246      i4_normalize_angle(guard_angle);
247      i4_normalize_angle(guard_pitch);
248
249      int aimed=i4_F;
250      i4_float dangle;
251
252      dangle = i4_rotate_to(theta,guard_angle,defaults->turn_speed);
253      aimed = (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
254      bottom->rotation.z = -theta;
255      dangle = i4_rotate_to(pod->rotation.y,guard_pitch,defaults->turn_speed);
256      aimed &= (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
257      prod->rotation.y = pod->rotation.y;
258     
259      if (aimed)
260        fire();
261
262      guard_time = 30;
263
264      if (spin_vel<ATTACK_SPIN)
265      {
266        if (spin_vel==0)
267          charge_sfx.play(x,y,h);
268
269        spin_vel += SPIN_ACCEL;
270      }
271    }
272    else
273    {
274      request_think();            // move this to draw function
275
276      if (guard_time<=0)
277      {
278        guard_angle = g1_float_rand(2)*i4_2pi();
279        guard_pitch = -g1_float_rand(3)*i4_pi()*0.45;
280        i4_normalize_angle(guard_pitch);
281        guard_time = 20;
282      }
283
284      int aimed;
285
286      aimed = (i4_rotate_to(theta,guard_angle,defaults->turn_speed)==0.0);
287      bottom->rotation.z = -theta;
288      aimed &= (i4_rotate_to(pod->rotation.y,guard_pitch,defaults->turn_speed)==0.0);
289      prod->rotation.y = pod->rotation.y;
290      if (aimed)
291        if (guard_time>0)
292          guard_time--;
293
294      if (spin_vel>0)
295        spin_vel -= SPIN_ACCEL;
296      else
297        spin_vel = 0;
298    }
299  }
300  //}}}
301
302  virtual void damage(g1_object_class *obj, int hp, i4_3d_vector _damage_dir)
303  //{{{
304  {
305    if (health>1)
306    {
307      health -= hp;
308      if (health<=1)
309      {
310        health=1;
311        set_flag(DANGEROUS,0);
312        shutdown_sfx.play(x,y,h);
313      }
314    }
315
316    request_think();
317  }
318  //}}}
319
320  virtual i4_bool check_collision(const i4_3d_vector &start, i4_3d_vector &ray)
321  //{{{
322  {
323    return g1_model_collide_radial(this, draw_params, start, ray);
324  }
325  //}}}
326};
327
328g1_object_definer<g1_tower_electric_class>
329g1_tower_electric_def("tower_electric", g1_object_definition_class::EDITOR_SELECTABLE,
330                     g1_tower_electric_init);
331
332//{{{ Emacs Locals
333// Local Variables:
334// folded-file: t
335// End:
336//}}}
Note: See TracBrowser for help on using the repository browser.