source: golgotha/src/golg/objs/tank_buster.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
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 "input.hh"
11#include "math/pi.hh"
12#include "math/trig.hh"
13#include "math/angle.hh"
14#include "resources.hh"
15#include "saver.hh"
16#include "map_cell.hh"
17#include "map.hh"
18#include "objs/vehic_sounds.hh"
19#include "sound/sfx_id.hh"
20#include "object_definer.hh"
21
22#include "objs/model_id.hh"
23#include "objs/model_draw.hh"
24#include "objs/fire.hh"
25#include "objs/tank_buster.hh"
26#include "lisp/lisp.hh"
27
28#include "image_man.hh"
29static g1_team_icon_ref radar_im("bitmaps/radar/tank_buster.tga");
30
31
32S1_SFX(raising, "misc/missile_truck_raise.wav", S1_3D, 5);
33S1_SFX(lowering, "misc/missile_truck_lower.wav", S1_3D, 5);
34
35
36enum { DATA_VERSION=1 };
37
38enum eRackState
39{
40  LOWERED,
41  RAISE,
42  RAISING,
43  RAISED,
44  LOWER,
45  LOWERING,
46};
47
48
49static g1_model_ref model_ref("buster_body"), shadow_ref("buster_body_shadow"),
50  missile_ref("buster_rocket"), bot_lod("buster_body_lod");
51
52static g1_object_type buster_rocket_type;
53static i4_3d_vector missile_attach, missile_offset;
54
55void g1_tank_buster_init()
56{
57  buster_rocket_type = g1_get_object_type("buster_rocket");
58
59  missile_attach.set(-0.1984,0,0.1468);
60  model_ref.get()->get_mount_point("Missile", missile_attach);
61
62  missile_offset.set(0,0,0);
63  missile_ref.get()->get_mount_point("Offset", missile_offset);
64  missile_offset.reverse();
65}
66
67g1_object_definer<g1_tank_buster_class>
68g1_tank_buster_def("tank_buster",
69                   g1_object_definition_class::TO_MAP_PIECE |
70                   g1_object_definition_class::EDITOR_SELECTABLE |
71                   g1_object_definition_class::MOVABLE,
72                   g1_tank_buster_init);
73
74g1_tank_buster_class::g1_tank_buster_class(g1_object_type id,
75                                           g1_loader_class *fp)
76  : g1_map_piece_class(id, fp)
77
78  draw_params.setup(model_ref.id(),0,bot_lod.id());
79
80  allocate_mini_objects(2,"Tank Buster Mini-objects");
81
82  missile = &mini_objects[0];
83  missile->defmodeltype = missile_ref.id();
84  missile->position(missile_attach);
85  missile->offset = missile_offset;
86 
87  i4_bool use_defaults = i4_T;
88
89  w16 ver,data_size;
90  if (fp)
91  {
92    fp->get_version(ver,data_size);
93    if (ver==DATA_VERSION)
94    {
95      use_defaults = i4_F;
96      fp->read_format("1fff",
97                      &rack_state,
98                      &missile->rotation.x,
99                      &missile->rotation.y,
100                      &missile->rotation.z);
101     
102      missile->lrotation = missile->rotation;
103    }
104    else
105      fp->seek(fp->tell() + data_size);
106
107    fp->end_version(I4_LF);
108  }
109 
110  if (use_defaults)
111  {
112    rack_state = LOWERED;
113    missile->rotation  = i4_3d_vector(0,0,0);
114    missile->lrotation = missile->rotation;
115    fire_delay = 0; //no delay time
116    explode_delay = -1;
117  }
118
119
120
121  init_rumble_sound(G1_RUMBLE_GROUND);
122  radar_type=G1_RADAR_VEHICLE;
123  radar_image=&radar_im;
124  set_flag(BLOCKING      |
125           TARGETABLE    |
126           GROUND        |
127           HIT_AERIAL    |
128           HIT_GROUND    |
129           DANGEROUS, 1);
130}
131   
132void g1_tank_buster_class::save(g1_saver_class *fp)
133{
134  g1_map_piece_class::save(fp);
135
136  fp->start_version(DATA_VERSION);
137
138  fp->write_format("1fff",
139                   &rack_state,
140                   &missile->rotation.x,
141                   &missile->rotation.y,
142                   &missile->rotation.z);
143 
144  fp->end_version();
145}
146
147void g1_tank_buster_class::fire()
148{
149  g1_object_class *target=attack_target.get();
150
151  if (target)
152  {
153
154    i4_transform_class o2w;   
155    calc_world_transform(1,&o2w);
156
157    i4_3d_vector local_fire_point;   
158    i4_3d_vector world_fire_point, world_fire_dir;
159    o2w.transform(i4_3d_vector(0.0, 0, 0.0), world_fire_point);
160    o2w.transform(i4_3d_vector(1,0,0), world_fire_dir);
161    world_fire_dir-=world_fire_point;
162   
163    g1_fire(defaults->fire_type, this, attack_target.get(),
164            world_fire_point, world_fire_dir);   
165
166 
167    //kill the missile, mainly so that it doesnt draw anymore
168    i4_free(mini_objects);
169    mini_objects     = 0;
170    num_mini_objects = 0;
171    missile          = 0;
172
173    explode_delay = 15;
174  }
175}
176
177void g1_tank_buster_class::raise_missile()
178{
179  if (rack_state==LOWERED || rack_state==LOWERING)
180    rack_state=RAISE;
181
182  request_think();
183}
184
185void g1_tank_buster_class::lower_missile()
186{
187  if (rack_state==RAISED || rack_state==RAISING)
188    rack_state=LOWER;
189
190  request_think();
191}
192
193void g1_tank_buster_class::think()
194
195  if (explode_delay >= 0)
196  {
197    if (explode_delay==0)
198      damage(this, health, i4_3d_vector(0,0,1));
199    else
200    {
201      explode_delay--;
202      request_think();
203    }
204   
205    return;
206  }
207
208  if (!check_life())
209    return;
210
211  g1_map_piece_class::think();
212
213  i4_bool keep_going = i4_F;
214
215  switch (rack_state)
216  {
217    case LOWERED:
218      break;
219
220    case RAISE:
221      raising.play(x,y,h);
222      rack_state = RAISING;
223   
224    case RAISING:     
225      if (i4_rotate_to(missile->rotation.y,-i4_pi()/8 + i4_2pi(),0.1)!=0.0)
226        keep_going = i4_T;
227
228      if (missile->x < 0)
229      {
230        missile->x += 0.02;
231        keep_going = i4_T;
232      }
233
234      if (missile->x > 0)
235        missile->x = 0;
236
237      if (keep_going)
238        request_think();
239      else
240        rack_state = RAISED;
241      break;
242
243    case RAISED:
244      break;
245
246    case LOWER:
247      lowering.play(x,y,h);
248      rack_state = LOWERING;
249
250    case LOWERING:
251      if (i4_rotate_to(missile->rotation.y,0,0.1)!=0.0)
252        keep_going = i4_T;
253
254      if (i4_rotate_to(missile->rotation.z,0,0.1)!=0.0)
255        keep_going = i4_T;
256
257      if (missile->x > -0.1984)
258      {
259        missile->x -= 0.02;
260        keep_going = i4_T;
261      }
262       
263      if (missile->x < -0.1984)
264        missile->x = -0.1984;
265
266      if (keep_going)
267        request_think();
268      else
269        rack_state = LOWERED;
270      break;
271  }
272 
273  //aim the missile rack
274  if (attack_target.valid())
275  {
276    request_think();
277
278    raise_missile();
279
280    if (rack_state==RAISED)
281      fire();
282  } 
283  else
284    lower_missile();
285}
Note: See TracBrowser for help on using the repository browser.