source: golgotha/src/golg/objs/eleccar.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: 15.9 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#include "input.hh"
13#include "math/pi.hh"
14#include "math/trig.hh"
15#include "math/angle.hh"
16#include "objs/bullet.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 "sound/sfx_id.hh"
23#include "objs/eleccar.hh"
24#include "math/random.hh"
25#include "g1_render.hh"
26#include "object_definer.hh"
27#include "draw_context.hh"
28
29#include "image_man.hh"
30static g1_team_icon_ref radar_im("bitmaps/radar/peon_tank.tga");
31
32
33static g1_model_ref model_ref("elec_body"),
34  shadow_ref("elec_shadow"),
35  wheel_ref("elec_wheel"),
36  gun_ref("elec_gun"),
37  lod_ref("elec_body_lod");
38
39static i4_3d_vector wheel_attach, wheel_offset, gun_l_attach, gun_r_attach, gun_offset;
40
41void g1_electric_car_init()
42{
43  //defaults until we get the real ones in the model
44  wheel_attach.set(0,0.1,0.03);
45  wheel_offset.set(0,0.1,0.03);
46  gun_r_attach.set(0.0422,0,-0.0494);
47  gun_l_attach.set(0.0422,0,0.0494);
48  gun_offset.set(0.0422,0,0.0494);
49
50  model_ref()->get_mount_point("Wheel", wheel_attach);
51  model_ref()->get_mount_point("GunLeft", gun_l_attach);
52  model_ref()->get_mount_point("GunRight", gun_r_attach);
53
54  wheel_ref()->get_mount_point("Wheel", wheel_offset);
55  wheel_offset.reverse();
56 
57  gun_ref()->get_mount_point("Gun", gun_offset);
58  gun_offset.reverse();
59}
60
61g1_object_definer<g1_electric_car_class>
62g1_electric_car_def("electric_car",
63                    g1_object_definition_class::TO_MAP_PIECE |
64                    g1_object_definition_class::EDITOR_SELECTABLE |
65                    g1_object_definition_class::MOVABLE,
66                    g1_electric_car_init);
67
68
69g1_electric_car_class::g1_electric_car_class(g1_object_type id,
70                                             g1_loader_class *fp)
71  : g1_map_piece_class(id,fp)
72{   
73  draw_params.setup(model_ref.id(),shadow_ref.id(), lod_ref.id()); 
74
75
76  allocate_mini_objects(4,"Electric Car Mini-Objects");
77
78  wheel     = &mini_objects[0];
79  wheel->defmodeltype     = wheel_ref.id();
80  wheel->position(wheel_attach);
81  wheel->offset = wheel_offset;
82
83  gun_left  = &mini_objects[1];
84  gun_left->defmodeltype  = gun_ref.id();
85  gun_left->position(gun_l_attach);
86  gun_left->offset = gun_offset;
87
88  gun_right = &mini_objects[2];
89  gun_right->defmodeltype = gun_ref.id();
90  gun_right->position(gun_r_attach);
91  gun_right->offset = gun_offset;
92
93  //read other data from file
94  w16 ver,data_size;
95  w32 i;
96  if (fp)
97  {
98    fp->get_version(ver,data_size);
99    if (ver==DATA_VERSION)
100    {
101      for (i=0;i<NUM_ARC_POINTS;i++)
102      {
103        arc_points1[i].position.x  = fp->read_float();
104        arc_points1[i].position.y  = fp->read_float();
105        arc_points1[i].position.z  = fp->read_float();
106        arc_points1[i].lposition.x = fp->read_float();
107        arc_points1[i].lposition.y = fp->read_float();
108        arc_points1[i].lposition.z = fp->read_float();
109       
110        arc_points2[i].position.x  = fp->read_float();
111        arc_points2[i].position.y  = fp->read_float();
112        arc_points2[i].position.z  = fp->read_float();
113        arc_points2[i].lposition.x = fp->read_float();
114        arc_points2[i].lposition.y = fp->read_float();
115        arc_points2[i].lposition.z = fp->read_float();           
116      }
117
118      firing = fp->read_8();
119
120      wheel->rotation.x = fp->read_float();
121      wheel->rotation.y = fp->read_float();
122      wheel->rotation.z = fp->read_float();
123      wheel->lrotation.x = fp->read_float();
124      wheel->lrotation.y = fp->read_float();
125      wheel->lrotation.z = fp->read_float();
126
127      gun_right->rotation.x = fp->read_float();
128      gun_right->rotation.y = fp->read_float();
129      gun_right->rotation.z = fp->read_float();
130      gun_right->lrotation.x = fp->read_float();
131      gun_right->lrotation.y = fp->read_float();
132      gun_right->lrotation.z = fp->read_float();
133
134      gun_left->rotation.x = fp->read_float();
135      gun_left->rotation.y = fp->read_float();
136      gun_left->rotation.z = fp->read_float();
137      gun_left->lrotation.x = fp->read_float();
138      gun_left->lrotation.y = fp->read_float();
139      gun_left->lrotation.z = fp->read_float();
140    }
141    else
142    if (ver==1)
143    {     
144      wheel->rotation.x = fp->read_float();
145      wheel->rotation.y = fp->read_float();
146      wheel->rotation.z = fp->read_float();
147      wheel->lrotation.x = fp->read_float();
148      wheel->lrotation.y = fp->read_float();
149      wheel->lrotation.z = fp->read_float();
150
151      gun_right->rotation.x = fp->read_float();
152      gun_right->rotation.y = fp->read_float();
153      gun_right->rotation.z = fp->read_float();
154      gun_right->lrotation.x = fp->read_float();
155      gun_right->lrotation.y = fp->read_float();
156      gun_right->lrotation.z = fp->read_float();
157
158      gun_left->rotation.x = fp->read_float();
159      gun_left->rotation.y = fp->read_float();
160      gun_left->rotation.z = fp->read_float();
161      gun_left->lrotation.x = fp->read_float();
162      gun_left->lrotation.y = fp->read_float();
163      gun_left->lrotation.z = fp->read_float();
164     
165      firing = i4_F;
166      memset(arc_points1,0,sizeof(arc_point) * NUM_ARC_POINTS);
167      memset(arc_points2,0,sizeof(arc_point) * NUM_ARC_POINTS);
168    }
169    else
170    {
171      fp->seek(fp->tell() + data_size);
172      strategy = g1_electric_car_class::SIT;
173   
174      wheel->rotation = i4_3d_vector(0,0,0);
175      wheel->lrotation = wheel->rotation;
176   
177      gun_left->rotation = i4_3d_vector(0,0,0);
178      gun_left->lrotation = gun_left->rotation;
179   
180      gun_right->rotation = i4_3d_vector(0,0,0);
181      gun_right->lrotation = gun_right->rotation;
182   
183      firing = i4_F;
184      memset(arc_points1,0,sizeof(arc_point) * NUM_ARC_POINTS);
185      memset(arc_points2,0,sizeof(arc_point) * NUM_ARC_POINTS);
186   
187    }
188
189    fp->end_version(I4_LF);
190  }
191  else
192  {   
193    strategy = g1_electric_car_class::SIT;
194   
195    wheel->rotation = i4_3d_vector(0,0,0);
196    wheel->lrotation = wheel->rotation;
197   
198    gun_left->rotation = i4_3d_vector(0,0,0);
199    gun_left->lrotation = gun_left->rotation;
200   
201    gun_right->rotation = i4_3d_vector(0,0,0);
202    gun_right->lrotation = gun_right->rotation;
203   
204    firing = i4_F;
205    memset(arc_points1,0,sizeof(arc_point) * NUM_ARC_POINTS);
206    memset(arc_points2,0,sizeof(arc_point) * NUM_ARC_POINTS);
207   
208  }
209 
210  init_rumble_sound(G1_RUMBLE_GROUND);
211  //  attack_sound = g1_sound_man.alloc_dynamic_3d_sound(g1_sfx_misc_electric_car_charged); sfxfix
212
213  radar_image=&radar_im;
214  radar_type=G1_RADAR_VEHICLE; 
215  set_flag(BLOCKING      |
216           TARGETABLE    |
217           GROUND        |
218           HIT_GROUND    |
219           SHADOWED      |
220           DANGEROUS,   1);
221
222}
223   
224g1_electric_car_class::~g1_electric_car_class()
225{
226  //make sure the sound gets deallocated
227//   if (attack_sound)  sfxfix
228//   {
229//     g1_sound_man.free_dynamic_3d_sound(attack_sound);
230//     attack_sound = 0;
231//   }   
232}
233
234
235void g1_electric_car_class::save(g1_saver_class *fp)
236{
237  g1_map_piece_class::save(fp);
238
239  fp->start_version(DATA_VERSION);
240
241  w32 i;
242  for (i=0;i<NUM_ARC_POINTS;i++)
243  {
244    fp->write_float(arc_points1[i].position.x);
245    fp->write_float(arc_points1[i].position.y);
246    fp->write_float(arc_points1[i].position.z);
247    fp->write_float(arc_points1[i].lposition.x);
248    fp->write_float(arc_points1[i].lposition.y);
249    fp->write_float(arc_points1[i].lposition.z);
250   
251    fp->write_float(arc_points2[i].position.x);
252    fp->write_float(arc_points2[i].position.y);
253    fp->write_float(arc_points2[i].position.z);
254    fp->write_float(arc_points2[i].lposition.x);
255    fp->write_float(arc_points2[i].lposition.y);
256    fp->write_float(arc_points2[i].lposition.z);
257  }
258
259  fp->write_8(firing);
260
261  fp->write_float(wheel->rotation.x);
262  fp->write_float(wheel->rotation.y);
263  fp->write_float(wheel->rotation.z);
264  fp->write_float(wheel->lrotation.x);
265  fp->write_float(wheel->lrotation.y);
266  fp->write_float(wheel->lrotation.z);
267
268  fp->write_float(gun_right->rotation.x);
269  fp->write_float(gun_right->rotation.y);
270  fp->write_float(gun_right->rotation.z);
271  fp->write_float(gun_right->lrotation.x);
272  fp->write_float(gun_right->lrotation.y);
273  fp->write_float(gun_right->lrotation.z);
274
275  fp->write_float(gun_left->rotation.x);
276  fp->write_float(gun_left->rotation.y);
277  fp->write_float(gun_left->rotation.z);
278  fp->write_float(gun_left->lrotation.x);
279  fp->write_float(gun_left->lrotation.y);
280  fp->write_float(gun_left->lrotation.z);
281  fp->end_version();
282}
283
284void g1_electric_car_class::draw(g1_draw_context_class *context)
285
286  g1_map_piece_class::draw(context);
287
288  sw32 i;
289
290  if (firing && health>0)
291  {
292    i4_3d_point_class pts[g1_electric_car_class::NUM_ARC_POINTS];
293    for (i=0;i<g1_electric_car_class::NUM_ARC_POINTS;i++)
294      pts[i].interpolate(arc_points1[i].lposition,arc_points1[i].position,g1_render.frame_ratio);
295
296    g1_render.add_translucent_trail(context->transform,pts,
297                                    g1_electric_car_class::NUM_ARC_POINTS,
298                                    0.02,0.02,1,1,0xFFFFFF,0x0088FF);
299 
300    for (i=0;i<g1_electric_car_class::NUM_ARC_POINTS;i++)
301      pts[i].interpolate(arc_points2[i].lposition,arc_points2[i].position,g1_render.frame_ratio);
302
303    g1_render.add_translucent_trail(context->transform,pts,
304                                    g1_electric_car_class::NUM_ARC_POINTS,
305                                    0.02,0.02,1,1,0xFFFFFF,0x0088FF);   
306  }
307}
308
309void g1_electric_car_class::copy_old_points()
310{
311  sw32 i;
312  for (i=0;i<NUM_ARC_POINTS;i++)
313  {
314    arc_points1[i].lposition = arc_points1[i].position;
315    arc_points2[i].lposition = arc_points2[i].position;
316  }
317}
318
319void g1_electric_car_class::new_arc_points(const i4_3d_vector &laser1,
320                                           const i4_3d_vector &laser2,
321                                           const i4_3d_vector &target)
322{
323  i4_float rx,ry,rz,px,py,pz;
324  i4_float map_point_height;
325 
326  i4_3d_vector vec1,vec2;
327
328  vec1 = target;
329  vec1 -= laser1;
330
331  vec2 = target;
332  vec2 -= laser2;
333
334  sw32 i;
335
336  for (i=0; i<NUM_ARC_POINTS; i++)
337  {
338    i4_float sin_factor = sin(i4_pi()*i/(NUM_ARC_POINTS-1));
339
340    //ARC #1
341    rx = (i4_rand()&0xFFFF)/((i4_float)0xffff) * 0.8 - 0.2;
342    ry = (i4_rand()&0xFFFF)/((i4_float)0xffff) * 0.8 - 0.2;
343    rz = (i4_rand()&0xFFFF)/((i4_float)0xffff) * 0.8 - 0.2;
344   
345    px = laser1.x + vec1.x*i/(NUM_ARC_POINTS-1) + rx*sin_factor;
346    py = laser1.y + vec1.y*i/(NUM_ARC_POINTS-1) + ry*sin_factor;
347    pz = laser1.z + vec1.z*i/(NUM_ARC_POINTS-1) + rz*sin_factor;
348   
349    map_point_height = g1_get_map()->map_height(px,py,pz) + 0.05;
350 
351    if (pz < map_point_height)
352      pz = map_point_height;
353 
354    arc_points1[i].position = i4_3d_vector(px,py,pz);
355   
356    //ARC #2
357    rx = (i4_rand()&0xFFFF)/((i4_float)0xffff) * 0.8 - 0.2;
358    ry = (i4_rand()&0xFFFF)/((i4_float)0xffff) * 0.8 - 0.2;
359    rz = (i4_rand()&0xFFFF)/((i4_float)0xffff) * 0.8 - 0.2;
360   
361    px = laser2.x + vec2.x*i/(NUM_ARC_POINTS-1) + rx*sin_factor;
362    py = laser2.y + vec2.y*i/(NUM_ARC_POINTS-1) + ry*sin_factor;
363    pz = laser2.z + vec2.z*i/(NUM_ARC_POINTS-1) + rz*sin_factor;
364     
365    map_point_height = g1_get_map()->map_height(px,py,pz) + 0.05;
366 
367    if (pz < map_point_height)
368      pz = map_point_height;
369 
370    arc_points2[i].position = i4_3d_vector(px,py,pz);
371  }
372}
373
374void g1_electric_car_class::fire()
375{
376  i4_3d_vector laser1,laser2;
377  i4_float     tmp_x,tmp_y,tmp_z;
378 
379  i4_transform_class btrans,tmp1;
380 
381  btrans.identity();
382
383  tmp1.rotate_x(groundroll);
384  btrans.multiply(tmp1);
385
386  tmp1.rotate_y(groundpitch);
387  btrans.multiply(tmp1);
388
389  tmp1.rotate_z(theta);
390  btrans.multiply(tmp1);
391     
392  i4_3d_point_class tpoint;
393 
394  tmp_x = 0.18;
395  tmp_y = 0.05;
396  tmp_z = 0.05;
397
398  btrans.transform(i4_3d_point_class(tmp_x,tmp_y,tmp_z),tpoint);
399 
400  laser1.x = x + tpoint.x;
401  laser1.y = y + tpoint.y;
402  laser1.z = h + tpoint.z;
403 
404  tmp_x = 0.18;
405  tmp_y = -0.05;
406  tmp_z = 0.05;
407
408  btrans.transform(i4_3d_point_class(tmp_x,tmp_y,tmp_z),tpoint);
409 
410  laser2.x = x + tpoint.x;
411  laser2.y = y + tpoint.y;
412  laser2.z = h + tpoint.z;
413 
414  //laser1 and laser2 are the woldspace points where the arcs should be emitted
415//   if (attack_sound)  sfxfix
416//   {
417//     i4_3d_vector delta_pos = i4_3d_vector(0,0,0);
418
419//     g1_sound_man.update_dynamic_3d_sound(attack_sound,laser1,delta_pos,1);
420//   }
421 
422  i4_3d_vector target_point;
423
424  if (firing)
425  {
426    //he's been firing
427    copy_old_points();
428
429    //aim arc_points.position at the current tick's position of the target
430    target_point = i4_3d_vector(attack_target->x,
431                                attack_target->y,
432                                attack_target->h + attack_target->occupancy_radius()/2);
433
434    new_arc_points(laser1, laser2, target_point);
435  }
436  else
437  {
438    //he just started firing
439    //aim arc_points.lposition at the last tick's position of the target
440    target_point = i4_3d_vector(attack_target->lx,
441                                attack_target->ly,
442                                attack_target->lh + attack_target->occupancy_radius()/2);
443
444    new_arc_points(laser1, laser2, target_point);
445
446    copy_old_points();
447
448    //aim arc_points.position at the current tick's position of the target
449    target_point = i4_3d_vector(attack_target->x,
450                                attack_target->y,
451                                attack_target->h + attack_target->occupancy_radius()/2);
452   
453
454    new_arc_points(laser1, laser2, target_point);
455
456  }
457
458
459  i4_3d_vector dir(attack_target->x-x, attack_target->y, attack_target->h-h);
460  dir.normalize();
461 
462  g1_apply_damage(this, this, attack_target.get(), dir);
463 
464  firing = i4_T;
465}
466
467void g1_electric_car_class::post_think()
468{
469  //(OLI) should fix semantics of post_think - should post_think only if requested
470
471  if (!alive())
472    return;
473
474  g1_object_class *target=attack_target.get();
475  if (target)
476  {       
477    request_think();
478
479    i4_float dx,dy,angle;     
480
481    dx = (attack_target->x - x);
482    dy = (attack_target->y - y);
483
484    //aim the vehicle   
485    angle = i4_atan2(dy,dx);
486
487    i4_normalize_angle(angle);
488
489    if (i4_angle_diff(angle,theta)<i4_pi()/4)
490    {
491      fire();
492      gun_right->rotation.x += 0.4;
493      gun_left->rotation.x  -= 0.4;
494    }
495    else
496    {
497      // turn toward stuff, when still
498      if (lx == x && ly==y)
499      {
500        theta = ltheta;
501        i4_rotate_to(theta, angle, defaults->turn_speed);
502      }
503
504      gun_right->rotation.x = gun_right->lrotation.x = 0;
505      gun_left->rotation.x  = gun_left->lrotation.x  = 0;
506      firing = i4_F;
507    }
508  }
509  else
510  {
511    firing = i4_F;
512    gun_right->rotation.x = gun_right->lrotation.x = 0;
513    gun_left->rotation.x  = gun_left->lrotation.x  = 0;
514  }
515 
516//   if (!firing && attack_sound && attack_sound->is_playing())  sfxfix
517//     attack_sound->stop();
518}
519
520void g1_electric_car_class::die()
521{
522//   if (attack_sound)
523//   {
524//     g1_sound_man.free_dynamic_3d_sound(attack_sound);
525//     attack_sound=0;
526//   }
527}
528
529
530
531i4_bool g1_electric_car_class::can_attack(g1_object_class *who) const
532{
533  if (g1_map_piece_class::can_attack(who))
534  {
535    i4_float dx,dy,angle;     
536
537    dx = (who->x - x);
538    dy = (who->y - y);
539    angle = i4_atan2(dy,dx);
540    i4_normalize_angle(angle);
541
542    if (i4_angle_diff(angle,theta)<i4_pi()/8)
543      return i4_T;
544  }
545
546  return i4_F;
547}
Note: See TracBrowser for help on using the repository browser.