source: golgotha/src/golg/objs/popup_turret.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: 5.8 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 "objs/model_id.hh"
11#include "objs/model_draw.hh"
12#include "objs/popup_turret.hh"
13#include "input.hh"
14#include "math/pi.hh"
15#include "math/angle.hh"
16#include "math/trig.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 "object_definer.hh"
24#include "lisp/lisp.hh"
25#include "objs/fire.hh"
26
27enum {DATA_VERSION=1};
28 
29static g1_model_ref model_ref("popup_housing"),
30  mount_ref("popup_mount"),
31  barrel_ref("popup_barrel");
32
33static g1_object_type bullet;
34static i4_3d_vector turret_attach, mount_offset, barrel_offset;
35
36//tunable variables
37//  burst of fire.
38//  rates of turning on, tracking
39//  angle ranges
40//  (weapons?  maybe different objects)
41//  entry range to fire
42
43const i4_float POPUP_HEIGHT      = 0.4;
44const i4_float POPUP_SPEED       = 0.1;
45const i4_float POPDOWN_SPEED     = 0.05;
46const i4_float POPUP_ROTATESPEED = 0.3;
47
48void g1_popup_turret_init()
49{
50  bullet = g1_get_object_type("bullet");
51
52  turret_attach.set(0,0,0);
53  model_ref()->get_mount_point("Mount Point", turret_attach);
54
55  mount_offset.set(0,0,0.15);
56  mount_ref()->get_mount_point("Mount Point", mount_offset);
57  mount_offset.reverse();
58  barrel_offset.set(0,0,0.15);
59  barrel_ref()->get_mount_point("Mount Point", barrel_offset);
60  barrel_offset.reverse();
61}
62
63g1_object_definer<g1_popup_turret_class>
64g1_popup_turret_def("popup_turret", g1_object_definition_class::EDITOR_SELECTABLE,
65                    g1_popup_turret_init);
66
67void g1_popup_turret_class::setup(i4_float _x, i4_float _y, g1_object_class *creator)
68{
69  x = x;
70  y = y;
71  player_num = creator->player_num;
72  occupy_location();
73  request_think();
74  grab_old();
75}
76
77g1_popup_turret_class::g1_popup_turret_class(g1_object_type id,
78                                 g1_loader_class *fp)
79  : g1_map_piece_class(id,fp)
80
81
82  radar_type=G1_RADAR_BUILDING;
83  set_flag(BLOCKING      |
84           SELECTABLE    |
85           TARGETABLE    |
86           GROUND        |
87           HIT_GROUND    |
88           HIT_AERIAL    |
89           DANGEROUS     |
90           SHADOWED, 1);
91
92  defaults = g1_popup_turret_def.defaults;
93  draw_params.setup(model_ref.id());
94 
95  allocate_mini_objects(2,"popup_turret mini objects");
96
97  mount = &mini_objects[0];
98  mount->defmodeltype = mount_ref.id();
99  mount->position(turret_attach);
100  mount->rotation.set(0,0,0);
101  mount->offset = mount_offset;
102 
103  barrel = &mini_objects[1];
104  barrel->defmodeltype = barrel_ref.id();
105  barrel->position(turret_attach);
106  barrel->rotation.set(0,i4_pi()/2,0);
107  barrel->offset = barrel_offset;
108 
109  if (fp && fp->check_version(DATA_VERSION))
110  {
111    fp->read_format("f",
112                    &mount->rotation.y);
113    barrel->rotation.y = mount->rotation.y;
114    fp->end_version(I4_LF);
115  }
116  else
117  {
118    health = defaults->health;
119  }
120
121  mount->grab_old();
122  barrel->grab_old();
123}
124
125void g1_popup_turret_class::save(g1_saver_class *fp)
126{
127  g1_map_piece_class::save(fp);
128 
129  fp->start_version(DATA_VERSION);
130
131  fp->write_format("f",
132                   &mount->rotation.y);
133
134  fp->end_version();
135}
136
137
138void g1_popup_turret_class::fire()
139{
140  fire_delay = defaults->fire_delay;
141 
142  i4_3d_point_class tpos, bpos, bvel;
143 
144  i4_transform_class t, main, l2w;
145  barrel->calc_transform(1.0, &t);   
146  calc_world_transform(1.0, &main);
147  l2w.multiply(main, t);
148 
149  main.transform(turret_attach, bpos);
150  l2w.transform_3x3(i4_3d_point_class(1.0, 0, 0), bvel);
151
152  // spin the barrel
153  barrel->rotation.x += 0.7;
154  i4_normalize_angle(barrel->rotation.x);
155
156  g1_fire(defaults->fire_type, this, attack_target.get(), bpos, bvel);
157}
158
159
160void g1_popup_turret_class::think()
161
162  find_target();
163
164  if (health < defaults->health)
165    health++;
166
167  if (fire_delay>0)
168    fire_delay--;
169
170  //aim the turet
171  if (attack_target.valid())
172  {
173    request_think();
174
175    if (h < terrain_height+POPUP_HEIGHT-0.001)
176    {
177      h += POPUP_SPEED;
178      if (h>terrain_height+POPUP_HEIGHT)
179        h = terrain_height+POPUP_HEIGHT;
180    }
181    else
182    {
183      i4_3d_point_class d,pos;
184
185      lead_target(d);
186
187      pos.set(x,y,h-POPUP_HEIGHT);
188      d -= pos;
189
190      //aim the turet
191
192      i4_float fire_angle,fire_pitch;
193   
194      fire_angle = i4_atan2(d.y,d.x);
195      fire_pitch = i4_atan2(-d.z,sqrt(d.x*d.x+d.y*d.y));
196   
197      i4_normalize_angle(fire_angle);
198      i4_normalize_angle(fire_pitch);
199
200      int aimed=i4_F;
201      i4_float dangle;
202
203      dangle = i4_rotate_to(theta,fire_angle,defaults->turn_speed);
204      aimed = (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
205      dangle = i4_rotate_to(mount->rotation.y,fire_pitch,POPUP_ROTATESPEED);
206      aimed &= (dangle<POPUP_ROTATESPEED && dangle>-POPUP_ROTATESPEED);
207      barrel->rotation.y = mount->rotation.y;
208      if (aimed)
209        if (!fire_delay)
210          fire();
211    }
212  }
213  else
214  {
215    request_think();            // move this to draw function
216
217    int aimed = i4_rotate_to(mount->rotation.y, i4_pi()/2, POPUP_ROTATESPEED)==0.0;
218    barrel->rotation.y = mount->rotation.y;
219
220    if (aimed && h>terrain_height)
221    {
222      h -= POPDOWN_SPEED;
223      if (h<terrain_height)
224        h = terrain_height;
225    }
226  }
227}
Note: See TracBrowser for help on using the repository browser.