source: golgotha/src/golg/objs/rocket.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: 6.5 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 "g1_object.hh"
10#include "objs/model_draw.hh"
11#include "math/num_type.hh"
12#include "objs/rocket.hh"
13#include "tile.hh"
14#include "objs/explosion1.hh"
15#include "saver.hh"
16#include "objs/fire_angle.hh"
17#include "math/pi.hh"
18#include "objs/map_piece.hh"
19#include "map.hh"
20#include "map_man.hh"
21#include "math/angle.hh"
22#include "math/trig.hh"
23#include "image/image.hh"
24#include "objs/smoke_trail.hh"
25#include "object_definer.hh"
26#include "g1_render.hh"
27#include "g1_rand.hh"
28
29static g1_object_type shrapnel_type, explosion_type, smoke_trail_type;
30void g1_rocket_init()
31{
32  shrapnel_type = g1_get_object_type("shrapnel");
33  explosion_type = g1_get_object_type("explosion1");
34  smoke_trail_type = g1_get_object_type("smoke_trail");
35}
36
37g1_object_definer<g1_rocket_class>
38g1_rocket_def("rocket",
39              g1_object_definition_class::MOVABLE,
40              g1_rocket_init);
41
42g1_rocket_class::g1_rocket_class(g1_object_type id,
43                                 g1_loader_class *fp)
44  : g1_object_class(id,fp)
45{
46  draw_params.setup("missile");
47
48  if (fp && fp->check_version(G1_ROCKET_DATA_VERSION))
49  {
50    zv=fp->read_float();
51    speed=fp->read_float();
52
53    fp->read_reference(who_fired_me);
54    fp->read_reference(track_object);
55    i4_warning("loaded rocket that does no damage");
56    fp->end_version(I4_LF);
57  }
58  else
59  {
60    zv=0;
61    speed=0;   
62  }
63
64  damage = 0;
65
66  radar_type=G1_RADAR_WEAPON; 
67  set_flag(AERIAL        |
68           HIT_GROUND    |
69           SHADOWED, 1);
70}
71
72void g1_rocket_class::save(g1_saver_class *fp)
73{
74  // save data associated with base classes
75  g1_object_class::save(fp);
76
77  fp->start_version(G1_ROCKET_DATA_VERSION);
78
79  fp->write_float(zv);
80  fp->write_float(speed);
81
82  fp->write_reference(who_fired_me);
83  fp->write_reference(track_object);
84
85  fp->end_version();
86}
87
88void g1_rocket_class::fire_at(i4_float sx, i4_float sy, i4_float sz,
89                              i4_float angle,
90                              g1_map_piece_class *kill_target,
91                              g1_map_piece_class *owner,
92                              w32 _damage)
93{
94  damage = _damage;
95
96  lx=x=sx;  ly=y=sy;  lh=h=sz;
97
98  i4_float x_y_dist = sqrt((kill_target->x - sx)*(kill_target->x - sx) +
99                           (kill_target->y - sy)*(kill_target->y - sy));
100 
101 
102  i4_float angle_with_ground;
103
104  if (!g1_calc_fire_angle(x_y_dist, sz, kill_target->h, g(), vo(), angle_with_ground))
105    angle_with_ground=i4_pi()/4;
106 
107 
108  speed=cos(angle_with_ground)*vo();
109  zv=sin(angle_with_ground)*vo();
110 
111
112  ltheta=theta=angle;
113  pitch = lpitch = atan(-zv/speed);
114  player_num=owner->player_num;
115
116  track_object = kill_target;
117  who_fired_me = owner;
118
119  occupy_location();
120  request_think();
121}
122
123void g1_rocket_class::fire(i4_float sx, i4_float sy, i4_float sz,
124                           i4_angle angle,
125                           g1_map_piece_class *owner,
126                           w32 _damage)
127
128  damage = _damage;
129
130  i4_float angle_with_ground=i4_pi()/4;
131 
132  speed=cos(angle_with_ground)*vo();
133  zv=sin(angle_with_ground)*vo();
134
135  theta=angle;
136
137  who_fired_me = owner;
138  player_num=owner->player_num;
139
140  occupy_location();
141  request_think();
142}
143
144void i4_normalize_angle(i4_float &angle);
145
146
147void g1_rocket_class::think()
148{   
149  zv-=g();
150  pitch = atan(-zv/speed);
151  i4_normalize_angle(pitch);
152
153  move(cos(theta) * speed, sin(theta) * speed, zv);
154}
155
156void g1_rocket_class::draw(g1_draw_context_class *context)
157{
158  g1_model_draw(this, draw_params, context);
159
160  if (smoke_trail.valid())
161    smoke_trail->draw(context);
162}
163
164i4_bool g1_rocket_class::move(i4_float x_amount,
165                              i4_float y_amount,
166                              i4_float z_amount)
167{
168
169  g1_smoke_trail_class *s;
170  if (!smoke_trail.valid())
171  {
172    s=(g1_smoke_trail_class *)g1_create_object(smoke_trail_type);
173    if (s)
174    {
175      s->setup(x, y, h, 0.01, 0.1, 0xffd000, 0xffffff);   // orange to white
176      s->occupy_location();
177      smoke_trail=s;
178    }
179  }
180  else s=(g1_smoke_trail_class *)smoke_trail.get();
181
182 
183  g1_object_class *hit = NULL;
184
185  unoccupy_location();
186 
187  i4_3d_vector ray(x_amount, y_amount, z_amount);
188
189  if (!g1_get_map()->check_non_player_collision(player_num,
190                                                i4_3d_vector(x,y,h),
191                                                ray,
192                                                hit))
193  { 
194    x += x_amount;
195    y += y_amount;
196    h += z_amount;
197   
198    request_think();
199    occupy_location();
200
201    if (s)
202      s->update_head(x,y,h);
203
204    return i4_T;
205  }
206  else
207  {           
208    if (s)    // delete the smoke trail
209    {
210      s->unoccupy_location();
211      s->request_remove();
212    }
213
214    // explode
215    if (hit)
216    {
217
218      if (fabs(hit->h - h)<0.2)
219      {
220        hit->damage(this, damage, i4_3d_vector(x_amount,y_amount,z_amount));
221        g1_explosion1_class *explosion;
222        explosion=(g1_explosion1_class *)g1_create_object(explosion_type);
223
224        i4_float rx,ry,rh;
225        rx = g1_float_rand(34) *0.2 - 0.1;
226        ry = g1_float_rand(10) *0.2 - 0.1;
227        rh = g1_float_rand(02) *0.2 - 0.1;
228
229        explosion->setup(hit->x+rx,hit->y+ry,hit->h + rh);
230        x = hit->x + rx;
231        y = hit->y + ry;
232        h = hit->h + rh;
233        request_remove();
234        return i4_F;;
235      }
236     
237      x += x_amount;
238      y += y_amount;
239      h += z_amount;
240   
241      request_think();
242      occupy_location();
243      return i4_T;
244    }
245    else if (who_fired_me.valid())
246    {
247      g1_explosion1_class *explosion=(g1_explosion1_class *)g1_create_object(explosion_type);
248     
249      i4_float rx,ry,rh;
250     
251      rx = g1_float_rand(34) *0.2 - 0.1;
252      ry = g1_float_rand(10) *0.2 - 0.1;
253      rh = g1_float_rand(02) *0.2 - 0.1;
254
255       
256      explosion->setup(lx+rx,ly+ry,lh+rh);     
257    }
258   
259    request_remove();   
260
261    return i4_F;
262  }
263}
264
Note: See TracBrowser for help on using the repository browser.