]> 4ch.mooo.com Git - 16.git/blob - 16/cawat/C5_ACT2.C
fd8633a29c296ced7891b8d2dccbd0ef60d44de3
[16.git] / 16 / cawat / C5_ACT2.C
1 /* Catacomb Armageddon Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\r
4  * This program is free software; you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation; either version 2 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along\r
15  * with this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
17  */\r
18 \r
19 // C3_PLAY.C\r
20 \r
21 #include "DEF.H"\r
22 #pragma hdrstop\r
23 \r
24 /*\r
25 =============================================================================\r
26 \r
27                                                  LOCAL CONSTANTS\r
28 \r
29 =============================================================================\r
30 */\r
31 void SpawnSkeleton(int tilex, int tiley);\r
32 \r
33 #if 0\r
34 #define MSHOTDAMAGE     2\r
35 #define MSHOTSPEED      10000\r
36 \r
37 #define ESHOTDAMAGE     1\r
38 #define ESHOTSPEED      5000\r
39 \r
40 #define SSHOTDAMAGE     3\r
41 #define SSHOTSPEED      6500\r
42 \r
43 #define RANDOM_ATTACK 20\r
44 #endif\r
45 \r
46 /*\r
47 =============================================================================\r
48 \r
49                                                  GLOBAL VARIABLES\r
50 \r
51 =============================================================================\r
52 */\r
53 \r
54 boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);\r
55 void T_ShootPlayer(objtype *ob);\r
56 \r
57 /*\r
58 =============================================================================\r
59 \r
60                                                  LOCAL VARIABLES\r
61 \r
62 =============================================================================\r
63 */\r
64 \r
65 \r
66 \r
67 /*\r
68 =============================================================================\r
69 \r
70                                                                 SKELETON IN WALL\r
71 \r
72 =============================================================================\r
73 */\r
74 \r
75 void T_WallSkeleton(objtype *ob);\r
76 \r
77 statetype s_wallskel = {0,40,T_WallSkeleton,&s_wallskel};\r
78 statetype s_wallskel2 = {0,1,NULL,NULL};\r
79 \r
80 \r
81 enum wskel_modes {ws_wall1,ws_wall2,ws_wall3,ws_exit};\r
82 //enum wskel_modes {ws_wall1,ws_exit};\r
83 \r
84 #define wskel_mode      ob->temp1\r
85 #define wskel_delay     ob->temp2\r
86 #define wskel_base      ob->angle\r
87 #define wskel_wallx     ob->hitpoints\r
88 #define wskel_wally     ob->speed\r
89 \r
90 /*\r
91 ===============\r
92 =\r
93 = SpawnWallSkeleton\r
94 =\r
95 ===============\r
96 */\r
97 void SpawnWallSkeleton(int tilex, int tiley)\r
98 {\r
99         char xofs[] = {0,0,-1,+1};\r
100         char yofs[] = {-1,+1,0,0};\r
101 \r
102         objtype *ob;\r
103         int wallx=tilex,wally=tiley,wallbase,wallmode,loop;\r
104         unsigned tile,current_delay;\r
105 \r
106         for (loop=0; loop<4; loop++)\r
107         {\r
108                 tile = *(mapsegs[0]+farmapylookup[tiley+yofs[loop]]+tilex+xofs[loop]);\r
109                 switch (tile)\r
110                 {\r
111 //                      case WALL_SKELETON_CODE:\r
112 //                      case WALL_SKELETON_CODE+1:\r
113 //                      case WALL_SKELETON_CODE+2:\r
114 //                              wallmode = ws_wall1+(tile-WALL_SKELETON_CODE);\r
115 //                              wallbase = WALL_SKELETON_CODE;\r
116 //                              goto foundtile;\r
117 //                      break;\r
118 \r
119                         case 66:\r
120                         case 68:\r
121 //                      case 21:\r
122                                 wallmode = ws_wall1+(tile-66);\r
123                                 wallbase = 66;\r
124                                 goto foundtile;\r
125 //                      break;\r
126 \r
127                         case 67:\r
128                         case 69:\r
129                                 wallmode = ws_wall1+(tile-67);\r
130                                 wallbase = 67;\r
131                                 goto foundtile;\r
132 //                      break;\r
133                 }\r
134         }\r
135 \r
136         return;\r
137 foundtile:;\r
138 \r
139         wallx += xofs[loop];\r
140         wally += yofs[loop];\r
141 \r
142         SpawnNewObj(tilex,tiley,&s_wallskel,PIXRADIUS*35);\r
143         ob = new;\r
144         new->obclass = wallskelobj;\r
145         new->speed = 1900;\r
146         new->flags &= ~of_shootable;\r
147         new->hitpoints = 12;\r
148 \r
149 //      new->tilex = wallx;\r
150 //      new->tiley = wally;\r
151         wskel_wallx = wallx;\r
152         wskel_wally = wally;\r
153         wskel_base = wallbase;\r
154         new->active = no;\r
155 \r
156         wskel_mode = wallmode;\r
157 \r
158         tile = *(mapsegs[2]+farmapylookup[wally]+wallx);\r
159         if (tile)\r
160                 wskel_delay = (tile>>8)*30;\r
161         else\r
162         {\r
163                 current_delay = (2*60)+random(4*60);\r
164                 wskel_delay = zombie_base_delay+current_delay;\r
165                 zombie_base_delay += current_delay;\r
166                 if (zombie_base_delay > 8*60)\r
167                         zombie_base_delay = 0;\r
168         }\r
169 }\r
170 \r
171 /*\r
172 ===============\r
173 =\r
174 = T_WallSkeleton\r
175 =\r
176 ===============\r
177 */\r
178 void T_WallSkeleton(objtype *ob)\r
179 {\r
180         int x=wskel_wallx,y=wskel_wally;\r
181 \r
182         wskel_delay -= realtics;\r
183         if (wskel_delay > 0)\r
184                 return;\r
185 \r
186         switch (wskel_mode)\r
187         {\r
188                 case ws_wall2:\r
189                         if ((wskel_base == 66) || (wskel_base == 67))\r
190                                 wskel_mode++;\r
191                 case ws_wall1:\r
192                 case ws_wall3:\r
193                         (unsigned)actorat[x][y]\r
194                                 = tilemap[x][y]\r
195                                 = *(mapsegs[0]+farmapylookup[y]+x)\r
196                                 = wskel_base+(wskel_mode-ws_wall1);\r
197 \r
198                         wskel_mode++;\r
199                         wskel_delay = (120);\r
200                         ob->active = always;\r
201                 break;\r
202 \r
203                 case ws_exit:\r
204                         (unsigned)actorat[x][y]\r
205                                 = tilemap[x][y]\r
206                                 = *(mapsegs[0]+farmapylookup[y]+x)\r
207                                 = 21;\r
208 //                              = wskel_base;\r
209                         ob->tilex = ob->x >> TILESHIFT;\r
210                         ob->tiley = ob->y >> TILESHIFT;\r
211 \r
212                         ob->obclass = skeletonobj;\r
213                         ob->speed = 2036;\r
214                         ob->flags |= of_shootable;\r
215                         ob->hitpoints = 12;\r
216                         ob->state = &s_skel_1;\r
217                         ob->ticcount = ob->state->tictime;\r
218                 break;\r
219         }\r
220 }\r
221 \r
222 \r
223 /*\r
224 =============================================================================\r
225 \r
226                                                                 SKELETONS\r
227 \r
228 =============================================================================\r
229 */\r
230 \r
231 void T_Skeleton(objtype *ob);\r
232 \r
233 \r
234 \r
235 \r
236 statetype s_skel_pause = {SKELETON_1PIC,40,NULL,&s_skel_2};\r
237 \r
238 statetype s_skel_1 = {SKELETON_1PIC,10,T_Skeleton,&s_skel_2};\r
239 statetype s_skel_2 = {SKELETON_2PIC,10,T_Skeleton,&s_skel_3};\r
240 statetype s_skel_3 = {SKELETON_3PIC,10,T_Skeleton,&s_skel_4};\r
241 statetype s_skel_4 = {SKELETON_4PIC,10,T_Skeleton,&s_skel_1};\r
242 \r
243 statetype s_skel_attack1 = {SKELETON_ATTACK_1PIC,12,NULL,&s_skel_attack2};\r
244 statetype s_skel_attack2 = {SKELETON_ATTACK_2PIC,12,NULL,&s_skel_attack3};\r
245 statetype s_skel_attack3 = {SKELETON_ATTACK_3PIC,12,T_DoDamage,&s_skel_pause};\r
246 \r
247 statetype s_skel_ouch = {SKELETON_OUCHPIC,8,NULL,&s_skel_1};\r
248 \r
249 statetype s_skel_die1 = {SKELETON_OUCHPIC,18,NULL,&s_skel_die2};\r
250 statetype s_skel_die2 = {SKELETON_DEATH_1PIC,18,NULL,&s_skel_die3};\r
251 statetype s_skel_die3 = {SKELETON_DEATH_2PIC,18,NULL,&s_skel_die3};\r
252 \r
253 /*\r
254 ===============\r
255 =\r
256 = SpawnSkeleton\r
257 =\r
258 ===============\r
259 */\r
260 void SpawnSkeleton(int tilex, int tiley)\r
261 {\r
262         SpawnNewObj(tilex,tiley,&s_skel_1,PIXRADIUS*35);\r
263         new->obclass = skeletonobj;\r
264         new->speed = 2036;\r
265         new->flags |= of_shootable;\r
266         new->hitpoints = EasyHitPoints(12);\r
267 }\r
268 \r
269 \r
270 /*\r
271 ===============\r
272 =\r
273 = T_Skeleton\r
274 =\r
275 ===============\r
276 */\r
277 \r
278 void T_Skeleton(objtype *ob)\r
279 {\r
280         if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
281         {\r
282                 ob->state = &s_skel_attack1;\r
283                 ob->ticcount = ob->state->tictime;\r
284                 return;\r
285         }\r
286 }\r
287 \r
288 /*\r
289 =============================================================================\r
290 \r
291                                                                 EYE\r
292 \r
293 =============================================================================\r
294 */\r
295 \r
296 void T_EyeMage (objtype *ob);\r
297 boolean T_EyeShoot (objtype *ob, boolean eyeshot);\r
298 void T_EyeShootPlayer (objtype *ob);\r
299 \r
300 extern statetype s_eye_shootplayer_1;\r
301 extern statetype s_eye_shootplayer_2;\r
302 \r
303 statetype s_eye_pause = {EYE_WALK1PIC,40,NULL,&s_eye_2};\r
304 \r
305 statetype s_eye_1 = {EYE_WALK1PIC,20,T_EyeMage,&s_eye_2};\r
306 statetype s_eye_2 = {EYE_WALK2PIC,20,T_EyeMage,&s_eye_3};\r
307 statetype s_eye_3 = {EYE_WALK3PIC,20,T_EyeMage,&s_eye_4};\r
308 statetype s_eye_4 = {EYE_WALK2PIC,20,T_EyeMage,&s_eye_1};\r
309 statetype s_eye_shootplayer_1 = {EYE_SCOWLPIC,1,T_EyeShootPlayer,&s_eye_shootplayer_2};\r
310 statetype s_eye_shootplayer_2 = {EYE_SCOWLPIC,20,NULL,&s_eye_1};\r
311 \r
312 statetype s_eye_ouch = {EYE_OUCH1PIC,8,NULL,&s_eye_ouch2};\r
313 statetype s_eye_ouch2 = {EYE_OUCH2PIC,8,NULL,&s_eye_1};\r
314 \r
315 statetype s_eye_die1 = {EYE_DEATH1PIC,22,NULL,&s_eye_die2};\r
316 statetype s_eye_die2 = {EYE_DEATH2PIC,22,NULL,&s_eye_die3};\r
317 statetype s_eye_die3 = {EYE_DEATH2PIC,22,NULL,NULL};\r
318 \r
319 extern statetype s_eshot2;\r
320 \r
321 statetype s_eshot1 = {EYE_SHOT1PIC,8,&T_ShootPlayer,&s_eshot2};\r
322 statetype s_eshot2 = {EYE_SHOT2PIC,8,&T_ShootPlayer,&s_eshot1};\r
323 \r
324 #define eye_mode        ob->temp1\r
325 #define eye_delay       ob->temp2\r
326 \r
327 \r
328 //-------------------------------------------------------------------------\r
329 // SpawnEye()\r
330 //-------------------------------------------------------------------------\r
331 void SpawnEye(int tilex, int tiley)\r
332 {\r
333         objtype *ob;\r
334 \r
335         SpawnNewObj(tilex,tiley,&s_eye_1,PIXRADIUS*35);\r
336         ob = new;\r
337         new->obclass = eyeobj;\r
338         new->speed = 1200;\r
339         new->flags |= of_shootable;\r
340         new->hitpoints = EasyHitPoints(15);\r
341         eye_mode = em_other1;\r
342 }\r
343 \r
344 \r
345 //---------------------------------------------------------------------------\r
346 // T_EyeShootPlayer\r
347 //---------------------------------------------------------------------------\r
348 void T_EyeShootPlayer (objtype *ob)\r
349 {\r
350         ShootPlayer(ob,eshotobj,ESHOTSPEED,&s_eshot1);\r
351 }\r
352 \r
353 \r
354 /*\r
355 =============================================================================\r
356 \r
357                                         SUCCUBUS\r
358 \r
359 =============================================================================\r
360 */\r
361 \r
362 void T_Succubus (objtype *ob);\r
363 void T_SuccubusShot (objtype *ob);\r
364 \r
365 extern statetype s_succubus_pause;\r
366 extern statetype s_succubus_walk1;\r
367 extern statetype s_succubus_walk2;\r
368 extern statetype s_succubus_walk3;\r
369 extern statetype s_succubus_walk4;\r
370 extern statetype s_succubus_shot1;\r
371 extern statetype s_succubus_attack1;\r
372 extern statetype s_succubus_attack2;\r
373 extern statetype s_succubus_attack3;\r
374 extern statetype s_succubus_death1;\r
375 extern statetype s_succubus_death2;\r
376 \r
377 statetype s_succubus_pause = {SUCCUBUS_WALK2PIC,10,NULL,&s_succubus_walk3};\r
378 \r
379 statetype s_succubus_walk1 = {SUCCUBUS_WALK1PIC,10,T_EyeMage,&s_succubus_walk2};\r
380 statetype s_succubus_walk2 = {SUCCUBUS_WALK2PIC,10,T_EyeMage,&s_succubus_walk3};\r
381 statetype s_succubus_walk3 = {SUCCUBUS_WALK3PIC,10,T_EyeMage,&s_succubus_walk4};\r
382 statetype s_succubus_walk4 = {SUCCUBUS_WALK4PIC,10,T_EyeMage,&s_succubus_walk1};\r
383 \r
384 statetype s_succubus_attack1 = {SUCCUBUS_ATTACK1PIC,15,NULL,&s_succubus_attack2};\r
385 statetype s_succubus_attack2 = {SUCCUBUS_ATTACK1PIC,-1,T_SuccubusShot,&s_succubus_attack3};\r
386 statetype s_succubus_attack3 = {SUCCUBUS_ATTACK2PIC,15,NULL,&s_succubus_pause};\r
387 \r
388 statetype s_succubus_ouch = {SUCCUBUS_OUCHPIC,15,NULL,&s_succubus_walk1};\r
389 \r
390 statetype s_succubus_death1 = {SUCCUBUS_DEATH1PIC,55,NULL,&s_succubus_death2};\r
391 statetype s_succubus_death2 = {SUCCUBUS_DEATH2PIC,20,NULL,&s_succubus_death2};\r
392 \r
393 statetype s_succubus_shot1 = {SUCCUBUS_SHOT1PIC,12,&T_ShootPlayer,&s_succubus_shot1};\r
394 \r
395 /*\r
396 ===============\r
397 =\r
398 = SpawnSuccubus\r
399 =\r
400 ===============\r
401 */\r
402 \r
403 void SpawnSuccubus (int tilex, int tiley)\r
404 {\r
405         SpawnNewObj(tilex,tiley,&s_succubus_walk1,PIXRADIUS*30);\r
406         new->obclass = succubusobj;\r
407         new->speed = 2500;\r
408         new->flags |= of_shootable;\r
409         new->hitpoints = EasyHitPoints(12);\r
410 }\r
411 \r
412 /*\r
413 ===============\r
414 =\r
415 = T_SuccubusShot\r
416 =\r
417 ===============\r
418 */\r
419 \r
420 void T_SuccubusShot (objtype *ob)\r
421 {\r
422         ShootPlayer(ob,sshotobj,ob->temp1 ? MSHOTSPEED : SSHOTSPEED,&s_succubus_shot1);\r
423 //      ob->state = &s_succubus_attack3;\r
424 //      ob->ticcount = ob->temp1 ? 7 : ob->state->tictime;\r
425 }\r
426 \r
427 \r
428 /*\r
429 =============================================================================\r
430 \r
431                                                         MAGE\r
432 \r
433 =============================================================================\r
434 */\r
435 \r
436 \r
437 void T_MageShoot (objtype *ob);\r
438 \r
439 extern  statetype s_magepause;\r
440 \r
441 extern  statetype s_mage1;\r
442 extern  statetype s_mage2;\r
443 \r
444 extern  statetype s_mageattack1;\r
445 extern  statetype s_mageattack2;\r
446 extern  statetype s_mageattack3;\r
447 \r
448 extern  statetype s_mageouch;\r
449 \r
450 extern  statetype s_magedie1;\r
451 extern  statetype s_magedie2;\r
452 \r
453 \r
454 statetype s_magepause = {MAGE1PIC,10,NULL,&s_mage2};\r
455 \r
456 statetype s_mage1 = {MAGE1PIC,20,T_EyeMage,&s_mage2};\r
457 statetype s_mage2 = {MAGE2PIC,20,T_EyeMage,&s_mage1};\r
458 \r
459 //statetype s_mageattack1 = {MAGEATTACKPIC,20,NULL,&s_mageattack2};\r
460 //statetype s_mageattack2 = {MAGEATTACKPIC,-1,T_MageShoot,&s_mageattack3};\r
461 statetype s_mageattack3 = {MAGEATTACKPIC,30,NULL,&s_magepause};\r
462 \r
463 statetype s_mageouch = {MAGEOUCHPIC,10,NULL,&s_mage1};\r
464 \r
465 statetype s_magedie1 = {MAGEDIE1PIC,20,NULL,&s_magedie2};\r
466 statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};\r
467 \r
468 \r
469 statetype s_mshot1 = {PSHOT1PIC,8,&T_ShootPlayer,&s_mshot2};\r
470 statetype s_mshot2 = {PSHOT2PIC,8,&T_ShootPlayer,&s_mshot1};\r
471 \r
472 /*\r
473 ===============\r
474 =\r
475 = SpawnMage\r
476 =\r
477 ===============\r
478 */\r
479 \r
480 void SpawnMage (int tilex, int tiley)\r
481 {\r
482         SpawnNewObj(tilex,tiley,&s_mage1,PIXRADIUS*35);\r
483         new->obclass = mageobj;\r
484         new->speed = 3072;\r
485         new->flags |= of_shootable;\r
486         new->hitpoints = EasyHitPoints(12);\r
487 }\r
488 \r
489 \r
490 /*\r
491 ===============\r
492 =\r
493 = T_EyeMage\r
494 =\r
495 = **********\r
496 = ***NOTE*** This routine controls the thinks for the Eye, Mage, and Succubus.\r
497 = **********\r
498 =\r
499 ===============\r
500 */\r
501 \r
502 void T_EyeMage (objtype *ob)\r
503 {\r
504         fixed tempx,tempy;\r
505         unsigned temp_tilex,temp_tiley;\r
506         int angle;\r
507 \r
508         eye_delay -= realtics;\r
509         if (eye_delay < 0)\r
510         {\r
511                 eye_mode = random(em_dummy);\r
512                 eye_delay = (10*60);\r
513         }\r
514 \r
515         tempx = player->x;\r
516         tempy = player->y;\r
517         temp_tilex = player->tilex;\r
518         temp_tiley = player->tiley;\r
519 \r
520 \r
521         switch (eye_mode)\r
522         {\r
523                 case em_other1:\r
524                 case em_other2:\r
525                 case em_other3:\r
526                 case em_other4:\r
527                         player->x = ((long)other_x[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;\r
528                         player->y = ((long)other_y[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;\r
529                         player->tilex = other_x[eye_mode];\r
530                         player->tiley = other_y[eye_mode];\r
531                 break;\r
532         }\r
533 \r
534         if (Chase(ob,true))\r
535                 eye_delay = 0;\r
536 \r
537         player->x = tempx;\r
538         player->y = tempy;\r
539         player->tilex = temp_tilex;\r
540         player->tiley = temp_tiley;\r
541 \r
542 \r
543         if (ob->obclass == mageobj)                                     // do the mage shot\r
544         {\r
545                 if (!random(10))\r
546                         if (ShootPlayer(ob,mshotobj,MSHOTSPEED,&s_mshot1))\r
547                         {\r
548                                 ob->state = &s_mageattack3;\r
549                                 ob->ticcount = ob->state->tictime;\r
550                         }\r
551         }\r
552         else\r
553                 if (ob->obclass == succubusobj)                         // do the succubus shot\r
554                 {\r
555                         angle = AngleNearPlayer(ob);        // make sure angle is correct\r
556                                                                                                                         //          - see AngleNearPlayer\r
557                         if (!random(5) && (angle != -1))   // if correct angle and random # attack\r
558                         {\r
559                                 ob->state = &s_succubus_attack1;    // change state to attack\r
560                                 ob->ticcount = ob->state->tictime;      // init ticcount - otherwise\r
561                         }                                                                                                       //  object may get hung in a\r
562                 }                                                                                                               //  endless state\r
563 \r
564                 else\r
565                 {\r
566                         angle = AngleNearPlayer(ob);                    // do the eye shot\r
567 \r
568                         if (!random(2) && (angle != -1))\r
569                         {\r
570                                 ob->state = &s_eye_shootplayer_1;\r
571                                 ob->ticcount = ob->state->tictime;\r
572                         }\r
573                 }\r
574 \r
575 }\r
576 \r
577 \r
578 /*\r
579 =============================================================================\r
580 \r
581                                         BUNNY\r
582 \r
583 =============================================================================\r
584 */\r
585 \r
586 void T_HarmlessBunnyWalk(objtype *ob);\r
587 void T_Bunny(objtype *ob);\r
588 \r
589 extern statetype s_bunny_left1;\r
590 extern statetype s_bunny_left2;\r
591 extern statetype s_bunny_left3;\r
592 extern statetype s_bunny_right1;\r
593 extern statetype s_bunny_right2;\r
594 extern statetype s_bunny_right3;\r
595 extern statetype s_bunny_meta1;\r
596 extern statetype s_bunny_meta2;\r
597 extern statetype s_bunny_walk1;\r
598 extern statetype s_bunny_walk2;\r
599 extern statetype s_bunny_attack1;\r
600 extern statetype s_bunny_attack2;\r
601 extern statetype s_bunny_pause;\r
602 extern statetype s_bunny_death1;\r
603 extern statetype s_bunny_death2;\r
604 extern statetype s_bunny_death3;\r
605 \r
606 statetype s_bunny_left1 = {BUNNY_LEFT1PIC, 55, NULL, &s_bunny_left2};\r
607 statetype s_bunny_left2 = {BUNNY_LEFT1PIC, 10, T_HarmlessBunnyWalk, &s_bunny_left1};\r
608 statetype s_bunny_left3 = {BUNNY_LEFT2PIC, 30, NULL, &s_bunny_left1};\r
609 \r
610 statetype s_bunny_right1 = {BUNNY_RIGHT1PIC, 55, NULL, &s_bunny_right2};\r
611 statetype s_bunny_right2 = {BUNNY_RIGHT1PIC, 10, T_HarmlessBunnyWalk, &s_bunny_right1};\r
612 statetype s_bunny_right3 = {BUNNY_RIGHT2PIC, 30, NULL, &s_bunny_right1};\r
613 \r
614 statetype s_bunny_meta1 = {BUNNY_META1PIC, 30, NULL, &s_bunny_meta2};\r
615 statetype s_bunny_meta2 = {BUNNY_META2PIC, 30, NULL, &s_bunny_walk1};\r
616 \r
617 statetype s_bunny_walk1 = {BUNNY_WALK1PIC, 25, T_Bunny, &s_bunny_walk2};\r
618 statetype s_bunny_walk2 = {BUNNY_WALK2PIC, 25, T_Bunny, &s_bunny_walk1};\r
619 \r
620 statetype s_bunny_attack1 = {BUNNY_WALK1PIC, 25, NULL, &s_bunny_attack2};\r
621 statetype s_bunny_attack2 = {BUNNY_WALK2PIC, 25, T_DoDamage, &s_bunny_walk1};\r
622 \r
623 statetype s_bunny_ouch = {BUNNY_OUCHPIC, 30, NULL, &s_bunny_pause};\r
624 statetype s_bunny_pause = {BUNNY_WALK1PIC, 50, T_Bunny, &s_bunny_walk2};\r
625 \r
626 statetype s_bunny_death1 = {BUNNY_OUCHPIC, 40, NULL, &s_bunny_death2};\r
627 statetype s_bunny_death2 = {BUNNY_DEATH1PIC, 50, NULL, &s_bunny_death3};\r
628 statetype s_bunny_death3 = {BUNNY_DEATH2PIC, 20, NULL, &s_bunny_death3};\r
629 \r
630 \r
631 #define bunny_dir_hop   ob->temp1\r
632 #define bunny_delay     ob->temp2\r
633 #define LEFTSIDE        0x8             // 1=left 0=right --side showing\r
634 \r
635 /*\r
636 ===============\r
637 =\r
638 = SpawnBunny\r
639 =\r
640 ===============\r
641 */\r
642 \r
643 void SpawnBunny (int tilex, int tiley)\r
644 {\r
645         SpawnNewObj(tilex,tiley,&s_bunny_left1,PIXRADIUS*35);\r
646         new->obclass =  hbunnyobj;\r
647         new->speed = 1947;\r
648         new->temp1 = (random(3))+2;\r
649         new->temp2 = random(30);\r
650         new->flags &= ~of_shootable;\r
651         new->flags |= LEFTSIDE;                         //left side showing}\r
652 }\r
653 \r
654 /*\r
655 ===============\r
656 =\r
657 = T_HarmlessBunnyWalk\r
658 =\r
659 ===============\r
660 */\r
661 \r
662 \r
663 void T_HarmlessBunnyWalk(objtype *ob)\r
664 {\r
665         int valid_dir[8][2] = {{6,5}, {7,6}, {4,7}, {5,4}, {3,2}, {0,3}, {1,0}, {2,1}};\r
666         long move;\r
667         dirtype player_dir;\r
668         fixed old_x, old_y;\r
669         unsigned old_tilex, old_tiley;\r
670         long old_distance;\r
671 \r
672 \r
673         ob->temp2 -= realtics;\r
674         if (ob->temp2 <= 0)\r
675         {\r
676                 if (CheckHandAttack(ob))\r
677                 {\r
678                         ob->temp2 = -1;\r
679                         return;\r
680                 }\r
681 \r
682                 actorat[ob->tilex][ob->tiley] = 0;\r
683                 ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;\r
684                 ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;\r
685                 ob->distance = TILEGLOBAL;\r
686                 ob->state = &s_bunny_meta1;\r
687                 ob->ticcount = ob->state->tictime;\r
688                 ob->obclass = bunnyobj;\r
689                 ob->flags |= of_shootable;\r
690                 ob->hitpoints = EasyHitPoints(10);\r
691                 ob->dir = nodir;\r
692                 ChaseThink(ob,true);                                    // JTR - testing..\r
693                 return;\r
694         }\r
695 \r
696         // The direction of the player isn't updated so it must be\r
697         // calculated.  This is done so the correct side (left/right)\r
698         // of the bunny will be showed.\r
699 \r
700         if ((player->angle > 337) || (player->angle <= 22))\r
701                 player_dir = east;\r
702         else\r
703                 if (player->angle <= 67)\r
704                         player_dir = northeast;\r
705                 else\r
706                         if (player->angle <= 112)\r
707                  player_dir = north;\r
708                         else\r
709                  if (player->angle <= 157)\r
710                          player_dir = northwest;\r
711                  else\r
712                          if (player->angle <= 202)\r
713                                  player_dir = west;\r
714                          else\r
715                                  if (player->angle <= 247)\r
716                           player_dir = southwest;\r
717                                  else\r
718                          if (player->angle <= 292)\r
719                                  player_dir = south;\r
720                          else\r
721                                  if (player->angle <= 337)\r
722                                          player_dir = southeast;\r
723         if (ob->temp1)\r
724                 ob->temp1--;\r
725         else\r
726                 ob->temp1 = (random(3))+2;\r
727         if (ob->flags & LEFTSIDE)\r
728         {\r
729                 if (ob->temp1)\r
730                 {\r
731                         if (valid_dir[player_dir][0] != ob->dir)\r
732                         {\r
733                                 ob->dir = valid_dir[player_dir][0];\r
734                         }\r
735                 }\r
736                 else\r
737                 {\r
738                         ob->state = &s_bunny_right1;\r
739                         ob->ticcount = ob->state->tictime;\r
740                         ob->flags &= ~LEFTSIDE;\r
741                         ob->dir = valid_dir[player_dir][1];\r
742                         return;\r
743                 }\r
744         }\r
745         else\r
746         {\r
747                 if (ob->temp1)\r
748                 {\r
749                         if (valid_dir[player_dir][1] != ob->dir)\r
750                         {\r
751                                 ob->dir = valid_dir[player_dir][1];\r
752                         }\r
753                 }\r
754                 else\r
755                 {\r
756                         ob->state = &s_bunny_left1;\r
757                         ob->ticcount = ob->state->tictime;\r
758                         ob->flags |= LEFTSIDE;\r
759                         ob->dir = valid_dir[player_dir][2];\r
760                         return;\r
761                 }\r
762         }\r
763 \r
764         move = ob->speed*tics;\r
765 \r
766         do\r
767         {\r
768                 old_distance    = ob->distance;\r
769                 old_x           = ob->x;\r
770                 old_y           = ob->y;\r
771                 old_tilex       = ob->tilex;\r
772                 old_tiley       = ob->tiley;\r
773 \r
774                 MoveObj (ob, move);\r
775 \r
776                 ob->tilex = ob->x >> TILESHIFT;\r
777                 ob->tiley = ob->y >> TILESHIFT;\r
778 \r
779                 if (ob->tilex == old_tilex && ob->tiley == old_tiley)\r
780                 {\r
781                         break;\r
782                 }\r
783                 else\r
784                         if (actorat[ob->tilex][ob->tiley] == 0)\r
785                         {\r
786                                 actorat[old_tilex][old_tiley] = 0;\r
787                                 actorat[ob->tilex][ob->tiley] = ob;\r
788                                 ob->distance = TILEGLOBAL;\r
789                         }\r
790                         else\r
791                         {\r
792                                 ob->distance    = old_distance;\r
793                                 ob->x           = old_x;\r
794                                 ob->y           = old_y;\r
795                                 ob->tilex       = old_tilex;\r
796                                 ob->tiley       = old_tiley;\r
797                                 return;\r
798                         }\r
799 \r
800          } while (0);\r
801 \r
802         CalcBounds (ob);\r
803 \r
804         if (ob->flags & LEFTSIDE)\r
805                 ob->state = &s_bunny_left3;\r
806         else\r
807                 ob->state = &s_bunny_right3;\r
808         ob->ticcount = ob->state->tictime;\r
809 }\r
810 \r
811 /*\r
812 ===============\r
813 =\r
814 = T_Bunny\r
815 =\r
816 ===============\r
817 */\r
818 \r
819 void T_Bunny(objtype *ob)\r
820 {\r
821         if (Chase (ob, true) || (random(1000)<RANDOM_ATTACK))\r
822         {\r
823                 ob->state = &s_bunny_attack1;\r
824                 ob->ticcount = ob->state->tictime;\r
825                 return;\r
826         }\r
827 }\r