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

Last change on this file since 80 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: 6.6 KB
RevLine 
[80]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
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 "map_man.hh"
23#include "sfx_id.hh"
24#include "objs/bomber.hh"
25#include "objs/fire.hh"
26#include "object_definer.hh"
27#include "objs/path_object.hh"
28
29#include "image_man.hh"
30static g1_team_icon_ref radar_im("bitmaps/radar/plane.tga");
31
32enum { DATA_VERSION=1 };
33
34enum
35{
36  TAKE_OFF=0,
37  FLYING,
38  DYING
39};
40
41const i4_float FLY_HEIGHT=1.5;
42
43void g1_bomber_init()
44//{{{
45{
46}
47//}}}
48
49g1_object_definer<g1_bomber_class>
50g1_bomber_def("bomber",
51              g1_object_definition_class::TO_MAP_PIECE |
52              g1_object_definition_class::EDITOR_SELECTABLE |
53              g1_object_definition_class::MOVABLE,
54              g1_bomber_init);
55
56
57g1_bomber_class::g1_bomber_class(g1_object_type id,
58                           g1_loader_class *fp)
59  : g1_map_piece_class(id, fp)
60//{{{
61
62  draw_params.setup("bomber","bomber_shadow", "bomber_lod");
63
64  damping_fraction = 0.02;
65
66  radar_type=G1_RADAR_VEHICLE;
67  radar_image=&radar_im;
68  set_flag(BLOCKING      |
69           TARGETABLE    |
70           AERIAL        |
71           HIT_GROUND    |
72           DANGEROUS,1);
73
74  w16 ver,data_size;
75  if (fp)
76    fp->get_version(ver,data_size);
77  else
78    ver =0;
79  switch (ver)
80  {
81    case DATA_VERSION:
82      fp->read_format("1f4",
83                      &mode,
84                      &vspeed,
85                      &sway);
86      break;
87    default:
88      if (fp) fp->seek(fp->tell() + data_size);
89      mode = 0;
90      vspeed = 0;
91      sway = 0;
92      break;
93  }
94     
95  if (fp)
96    fp->end_version(I4_LF);
97}
98//}}}
99   
100void g1_bomber_class::save(g1_saver_class *fp)
101//{{{
102{
103  g1_map_piece_class::save(fp);
104
105  fp->start_version(DATA_VERSION);
106 
107  fp->write_format("1f4",
108                   &mode,
109                   &vspeed,
110                   &sway);
111 
112  fp->end_version();
113}
114//}}}
115
116void g1_bomber_class::fire()
117//{{{
118{
119  fire_delay = g1_bomber_def.defaults->fire_delay;
120 
121  i4_3d_vector pos(x,y,h);
122
123  pos.x += g1_float_rand(3)*0.4-0.2;
124  pos.y += g1_float_rand(2)*0.4-0.2;
125
126  g1_fire(defaults->fire_type,
127          this, attack_target.get(), pos,
128          i4_3d_vector(x-lx,y-ly,h-lh));         
129}
130//}}}
131
132i4_bool g1_bomber_class::move(i4_float x_amount, i4_float y_amount)
133//{{{
134{
135  i4_float
136    newx = x+x_amount,
137    newy = y+y_amount;
138
139  unoccupy_location();
140  if (newx>0 && newx<g1_get_map()->width() && newy>0 && newy<g1_get_map()->height())
141  {
142    x = newx;
143    y = newy;
144
145    if (occupy_location())
146      return i4_T;
147  }
148  request_remove();
149  return i4_F;
150}
151//}}}
152
153void g1_bomber_class::think()
154//{{{
155{
156  if (!check_life())
157    return;
158
159  find_target();
160
161  if (fire_delay>0)
162    fire_delay--;
163
164  h += vspeed;
165       
166  switch (mode)
167  {
168    case TAKE_OFF:
169    {
170      if (next_path.valid())
171      {
172        dest_x = next_path->x - path_cos*path_len;
173        dest_y = next_path->y - path_sin*path_len;
174        dest_z = next_path->h - path_tan_phi*path_len;
175      }
176
177      //then raise the bomber
178      i4_float dist_to_go = dest_z - h;
179      if (dist_to_go>0.05)
180      {
181        //if he is more than halfway away, accelerate down
182        //otherwise accelerate up       
183        if (dist_to_go > (FLY_HEIGHT * 0.5))
184          vspeed = (vspeed<0.05) ? vspeed+0.005 : vspeed;
185      }
186      else
187      {
188        //lock these in case there were any small errors
189        h = dest_z;
190        vspeed = 0;
191       
192        //think one more time so the l* variables catch up
193        //(otherwise he'll bob up and down)
194        if (h == lh)
195          mode = FLYING;
196      }
197    } break;
198
199    case FLYING:
200    {
201      i4_3d_vector d;
202      i4_float angle,t;
203
204      // sway over terrain
205      sway++;
206
207      if (attack_target.valid())
208        if (fire_delay==0)
209          fire();
210
211      i4_float roll_to  = 0.02*sin(i4_pi()*sway/17.0);
212      i4_float pitch_to = 0.02*sin(i4_pi()*sway/13.0);
213     
214      if (next_path.valid())
215      {
216        dest_x = next_path->x;
217        dest_y = next_path->y;
218        dest_z = next_path->h;
219      }
220
221      i4_float dist, dtheta;
222      suggest_air_move(dist, dtheta, d);
223      move(d.x,d.y);
224      h += d.z + 0.02*sin(i4_pi()*sway/15.0);
225     
226      if (dist<speed)
227        advance_path();
228     
229      i4_normalize_angle(roll_to);
230     
231      if (speed>0.001 || dtheta!=0.0)
232      {
233        roll_to = -i4_pi()/4 * dtheta;
234        pitch_to = -i4_pi()/8 * speed;
235      }
236
237      i4_rotate_to(roll,roll_to,defaults->turn_speed/4); 
238      i4_rotate_to(pitch,pitch_to,defaults->turn_speed/4); 
239     
240      groundpitch = 0; //no ground in the air (duh)
241      groundroll  = 0;
242    } break;
243
244    case DYING:
245    {
246      i4_float &roll_speed  = dest_x;
247      i4_float &pitch_speed = dest_y;
248     
249      pitch_speed += 0.004;
250      pitch += pitch_speed;
251
252      roll_speed += 0.01;
253      roll += roll_speed;
254
255      vspeed -= (g1_resources.gravity * 0.1);
256
257      i4_float dx,dy;
258      dx = speed*cos(theta);
259      dy = speed*sin(theta);
260      move(dx,dy);
261
262      if (h<=terrain_height)
263        g1_map_piece_class::damage(0,health,i4_3d_vector(0,0,1));               // die somehow!!!
264    } break;
265  }
266
267  // have to keep thinking to sway
268  request_think(); 
269}
270//}}}
271
272void g1_bomber_class::damage(g1_object_class *obj, int hp, i4_3d_vector _damage_dir)
273//{{{
274{
275  //we dont want to explode if ppl shoot us while we're dying.. we want to
276  //smash into the ground and create a nice explosion
277  if (mode != DYING)
278  {
279    if (health<20)
280    {
281      i4_float &roll_speed  = dest_x;
282      i4_float &pitch_speed = dest_y;
283     
284      roll_speed  = 0;
285      pitch_speed = 0;
286      health = 20;
287      set_flag(DANGEROUS,0);
288      mode = DYING;
289    }
290    g1_map_piece_class::damage(obj,hp,_damage_dir); 
291  }
292}
293//}}}
294
295//{{{ Emacs Locals
296// Local Variables:
297// folded-file: t
298// End:
299//}}}
Note: See TracBrowser for help on using the repository browser.