1 /***************************************************************************
2 ****************************************************************************
3 ****************************************************************************
4 * Nighthawk
5 * Copyright (C) 1996-2004 Jason Nunn et al
6 * Developed by Jason Nunn et al (see README for Acknowledgements)
7 *
8 * Project head and maintainer--
9 *   Eric Gillespie (The Viking)
10 *   Email: viking667@users.sourceforge.net
11 *   http://night-hawk.sourceforge.net
12 *
13 * Original Author--
14 *   Jason Nunn
15 *   http://jsno.leal.com.au
16 *
17 *   C/- Jason Nunn
18 *   PO Box 15
19 *   Birdwood SA 5234
20 *   Australia
21 *
22 * This software is Open Source GPL. Please read COPYING notice.
23 * ==================================================================
24 * daddy droid object routines
25 *
26 ****************************************************************************
27 ****************************************************************************
28 ***************************************************************************/
29 #include "defs.h"
30 #include "protos.p"
31 
32 #include "tdroid.h"
33 #include "tparadroid.h"
34 
35 /***************************************************************************
36 *
37 ***************************************************************************/
tdroid(void)38 tdroid::tdroid(void)
39 {
40   int x;
41 
42   for(x = 0; x < MAX_LASERS; x++)
43     laser_list[x] = NULL;
44 
45   expl_anim_ptr = 0.0;
46   expl_anim_speed = 0.3;
47   expl_anim_len = 7.0;
48   shield_wave_inc = 0.0;
49   captured = 0;
50   recharge_delay = 0.0;
51 }
52 
init(tfloor * f,tentity ** dp,float px,float py)53 void tdroid::init(tfloor *f, tentity **dp, float px, float py)
54 {
55   tentity::init(f, &droid_bm[0], dp, 10, px, py);
56 }
57 
create_laser(int vx,int vy)58 int tdroid::create_laser(int vx, int vy)
59 {
60   int x, status = 0;
61 
62   for(x = 0; x < MAX_LASERS; x++)
63     if(laser_list[x] == NULL)
64     {
65       switch(stats.armament)
66       {
67         case 1:
68           laser_list[x] = new tlaser0();
69           break;
70         case 2:
71           laser_list[x] = new tlaser1();
72           break;
73         case 3:
74           laser_list[x] = new tlaser2();
75           break;
76         case 4:
77           laser_list[x] = new tlaser3();
78           break;
79       }
80 
81       if(laser_list[x] == NULL)
82         malloc_error_h();
83 
84       laser_list[x]->init(
85         floor_ptr, droids, pos_x, pos_y, vx, vy, this);
86 
87       break;
88     }
89 
90   return status;
91 }
92 
free_all_laser(void)93 void tdroid::free_all_laser(void)
94 {
95   int x;
96 
97   for(x = 0; x < MAX_LASERS; x++)
98     if(laser_list[x] != NULL)
99     {
100       delete(laser_list[x]);
101       laser_list[x] = NULL;
102     }
103 }
104 
snap_shot(void)105 void tdroid::snap_shot(void)
106 {
107   int x;
108 
109   tentity::snap_shot();
110 
111   ss_expl_anim_ptr = expl_anim_ptr;
112 
113   for(x = 0; x < MAX_LASERS; x++)
114     if(laser_list[x] != NULL)
115       laser_list[x]->snap_shot();
116 }
117 
draw_laser(tfloor * c_f_ptr,int px,int py)118 void tdroid::draw_laser(tfloor *c_f_ptr, int px, int py)
119 {
120   int x;
121 
122   for(x = 0; x < MAX_LASERS; x++)
123     if(laser_list[x] != NULL)
124       laser_list[x]->draw(c_f_ptr, px, py);
125 }
126 
bg_calc_laser(void)127 void tdroid::bg_calc_laser(void)
128 {
129   int x;
130 
131   for(x = 0; x < MAX_LASERS; x++)
132     if(laser_list[x] != NULL)
133     {
134       laser_list[x]->bg_calc();
135       if(laser_list[x]->state == 2)
136       {
137         delete(laser_list[x]);
138         laser_list[x] = NULL;
139       }
140     }
141 }
142 
143 
draw_droid_ls(int ix,int iy)144 void tdroid::draw_droid_ls(int ix, int iy)
145 {
146   int        i;
147   static int pos[4][2] =
148     {{-2, -19}, {-2, 16}, {-17, -2}, {14, -2}};
149 
150   for(i = 0; i < 4; i++)
151     blit_rect(ix + pos[i][X], iy + pos[i][Y], 3, 3);
152 }
153 
draw_droid(int ix,int iy)154 void tdroid::draw_droid(int ix, int iy)
155 {
156   int x;
157 
158   if(stats.shielding <= (stats.max_shielding >> 3))
159   {
160     glColor4f(1.0, 0.0, 0.0, 0.5);
161     draw_droid_ls(ix, iy);
162     glColor4f(1.0, 0.0, 0.0, fabs(sin(shield_wave_inc)));
163   }
164   else
165     if(stats.shielding <= (stats.max_shielding >> 2))
166     {
167       glColor4f(0.0, 1.0, 0.0, 0.5);
168       draw_droid_ls(ix, iy);
169       glColor4f(0.0, 1.0, 0.0, fabs(sin(shield_wave_inc)));
170     }
171     else
172       glColor4fv(bm_colour);
173 
174   blit_bm(
175     &bm[(int)ss_anim_ptr], ix - SPRITE_HSIZE_X, iy - SPRITE_HSIZE_Y);
176 
177   glColor4fv(bm_colour2);
178   for(x = 0; x < 3; x++)
179     blit_bm(
180       &digit_bm[(int)(stats.type[x] - '0')], ix - 13 + (x << 3), iy - 4);
181 }
182 
draw(tfloor * c_f_ptr,int px,int py)183 void tdroid::draw(tfloor *c_f_ptr, int px, int py)
184 {
185   draw_laser(c_f_ptr, px, py);
186 
187   if(floor_ptr != c_f_ptr)
188     return;
189 
190   switch(state)
191   {
192     case 0: /*running*/
193       draw_droid(
194         (spos_x - px) + SCREEN_HSIZE_X,
195         (spos_y - py) + SCREEN_HSIZE_Y);
196       break;
197 
198     case 1: /*dieing*/
199       glColor4fv(bm_colour);
200       blit_bm(
201         &explosion_bm[(int)ss_expl_anim_ptr],
202         (spos_x - px) + (SCREEN_HSIZE_X - 20),
203         (spos_y - py) + (SCREEN_HSIZE_Y - 20));
204       break;
205   }
206 }
207 
recharge(void)208 void tdroid::recharge(void)
209 {
210   int ix, iy;
211 
212   if(floor_ptr->power_bay == NULL)
213     return;
214 
215   recharge_delay += get_time_lapse();
216   if(recharge_delay <= 1.0)
217     return;
218   recharge_delay =- 1.0;
219 
220   if(stats.max_shielding == stats.shielding)
221     return;
222 
223   ix = ((int)rint(pos_x) + SPRITE_HSIZE_X) - floor_ptr->power_bay->pos_x;
224   iy = ((int)rint(pos_y) + SPRITE_HSIZE_Y) - floor_ptr->power_bay->pos_y;
225   if((ix < 0) || (ix > SPRITE_SIZE_X) || (iy < 0) || (iy > SPRITE_SIZE_Y))
226     return;
227 
228   if(this == droids[0])
229   {
230     if(score > 0)
231     {
232       score--;
233       stats.shielding++;
234       console_message_add("Boost!");
235     }
236   }
237   else
238     stats.shielding++;
239 
240 //  if(cf1)
241 //    sound_engine_cmd(SND_CMD_FX,FX_POWER_UP,0xff,0x80);
242 }
243 
floor_down_test(void)244 void tdroid::floor_down_test(void)
245 {
246   int a, c;
247 
248   for(a = 1, c = 0; a < MAX_DROIDS; a++)
249   {
250     if(droids[a] == NULL)
251       continue;
252 
253     if((floor_ptr == droids[a]->floor_ptr) && !droids[a]->state)
254       c++;
255   }
256 
257   if(!c)
258   {
259     floor_ptr->down = 1;
260     console_message_add("Floor clear");
261   }
262 }
263 
bg_calc(void)264 void tdroid::bg_calc(void)
265 {
266   double spin;
267 
268   spin = (stats.shielding * 0.35) / stats.max_shielding;
269 
270   switch(state)
271   {
272     case 0: /*running*/
273       anim_speed = spin;
274       shield_wave_inc += 0.05 * get_time_lapse();
275       tentity::bg_calc();
276       recharge();
277       break;
278 
279     case 1: /*dieing*/
280       anim_speed = spin;
281       tentity::bg_calc();
282       expl_anim_ptr += expl_anim_speed * get_time_lapse();
283       if(expl_anim_ptr >= expl_anim_len)
284       {
285         state++;
286         floor_down_test();
287       }
288       break;
289   }
290 
291   bg_calc_laser();
292 }
293 
friction(void)294 void tdroid::friction(void)
295 {
296   float x;
297 
298   if(pos_dx > 0.0)
299   {
300     x = pos_dx;
301     if(x > 0.15)
302       x = 0.15;
303     pos_dx -= x;
304   }
305 
306   if(pos_dx < 0.0)
307   {
308     x = pos_dx;
309     if(x < -0.15)
310       x = -0.15;
311     pos_dx -= x;
312   }
313 
314   if(pos_dy > 0.0)
315   {
316     x = pos_dy;
317     if(x > 0.15)
318       x = 0.15;
319     pos_dy -= x;
320   }
321 
322   if(pos_dy < 0.0)
323   {
324     x = pos_dy;
325     if(x < -0.15)
326       x = -0.15;
327     pos_dy -= x;
328   }
329 }
330 
display_nd(void)331 void tdroid::display_nd(void)
332 {
333   char str[STR_LABEL_LEN + 1];
334   int  a, nd = 0;
335 
336   for(a = 1; a < MAX_DROIDS; a++)
337     if(*(droids + a) != NULL)
338       if(!(*(droids + a))->state)
339         nd++;
340 
341   sprintf(str, "droids=%d", nd);
342   console_message_add(str);
343 }
344 
hit(tlaser * l)345 void tdroid::hit(tlaser *l)
346 {
347   char str[STR_LABEL_LEN + 1];
348 
349   pos_dx = l->pos_dx / 4.0;
350   pos_dy = l->pos_dy / 4.0;
351 
352   stats.shielding -= l->damage_factor;
353   if(stats.shielding < 0)
354   {
355     state = 1;
356 
357     sprintf(str, "%s d %s", l->owner->stats.type, stats.type);
358     console_message_add(str);
359 
360     if(this != droids[0])
361       if(!god_mode)
362         score += stats.entry * 25;
363 
364     display_nd();
365 
366 //    if(random() & 1)
367 //      do_sound(FX_EXPLOSION_1,40);
368 //    else
369 //      do_sound(FX_EXPLOSION_2,40);
370   }
371   else
372   {
373     attack_droid = l->owner;
374 
375     sprintf(
376       str, "%s h %s(%d)", l->owner->stats.type, stats.type, stats.shielding);
377     console_message_add(str);
378 
379     if(this != droids[0])
380       if(!god_mode)
381         score += stats.entry;
382 
383 //    do_sound(FX_DROID_HIT_1,50);
384   }
385 }
386