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 * paradroid object routines
25 *
26 ****************************************************************************
27 ****************************************************************************
28 ***************************************************************************/
29 #include "defs.h"
30 #include "protos.p"
31 
32 #include "tparadroid.h"
33 
34 /***************************************************************************
35 *
36 ***************************************************************************/
tparadroid(void)37 tparadroid::tparadroid(void)
38 {
39   memcpy(&stats, &droid_stats[DROID_002], sizeof(tdroid_stats));
40   transferring = 0;
41 
42  /*Rafael Laboissiere*/
43   cascade = 0;
44 
45   captured_droid = NULL;
46   low_shields_trig = 0;
47 }
48 
~tparadroid(void)49 tparadroid::~tparadroid(void)
50 {
51 }
52 
init(tfloor * f,tentity ** dp,float px,float py)53 void tparadroid::init(tfloor *f, tentity **dp, float px, float py)
54 {
55   tentity::init(f, &paradroid_bm[0], dp, 10, px, py);
56 }
57 
draw(void)58 void tparadroid::draw(void)
59 {
60   int        x;
61   static int pos[4][2] =
62      {{-16 + SCREEN_HSIZE_X, -17 + SCREEN_HSIZE_Y},
63       {-17 + SCREEN_HSIZE_X,  15 + SCREEN_HSIZE_Y},
64       { 14 + SCREEN_HSIZE_X,  15 + SCREEN_HSIZE_Y},
65       { 14 + SCREEN_HSIZE_X, -17 + SCREEN_HSIZE_Y}};
66 
67   draw_laser(floor_ptr, (int)pos_x, (int)pos_y);
68 
69   switch(state)
70   {
71     case 0:
72       draw_droid(SCREEN_HSIZE_X, SCREEN_HSIZE_Y);
73 
74       if(transferring)
75       {
76         glColor4f(0.8, 0.8, 0.8, fabs(sin(shield_wave_inc)));
77         for(x = 0; x < 4; x++)
78           blit_rect(pos[x][X], pos[x][Y], 3, 3);
79 
80         if(captured_droid != NULL)
81         {
82           int np, nv;
83 
84           np = SCREEN_HSIZE_X - (44 >> 1);
85 
86           glEnable(GL_LINE_STIPPLE);
87           glLineWidth(5.0);
88           glLineStipple(2, 0xf7f7);
89           glColor3fv(red_pixel[0]);
90           blit_line(
91             SCREEN_HSIZE_X,
92             SCREEN_HSIZE_Y,
93             SCREEN_HSIZE_X + captured_droid->spos_x - spos_x,
94             SCREEN_HSIZE_Y + captured_droid->spos_y - spos_y);
95           glDisable(GL_LINE_STIPPLE);
96 
97           glColor4fv(bm_colour);
98           blit_bm(&neg_bm, np, 50);
99 
100           nv = ((tug1 + -tug2) >> 2) + 20;
101           if(nv < 0) nv = 0;
102           if(nv > 40) nv = 40;
103           nv += 2;
104 
105           glLineWidth(8.0);
106           glLineStipple(1, 0xffff);
107           glColor3fv(green_pixel[0]);
108           blit_rect(np + 2, 61, nv, 3);
109         }
110       }
111       break;
112 
113     case 1:
114       glColor4fv(bm_colour);
115       blit_bm(
116         &explosion_bm[(int)ss_expl_anim_ptr],
117         SCREEN_HSIZE_X - 20, SCREEN_HSIZE_Y - 20);
118       break;
119   }
120 }
121 
within_capt_dist(void)122 int tparadroid::within_capt_dist(void)
123 {
124   int d1, d2;
125 
126   d1 = (int)(captured_droid->pos_x - pos_x);
127   d2 = (int)(captured_droid->pos_y - pos_y);
128   if(((d1 * d1) + (d2 * d2)) > (100 * 100))
129   {
130     captured_droid->captured = 0;
131     captured_droid = NULL;
132     return 0;
133   }
134 
135   return 1;
136 }
137 
bg_calc(void)138 void tparadroid::bg_calc(void)
139 {
140   static float handicap[10] =
141     {6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.2, 3.0, 2.7, 2.5};
142 
143   tdroid::bg_calc();
144 
145   if(!state)
146   {
147     friction();
148 
149     if(stats.shielding <= (stats.max_shielding >> 2))
150     {
151       if(!low_shields_trig)
152       {
153         low_shields_trig = 25;
154 //        sound_engine_cmd(SND_CMD_FX,FX_LOW_SHIELDS,0xff,0x80);
155       }
156       else
157         low_shields_trig--;
158     }
159 
160     if(captured_droid != NULL)
161     {
162       if(!within_capt_dist())
163         console_message_add("lost contact");
164       else
165       {
166         if(captured_droid->state)
167         {
168           console_message_add("Forced detach");
169           captured_droid = NULL;
170         }
171         else
172         {
173           int tt;
174 
175           tug1 +=
176             (int)rint(handicap[stats.entry] *
177             (float)stats.entry * ((float)random() / RAND_MAX));
178 
179           tug2 +=
180             (int)rint(2.0 * (float)captured_droid->stats.entry *
181            ((float)random() / RAND_MAX));
182 
183           tt = tug1 + -tug2;
184           if(tt <= -80)
185           {
186             console_message_add("Burn out!");
187             state = 1;
188             captured_droid = NULL;
189 //            do_sound(FX_EXPLOSION_1,40);
190           }
191           else
192           {
193             if(tt >= 80)
194             {
195               float tx, ty, tdx, tdy;
196 
197               if(!god_mode)
198                 score += captured_droid->stats.entry * 50;
199 
200               memcpy(&stats,
201                 &(captured_droid->stats), sizeof(tdroid_stats));
202               tx = pos_x;
203               ty = pos_y;
204               tdx = pos_dx;
205               tdy = pos_dy;
206               pos_x = captured_droid->pos_x;
207               pos_y = captured_droid->pos_y;
208               pos_dx = captured_droid->pos_dx;
209               pos_dy = captured_droid->pos_dy;
210               captured_droid->pos_x = tx;
211               captured_droid->pos_y = ty;
212               captured_droid->pos_dx = tdx;
213               captured_droid->pos_dy = tdy;
214               captured_droid->state = 1;
215               captured_droid = NULL;
216 //              do_sound(FX_EXPLOSION_1,40);
217 //              do_sound(FX_POWER_UP,40);
218 
219              /*Rafael Laboissiere*/
220               if(!cascade)
221                 transferring = 0;
222 
223               console_message_add("Transferred!!");
224               tdroid::display_nd();
225             }
226           }
227         }
228       }
229     }
230   }
231 }
232 
capture_droid(int cx,int cy)233 void tparadroid::capture_droid(int cx, int cy)
234 {
235   int  x;
236   char str[STR_LABEL_LEN + 1];
237 
238   for(x = 0; x < MAX_DROIDS; x++)
239     if(*(droids + x) != NULL)
240     {
241       if((*(droids + x) != this) && !(*(droids + x))->state &&
242         ((*(droids + x))->floor_ptr == floor_ptr))
243       {
244         float ix, iy;
245 
246         ix = cx - (*(droids + x))->pos_x + SPRITE_HSIZE_X;
247         iy = cy - (*(droids + x))->pos_y + SPRITE_HSIZE_Y;
248         if((ix >= 0) && (ix < SPRITE_SIZE_X) &&
249            (iy >= 0) && (iy < SPRITE_SIZE_Y))
250         {
251           captured_droid = (tparadroid *)*(droids + x);
252           captured_droid->captured = 1;
253           tug1 = tug2 = 0;
254 
255           if(within_capt_dist())
256             sprintf(str,"%s captured", captured_droid->stats.type);
257           else
258           {
259             sprintf(str,"Out of range");
260 //            sound_engine_cmd(SND_CMD_FX,FX_NO_WEAPON,0xff,0x80);
261           }
262           console_message_add(str);
263           return;
264         }
265       }
266     }
267     else
268       break;
269 
270   console_message_add("Empty Space");
271 //  sound_engine_cmd(SND_CMD_FX,FX_NO_WEAPON,0xff,0x80);
272 }
273 
action(tkevent * kp)274 int tparadroid::action(tkevent *kp)
275 {
276   int         s = 0;
277   static char *no_weapon_mess = "No weapon!";
278 
279   if(state)
280     return 0;
281 
282   switch(kp->type)
283   {
284     case MOUSE_EVENT:
285       switch(kp->val)
286       {
287         case GLUT_LEFT_BUTTON:
288           if(transferring)
289           {
290             if(captured_droid == NULL)
291               capture_droid(
292                 kp->mouse_x + ((int)pos_x - SCREEN_HSIZE_X),
293                 kp->mouse_y + ((int)pos_y - SCREEN_HSIZE_Y));
294           }
295           else
296           {
297             if(stats.armament)
298             {
299               create_laser(
300                 (kp->mouse_x - SCREEN_HSIZE_X),
301                 (kp->mouse_y - SCREEN_HSIZE_Y));
302             }
303             else
304               console_message_add(no_weapon_mess);
305 //              sound_engine_cmd(SND_CMD_FX,FX_NO_WEAPON,0xff,0x80);
306           }
307           break;
308 
309         case GLUT_RIGHT_BUTTON:
310           if(!transferring)
311           {
312             if(stats.armament)
313             {
314               create_laser(-10000,     0);
315               create_laser( 10000,     0);
316               create_laser(     0,-10000);
317               create_laser(     0, 10000);
318               create_laser(-10000,-10000);
319               create_laser( 10000,-10000);
320               create_laser(-10000, 10000);
321               create_laser( 10000, 10000);
322             }
323             else
324               console_message_add(no_weapon_mess);
325           }
326           break;
327       }
328       break;
329 
330     case KEYBOARD_EVENT:
331       switch(kp->val)
332       {
333         case KEY_STATUS:
334           display_nd();
335 //          sound_engine_cmd(SND_CMD_FX,FX_SELECT,0xff,0x80);
336           break;
337 
338        /*Rafael Laboissiere*/
339         case KEY_CASCADE_MODE:
340           cascade = 1;
341 
342         case KEY_TRANSFER_MODE:
343           if(captured_droid == NULL)
344           {
345             transferring ^= 1;
346             if(transferring)
347             {
348 //              sound_engine_cmd(SND_CMD_FX,FX_SELECT,0xff,0x80);
349             }
350             else
351             {
352              /*Rafael Laboissiere*/
353               cascade = 0;
354 //              sound_engine_cmd(SND_CMD_FX,FX_WEAPON_RELOAD,0xff,0x80);
355             }
356           }
357           else
358           {
359             console_message_add("You're commited!");
360 //            sound_engine_cmd(SND_CMD_FX,FX_NO_WEAPON,0xff,0x80);
361           }
362           break;
363 
364         case KEY_SELECT:
365           if(captured_droid != NULL)
366           {
367             console_message_add("Can't trans.");
368 //            sound_engine_cmd(SND_CMD_FX,FX_NO_WEAPON,0xff,0x80);
369           }
370           else
371           {
372             int x, rpx, rpy;
373 
374             rpx = spos_x + SPRITE_HSIZE_X;
375             rpy = spos_y + SPRITE_HSIZE_Y;
376 
377             for(x = 0; x < MAX_TRANSPORTS; x++)
378               if(floor_ptr->transport[x].x != -1)
379               {
380                 int ix, iy;
381 
382                 ix = rpx - floor_ptr->transport[x].x;
383                 iy = rpy - floor_ptr->transport[x].y;
384                 if((ix >= 0) && (ix < SPRITE_SIZE_X) &&
385                    (iy >= 0) && (iy < SPRITE_SIZE_Y))
386                 {
387                   pos_dx = 0;
388                   pos_dy = 0;
389                   s = 1;
390 //                  sound_engine_cmd(SND_CMD_FX,FX_SELECT,0xff,0x80);
391                   break;
392                 }
393               }
394 
395             if(floor_ptr->console.x != -1)
396             {
397               int ix, iy;
398 
399               ix = rpx - floor_ptr->console.x;
400               iy = rpy - floor_ptr->console.y;
401               if((ix >= 0) && (ix < SPRITE_SIZE_X) &&
402                  (iy >= 0) && (iy < SPRITE_SIZE_Y))
403               {
404                 pos_dx = 0;
405                 pos_dy = 0;
406                 s = 2;
407 //                sound_engine_cmd(SND_CMD_FX,FX_SELECT,0xff,0x80);
408                 break;
409               }
410             }
411           }
412           break;
413       }
414       break;
415 
416     case SPECIAL_EVENT:
417       switch(kp->val)
418       {
419         case GLUT_KEY_UP:
420           pos_dx = 0;
421           pos_dy = -stats.speed;
422           break;
423 
424         case GLUT_KEY_DOWN:
425           pos_dx = 0;
426           pos_dy = stats.speed;
427           break;
428 
429         case GLUT_KEY_LEFT:
430           pos_dx = -stats.speed;
431           pos_dy = 0;
432           break;
433 
434         case GLUT_KEY_RIGHT:
435           pos_dx = stats.speed;
436           pos_dy = 0;
437           break;
438       }
439       break;
440   }
441 
442   return s;
443 }
444 
display_nd(void)445 void tparadroid::display_nd(void)
446 {
447   char str[STR_LABEL_LEN + 1];
448 
449   sprintf(str,"Shield=%d", stats.shielding);
450   console_message_add(str);
451   tdroid::display_nd();
452 }
453 
hit(tlaser * l)454 void tparadroid::hit(tlaser *l)
455 {
456   char str[STR_LABEL_LEN + 1];
457 
458   if(!god_mode)
459   {
460     tdroid::hit(l);
461     return;
462   }
463 
464   sprintf(
465     str, "%s h %s(god)", l->owner->stats.type, stats.type);
466   console_message_add(str);
467 
468 //  do_sound(FX_DROID_HIT_1,50);
469 }
470