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, ¶droid_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