source: golgotha/src/golg/objs/moneyplane.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: 8.7 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 <math.h>
10#include "objs/model_id.hh"
11#include "objs/model_draw.hh"
12#include "lisp/li_class.hh"
13#include "math/pi.hh"
14#include "math/trig.hh"
15#include "math/angle.hh"
16#include "g1_rand.hh"
17#include "saver.hh"
18#include "map_cell.hh"
19#include "map.hh"
20#include "map_man.hh"
21#include "player.hh"
22#include "object_definer.hh"
23#include "objs/moneycrate.hh"
24#include "objs/bank.hh"
25#include "objs/bases.hh"
26#include "objs/moneyplane.hh"
27#include "lisp/li_class.hh"
28#include "li_objref.hh"
29#include "resources.hh"
30
31#include "image_man.hh"
32static g1_team_icon_ref radar_im("bitmaps/radar/moneyplane.tga");
33
34enum
35{
36  RETURNING=0,
37  TOBASE,
38  DROPPING,
39  LAUNCHING,
40  TOBANK,
41  GRABBING,
42  LIFTING,
43  DYING,
44};
45
46static li_symbol_ref stank_factory("mainbasepad");
47static li_g1_ref_class_member li_crate("crate");
48static li_int_class_member li_mode("mode");
49
50const i4_float VSPEED = 0.04;
51const i4_float FLY_HEIGHT = 3.0;
52const i4_float DROP_HEIGHT = 2.7;
53
54S1_SFX(mo_money, "narrative/money_recieved_22KHz.wav", S1_STREAMED, 200);
55
56static g1_model_ref model_ref("moneyplane"), lod_ref("moneyplane_lod");
57static i4_3d_vector crate_attach;
58
59static void g1_moneyplane_init();
60g1_object_definer<g1_moneyplane_class>
61g1_moneyplane_def("moneyplane",
62                  g1_object_definition_class::TO_MAP_PIECE |
63                  g1_object_definition_class::EDITOR_SELECTABLE |
64                  g1_object_definition_class::MOVABLE,
65                  g1_moneyplane_init);
66
67i4_float damp_distance;
68
69static void g1_moneyplane_init()
70{
71  crate_attach.set(0,0,0);
72  model_ref()->get_mount_point("mountcrate",crate_attach);
73  crate_attach -= g1_moneycrate_class::crate_attach();
74
75  damp_distance = g1_moneyplane_def.defaults->speed/-log(0.9);
76}
77
78g1_moneyplane_class::g1_moneyplane_class(g1_object_type id,
79                           g1_loader_class *fp)
80  : g1_map_piece_class(id, fp)
81
82  draw_params.setup(model_ref.id(), 0, lod_ref.id());
83
84  init_rumble_sound(G1_RUMBLE_JET);
85  radar_type=G1_RADAR_VEHICLE; 
86  radar_image=&radar_im;
87  set_flag(BLOCKING      |
88           TARGETABLE    |
89           AERIAL        |
90           DANGEROUS, 1);
91
92}
93   
94g1_moneycrate_class *g1_moneyplane_class::crate()
95{
96  li_class_context c(vars);
97  return (g1_moneycrate_class *)(li_crate()->value());
98}
99
100void g1_moneyplane_class::set_crate(g1_moneycrate_class *c)
101{
102  vars->set(li_crate, new li_g1_ref(c));
103}
104
105i4_bool g1_moneyplane_class::move(const i4_3d_vector &d)
106{
107  i4_3d_vector np(x,y,h);
108
109  np += d;
110
111  unoccupy_location();
112  x = np.x;
113  y = np.y;
114  h = np.z;
115 
116  if (!occupy_location())
117    return i4_F;
118
119  if (crate())
120  {
121    i4_transform_class t;
122    i4_3d_vector p;
123    calc_world_transform(1.0, &t);
124    t.transform(crate_attach, p);
125    crate()->follow(p, i4_3d_vector(roll, pitch, theta));
126  }
127
128  return i4_T;
129}
130
131void g1_moneyplane_class::damage(g1_object_class *obj, int hp, i4_3d_vector _damage_dir)
132{
133  li_class_context c(vars);
134
135  if (li_mode() != DYING)
136  {
137    g1_map_piece_class::damage(obj,hp,_damage_dir);
138    if (health<20)
139    {
140      i4_float &roll_speed  = dest_x;
141      i4_float &pitch_speed = dest_y;
142     
143      health = 20;
144      set_flag(DANGEROUS,0);
145      roll_speed  = 0;
146      pitch_speed = 0;
147      li_mode() = DYING;
148      if (crate())
149      {
150        crate()->release();
151        set_crate(0);
152      }
153    }
154  }
155
156}
157
158void g1_moneyplane_class::think()
159{
160  int mode = li_mode();
161
162  check_life(i4_F);
163 
164  i4_float height = g1_get_map()->terrain_height(x,y);
165  switch (li_mode())
166  {
167    case RETURNING:
168    {
169      if (h<height + DROP_HEIGHT)
170        h += ((height + DROP_HEIGHT + 0.05)-h)*0.1;
171      else
172      {
173        i4_isl_list<g1_factory_class>::iterator p = g1_factory_list.begin();
174     
175        while (p!=g1_factory_list.end())
176        {
177          if (p->player_num==player_num &&
178              p->id==g1_get_object_type(stank_factory.get()))
179            attack_target = &*p;
180          p++;
181        }
182
183        if (attack_target.valid())
184        {
185          dest_x = attack_target->x;
186          dest_y = attack_target->y;
187          dest_theta = 0;
188          mode = TOBASE;
189        }
190      }
191    } break;
192    case TOBANK:
193    case TOBASE:
194    {
195      i4_3d_vector d(dest_x - x,dest_y - y,0);
196      i4_float
197        dist = d.x*d.x+d.y*d.y;
198
199      i4_float dangle;
200
201      if (mode == TOBANK)
202        d.z = height+FLY_HEIGHT - h;
203      else
204        d.z = height+DROP_HEIGHT - h;
205
206      if (dist<0.0025)
207      {
208        if (theta!=dest_theta)
209          dangle = i4_rotate_to(theta, dest_theta, defaults->turn_speed);
210        else if (mode == TOBANK)
211          mode = GRABBING;
212        else
213          mode = DROPPING;
214        d.set(0,0,0);
215      }
216      else
217      {
218        i4_float angle = i4_atan2(d.y,d.x);
219        i4_normalize_angle(angle);   
220
221        if (dist>damp_distance)
222        {
223          dangle = i4_rotate_to(theta, angle, defaults->turn_speed);
224          if (speed<defaults->speed)
225            speed += defaults->accel;
226          else
227            speed = defaults->speed;
228        }
229        else
230        {
231          speed = (dist+0.1)*-log(0.9);
232          if (theta!=dest_theta)
233            dangle = i4_rotate_to(theta, dest_theta, defaults->turn_speed);
234        }
235       
236        d.x = cos(angle)*speed;
237        d.y = sin(angle)*speed;
238      }
239
240      if (dangle<-0.01)
241        roll += (0.7 - roll)*0.1;
242      else if (dangle>0.01)
243        roll += (-0.7 - roll)*0.1;
244      else
245        roll += -roll*0.1;
246
247      pitch += -pitch*0.1;
248
249      move(d);
250    } break;
251    case DROPPING:
252      if (crate())
253      {
254        g1_player_man.get(player_num)->money() += crate()->value();
255        char msg[100];
256        sprintf(msg, "Money Received : $%d", crate()->value());
257        g1_player_man.show_message(msg, 0x00ff00, player_num);
258
259        mo_money.play();
260        crate()->release();
261        set_crate(0);
262      }
263      mode = LAUNCHING;
264      break;
265    case LAUNCHING:
266      if (h<height + FLY_HEIGHT)
267        h += (height+FLY_HEIGHT+0.05 - h)*0.1;
268      else if (g1_bank_list_count[player_num]>0)
269      {
270        int n=g1_rand(43)%g1_bank_list_count[player_num];
271       
272        i4_isl_list<g1_bank_class>::iterator p = g1_bank_list[player_num].begin();
273        for (int i=0; i<n; i++, p++) ;
274         
275        attack_target = &*p;
276
277        if (attack_target.valid())
278        {
279          i4_3d_vector pos;
280          p->crate_location(pos);
281          pos -= crate_attach;
282          dest_x = pos.x;
283          dest_y = pos.y;
284          dest_z = pos.z;
285          dest_theta = p->theta;
286          mode = TOBANK;
287        }
288      }
289      break;
290    case GRABBING:
291      if (!attack_target.valid())
292        mode = RETURNING;
293      else
294      {
295        i4_bool ok=i4_T;
296
297        ok = (i4_rotate_to(theta,0,defaults->turn_speed)==0) && ok;
298        ok = (i4_rotate_to(pitch,0,defaults->turn_speed)==0) && ok;
299        ok = (i4_rotate_to(roll, 0,defaults->turn_speed)==0) && ok;
300
301        if (h>dest_z)
302        {
303          h -= VSPEED;
304          ok = i4_F;
305        }
306
307        if (ok)
308        {
309          g1_bank_class *bank = (g1_bank_class *)attack_target.get();
310          set_crate(bank->crate());
311          bank->detach_crate();
312
313          mode = LIFTING;
314        }
315      }
316      break;
317    case LIFTING:
318    {
319      if (h<height+DROP_HEIGHT)
320      {
321        i4_3d_vector d(0,0,VSPEED*0.2);
322        pitch += (0.4 - pitch)*0.1;
323        move(d);
324      }
325      else
326        mode = RETURNING;
327    } break;
328    case DYING:
329    {
330      i4_float &roll_speed  = dest_x;
331      i4_float &pitch_speed = dest_y;
332     
333      pitch_speed += 0.004;
334      pitch += pitch_speed;
335
336      roll_speed += 0.008;
337      roll += roll_speed;
338
339      vspeed -= (g1_resources.gravity * 0.1);
340
341      i4_3d_vector d;
342      d.set(speed*cos(theta), speed*sin(theta), vspeed);
343      move(d);
344
345      if (h<=terrain_height)
346        g1_map_piece_class::damage(0,health,i4_3d_vector(0,0,1));               // die somehow!!!
347    } break;
348  }
349
350  groundpitch = lgroundpitch = 0;
351  groundroll = groundroll = 0;
352  request_think();
353
354  li_mode() = mode;
355}
Note: See TracBrowser for help on using the repository browser.