source: golgotha/src/golg/objs/tower_missile.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 12 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: 6.7 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 "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
32static g1_team_icon_ref radar_im("bitmaps/radar/tower_missile.tga");
33
34enum {DATA_VERSION=1};
35 
36static g1_model_ref model_ref("tower_missile_base"),
37  launcher_ref("tower_missile_launcher"),
38  bottom_ref("tower_missile_bottom");
39
40static i4_3d_vector launcher_attach, launcher_offset, launch;
41
42S1_SFX(tower_secured, "narrative/turret_captured_22khz.wav", S1_STREAMED, 200);
43S1_SFX(tower_lost, "narrative/turret_lost_22khz.wav", S1_STREAMED, 200);
44
45void 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
58class g1_tower_missile_class : public g1_map_piece_class
59{
60protected:
61  g1_mini_object        *launcher,*bottom;
62  i4_float guard_angle, guard_pitch;
63  int guard_time;
64  int missiles;
65public:
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
255g1_object_definer<g1_tower_missile_class>
256g1_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//}}}
Note: See TracBrowser for help on using the repository browser.