source: golgotha/src/golg/objs/bullet.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: 8.0 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 "objs/bullet.hh"
10#include "input.hh"
11#include "map.hh"
12#include "math/pi.hh"
13#include "math/trig.hh"
14#include "math/random.hh"
15#include "resources.hh"
16
17#include "objs/model_draw.hh"
18
19#include "objs/explosion1.hh"
20#include "saver.hh"
21#include "tile.hh"
22
23#include "sfx_id.hh"
24#include "sound_man.hh"
25#include "objs/map_piece.hh"
26#include "objs/explosion1.hh"
27#include "objs/flak.hh"
28#include "objs/shrapnel.hh"
29#include "object_definer.hh"
30#include "math/pi.hh"
31#include "g1_texture_id.hh"
32#include "r1_api.hh"
33#include "g1_tint.hh"
34#include "map_man.hh"
35#include "flare.hh"
36#include "objs/light_o.hh"
37#include "objs/particle_emitter.hh"
38#include "lisp/li_class.hh"
39#include "li_objref.hh"
40#include "camera.hh"
41#include "time/profile.hh"
42
43static i4_profile_class pf_bullet("bullet_think");
44
45static li_symbol_ref explosion_type("explosion1"),
46  flak_type("flak"),
47  shrapnel_type("shrapnel"),
48  light_type("lightbulb"),
49  particle_emitter_type("particle_emitter"),
50  damager_type("damager");
51
52g1_object_definer<g1_bullet_class> g1_b120mm_def("b120mm");
53g1_object_definer<g1_bullet_class> g1_b90mm_def("b90mm");
54g1_object_definer<g1_bullet_class> g1_acid_def("acid", g1_object_definition_class::HAS_ALPHA);
55g1_object_definer<g1_bullet_class> g1_napalm_def("napalm", g1_object_definition_class::HAS_ALPHA);
56g1_object_definer<g1_bullet_class> g1_chain_gun_def("chain_gun", g1_object_definition_class::HAS_ALPHA);
57
58static li_float_class_member start_size("start_size"),
59  grow_speed("grow_speed"), max_speed("max_speed");
60
61static li_object_class_member texture_name("texture_name");
62static r1_texture_ref bullet_particle("bullet_particle");
63
64
65void g1_bullet_class::think()
66{
67  pf_bullet.start();
68  move();
69  pf_bullet.stop();
70}
71
72
73void g1_bright_ambient(i4_transform_class *object_to_world,
74                      i4_float &ar, i4_float &ag, i4_float &ab)
75{
76  ar=ag=ab=1;
77}
78
79
80g1_bullet_class::g1_bullet_class(g1_object_type id,
81                                 g1_loader_class *fp)
82  : g1_object_class(id,fp)
83{
84  range=10;
85
86  if (fp && fp->check_version(DATA_VERSION))
87  {
88    x=-1;
89//     fp->read_reference(who_fired_me);   
90//     fp->read_format("fffff4",
91//                     &vel.x, &vel.y, &vel.z,
92//                     &range, &range_decrement,
93//                     &bullet_flags);
94
95//     fp->end_version(I4_LF);
96  }
97  else
98  {
99    bullet_flags=0;
100    vel=i4_3d_vector(0,0,0);
101    range=0;
102    range_decrement=1;
103  }
104
105  if (fp)
106    flags|=THINKING;
107}
108
109
110void g1_bullet_class::move_forward()
111{
112  grab_old();
113  x += vel.x; y += vel.y;  h += vel.z;
114
115  if (bullet_flags & SPINS)
116    roll+=0.9;
117
118  range -= range_decrement;
119
120  if (light.get())
121    light->move(x,y,h);
122
123  if (particle_emitter.get())
124    particle_emitter->move(x,y,h);
125}
126
127
128void g1_bullet_class::setup(const i4_3d_vector &start_pos,
129                            const i4_3d_vector &_vel,
130                            g1_object_class *this_guy_fired_me,
131                            i4_float _range,
132                            w32 flags,
133                            r1_texture_handle sprite_texture,
134                            g1_light_object_class *_light)
135                           
136{   
137  bullet_flags = flags;
138  range  = _range;
139
140  x=start_pos.x;
141  y=start_pos.y;
142  h=start_pos.z;
143
144  lx=start_pos.x;
145  ly=start_pos.y;
146  lh=start_pos.z;
147
148  vel=_vel;
149  range_decrement=vel.length()/range;
150 
151  ltheta=theta = i4_atan2(vel.y, vel.x);   
152  pitch=lpitch = i4_atan2(-vel.z, sqrt(vel.x * vel.x +
153                                       vel.y * vel.y));
154  lroll=roll   = 0;
155  player_num   = this_guy_fired_me->player_num;
156  who_fired_me = this_guy_fired_me;
157
158  if (bullet_flags & IS_SPRITE)
159    tex=sprite_texture;
160  else
161    draw_params.setup(name());
162
163  if (!get_flag(MAP_OCCUPIED))
164  {
165    if (!occupy_location())
166      return;
167    request_think();
168  }
169
170  i4_bool possible_visible;
171
172  float r=g1_resources.visual_radius();
173  if (g1_current_view_state()->dist_sqrd(i4_3d_vector(x,y,h))<r*r)
174    possible_visible=i4_T;
175  else
176    possible_visible=i4_F;
177 
178  if ((bullet_flags & MAKE_SMOKE) && possible_visible)
179  {
180    int type=g1_get_object_type(particle_emitter_type.get());
181    particle_emitter = (g1_particle_emitter_class *)g1_create_object(type);
182
183    if (particle_emitter.get())
184    {
185      g1_particle_emitter_params p;
186      p.defaults();
187      p.start_size=0.0001;
188      p.grow_speed=0.001;
189      p.max_speed=0.01;
190
191      p.texture=bullet_particle.get();
192      particle_emitter->setup(x,y,h, p);
193    }
194  }
195
196  light=_light;
197
198  move();
199
200}
201
202
203void g1_bullet_class::save(g1_saver_class *fp)
204{
205  // tell direived classes to save themselves
206  g1_object_class::save(fp);
207
208  fp->start_version(DATA_VERSION);
209
210  fp->write_reference(who_fired_me);   
211 
212  fp->write_format("fffff44",
213                   &vel.x, &vel.y, &vel.z,
214                   &range, &range_decrement,
215                   &bullet_flags);
216
217  fp->end_version();
218}
219
220
221void g1_bullet_class::draw(g1_draw_context_class *context)
222{
223  if ((bullet_flags & IS_SPRITE)==0)
224  {
225    g1_get_ambient_function_type old_ambient=g1_render.get_ambient;
226    g1_render.get_ambient=g1_bright_ambient;
227
228    g1_render.r_api->set_filter_mode(R1_BILINEAR_FILTERING);
229    g1_model_draw(this, draw_params, context);
230    g1_render.r_api->set_filter_mode(R1_NO_FILTERING);
231
232    g1_render.get_ambient=old_ambient;
233  }
234  else
235  {
236    i4_3d_vector pos(i4_interpolate(lx,x, g1_render.frame_ratio),
237                     i4_interpolate(ly,y, g1_render.frame_ratio),
238                     i4_interpolate(lh,h, g1_render.frame_ratio)), t_pos;
239    context->transform->transform(pos, t_pos); 
240    g1_render.render_sprite(t_pos, tex, 0.05, 0.05);
241  }
242}
243
244
245void g1_bullet_class::done(i4_bool hit, g1_object_class *hit_object)
246{
247  unoccupy_location();
248  request_remove();
249
250  if (hit_object)
251  {
252    g1_shrapnel_class *shrap =
253      (g1_shrapnel_class *)g1_create_object(g1_get_object_type(shrapnel_type.get()));
254
255    if (shrap)
256      shrap->setup(x,y,h,5,1);
257
258    g1_apply_damage(this, who_fired_me.get(), hit_object, vel);     
259  }
260  else if (hit)
261  {
262    g1_flak_class *flak = (g1_flak_class *)g1_create_object(g1_get_object_type(flak_type.get()));
263
264    if (flak)
265      flak->setup(i4_3d_vector(x,y,h), 0.1);
266  }
267
268  if (light.get())
269  {
270    light->unoccupy_location();
271    light->request_remove();
272  }
273
274  if (particle_emitter.get())
275    particle_emitter->stop();
276}
277
278
279i4_bool g1_bullet_class::move()
280
281{
282  // we traveled to far already, let's go away
283  if (range<0)
284  {
285    done();
286    return i4_F;
287  }
288
289  g1_object_class *hit = 0;
290
291  i4_3d_vector pos(x,y,h);
292  if (!g1_get_map()->check_non_player_collision(player_num,pos,vel,hit))
293  { 
294    unoccupy_location();
295
296    move_forward();
297   
298    occupy_location();
299    request_think();
300   
301    return i4_T;
302  }
303  else
304  {
305#ifdef TEST_COLLIDE
306    x += vel.x;
307    y += vel.y;
308    h += vel.z;
309    vel.set(0,0,0);
310    grab_old();
311#else
312    if (hit)
313    {
314      float v_len=vel.length();
315     
316      if (v_len>0.05)
317      {
318        i4_3d_vector dir=vel;      // scoot the bullet back so smoke & stuff show up in front
319        dir/=v_len;                // of the vehicle
320        dir*=0.05;
321        vel-=dir;
322      }
323      else
324        vel.set(0,0,0);
325      x+=vel.x;
326      y+=vel.y;
327      h+=vel.z;
328    }
329
330    done(i4_T, hit); //we've hit something or the ground
331#endif
332  }
333 
334  return i4_F;
335}
336
337
338
Note: See TracBrowser for help on using the repository browser.