]> 4ch.mooo.com Git - 16.git/blob - 16/cawat/C5_ACT1.C
dcd65e3503f1dd9ac3236248156a4d7e47a4f6cc
[16.git] / 16 / cawat / C5_ACT1.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 \r
32 #if 0\r
33 #define MSHOTDAMAGE     2\r
34 #define MSHOTSPEED      10000\r
35 \r
36 #define ESHOTDAMAGE     1\r
37 #define ESHOTSPEED      5000\r
38 \r
39 #define SSHOTDAMAGE     3\r
40 #define SSHOTSPEED      6500\r
41 \r
42 #define RANDOM_ATTACK 20\r
43 #endif\r
44 \r
45 /*\r
46 =============================================================================\r
47 \r
48                                                  GLOBAL VARIABLES\r
49 \r
50 =============================================================================\r
51 */\r
52 \r
53 boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);\r
54 void T_ShootPlayer(objtype *ob);\r
55 \r
56 short zombie_base_delay;\r
57 \r
58 short other_x[] = {0,39,39,0},\r
59                 other_y[] = {0,0,27,27};\r
60 \r
61 /*\r
62 =============================================================================\r
63 \r
64                                                  LOCAL VARIABLES\r
65 \r
66 =============================================================================\r
67 */\r
68 \r
69 \r
70 dirtype dirtable[9] = {northwest,north,northeast,west,nodir,east,\r
71         southwest,south,southeast};\r
72 \r
73 \r
74 /*\r
75 =============================================================================\r
76 \r
77                                                   BONUS ITEMS\r
78 \r
79 =============================================================================\r
80 */\r
81 \r
82 extern statetype        s_boltbonus2;\r
83 extern statetype        s_nukebonus2;\r
84 extern statetype        s_boltbonus3;\r
85 extern statetype        s_nukebonus3;\r
86 \r
87 statetype s_boltbonus = {BOLTOBJPIC,8,NULL,&s_boltbonus2};\r
88 statetype s_boltbonus2 = {BOLT2OBJPIC,8,NULL,&s_boltbonus3};\r
89 statetype s_boltbonus3 = {BOLT3OBJPIC,8,NULL,&s_boltbonus};\r
90 \r
91 statetype s_nukebonus = {NUKEOBJPIC,8,NULL,&s_nukebonus2};\r
92 statetype s_nukebonus2 = {NUKE2OBJPIC,8,NULL,&s_nukebonus3};\r
93 statetype s_nukebonus3 = {NUKE3OBJPIC,8,NULL,&s_nukebonus};\r
94 \r
95 statetype s_potionbonus = {POTIONOBJPIC,0,NULL,&s_potionbonus};\r
96 //statetype s_rkey2bonus = {RKEY2PIC,0,NULL,&s_rkey2bonus};\r
97 statetype s_rkeybonus = {RKEYOBJPIC,0,NULL,&s_rkeybonus};\r
98 statetype s_ykeybonus = {YKEYOBJPIC,0,NULL,&s_ykeybonus};\r
99 statetype s_gkeybonus = {GKEYOBJPIC,0,NULL,&s_gkeybonus};\r
100 statetype s_bkeybonus = {BKEYOBJPIC,0,NULL,&s_bkeybonus};\r
101 //////////////////////////statetype s_scrollbonus = {SCROLLOBJPIC,0,NULL,&s_scrollbonus};\r
102 statetype s_chestbonus = {CHESTOBJPIC,0,NULL,&s_chestbonus};\r
103 //statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};\r
104 \r
105 extern statetype s_waterchestbonus2;\r
106 statetype s_waterchestbonus1 = {O_WATER_CHEST1PIC,8,NULL,&s_waterchestbonus2};\r
107 statetype s_waterchestbonus2 = {O_WATER_CHEST2PIC,8,NULL,&s_waterchestbonus1};\r
108 \r
109 extern statetype s_rgem2bonus;\r
110 extern statetype s_ygem2bonus;\r
111 extern statetype s_ggem2bonus;\r
112 extern statetype s_bgem2bonus;\r
113 extern statetype s_pgem2bonus;\r
114 \r
115 statetype s_rgem1bonus = {RGEM1PIC,30,NULL,&s_rgem2bonus};\r
116 statetype s_ygem1bonus = {YGEM1PIC,30,NULL,&s_ygem2bonus};\r
117 statetype s_ggem1bonus = {GGEM1PIC,30,NULL,&s_ggem2bonus};\r
118 statetype s_bgem1bonus = {BGEM1PIC,30,NULL,&s_bgem2bonus};\r
119 statetype s_pgem1bonus = {PGEM1PIC,30,NULL,&s_pgem2bonus};\r
120 \r
121 statetype s_rgem2bonus = {RGEM2PIC,30,NULL,&s_rgem1bonus};\r
122 statetype s_ygem2bonus = {YGEM2PIC,30,NULL,&s_ygem1bonus};\r
123 statetype s_ggem2bonus = {GGEM2PIC,30,NULL,&s_ggem1bonus};\r
124 statetype s_bgem2bonus = {BGEM2PIC,30,NULL,&s_bgem1bonus};\r
125 statetype s_pgem2bonus = {PGEM2PIC,30,NULL,&s_pgem1bonus};\r
126 \r
127 statetype s_bonus_die = {0,8,NULL,NULL};\r
128 \r
129 /*\r
130 ===============\r
131 =\r
132 = SpawnBonus\r
133 =\r
134 ===============\r
135 */\r
136 \r
137 void SpawnBonus (int tilex, int tiley, int number)\r
138 {\r
139         extern unsigned gcolor;\r
140 \r
141         statetype *state;\r
142 \r
143         switch (number)\r
144         {\r
145                 case B_BOLT:                    state = &s_boltbonus;           break;\r
146                 case B_NUKE:                    state = &s_nukebonus;           break;\r
147                 case B_POTION:                  state = &s_potionbonus;         break;\r
148 \r
149                 case B_RKEY:                    state = &s_rkeybonus;           break;\r
150                 case B_YKEY:                    state = &s_ykeybonus;           break;\r
151                 case B_GKEY:                    state = &s_gkeybonus;           break;\r
152                 case B_BKEY:                    state = &s_bkeybonus;           break;\r
153 \r
154                 case B_RGEM:                    state = &s_rgem1bonus;          break;\r
155                 case B_YGEM:                    state = &s_ygem1bonus;          break;\r
156                 case B_GGEM:                    state = &s_ggem1bonus;          break;\r
157                 case B_BGEM:                    state = &s_bgem1bonus;          break;\r
158                 case B_PGEM:                    state = &s_pgem1bonus;          break;\r
159 \r
160                 case B_CHEST:\r
161                         if (gcolor == 0x0101)\r
162                                 state = &s_waterchestbonus1;\r
163                         else\r
164                                 state = &s_chestbonus;\r
165                 break;\r
166 \r
167 #if 0\r
168                 case B_SCROLL1:\r
169                 case B_SCROLL2:\r
170                 case B_SCROLL3:\r
171                 case B_SCROLL4:\r
172                 case B_SCROLL5:\r
173                 case B_SCROLL6:\r
174                 case B_SCROLL7:\r
175                 case B_SCROLL8:                 state = &s_scrollbonus;         break;\r
176 #endif\r
177 \r
178 //              case B_RKEY2:                   state = &s_rkey2bonus;          break;\r
179 \r
180                 default:\r
181                         Quit("SpawnBonus(): INVALID BONUS");\r
182                 break;\r
183         }\r
184 \r
185         SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);\r
186 //      new->tileobject = true;\r
187         new->temp1 = number;\r
188         new->obclass = bonusobj;\r
189 \r
190         switch (number)\r
191         {\r
192                 case B_POTION:\r
193                 case B_CHEST:\r
194                 case B_BOLT:\r
195                 case B_NUKE:\r
196                         new->flags |= of_shootable;\r
197                 break;\r
198 \r
199                 default:\r
200                         new->flags &= ~of_shootable;\r
201                 break;\r
202         }\r
203 }\r
204 \r
205 \r
206 /*\r
207 ===============\r
208 =\r
209 = SpawnTombstone\r
210 =\r
211 ===============\r
212 */\r
213 \r
214 statetype s_tombs[3] = {{TOMB1PIC,8,NULL,&s_tombs[0]},\r
215                                                                 {TOMB2PIC,8,NULL,&s_tombs[1]},\r
216                                                                 {TOMB3PIC,8,NULL,&s_tombs[2]}};\r
217 \r
218 void SpawnTombstone (int tilex, int tiley, int shape)\r
219 {\r
220         statetype *state=&s_tombs[shape];\r
221 \r
222         SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);\r
223 //      new->tileobject = true;\r
224         new->obclass = realsolidobj;\r
225         new->flags |= of_shootable;\r
226 }\r
227 \r
228 \r
229 /*\r
230 ============================================================================\r
231 \r
232                                                                         FREEZE TIME OBJECT\r
233 \r
234 ============================================================================\r
235 */\r
236 \r
237 extern statetype s_ftimebonus;\r
238 extern statetype s_ftimebonus2;\r
239 \r
240 statetype s_ftimebonus = {TIMEOBJ1PIC,6,NULL,&s_ftimebonus2};\r
241 statetype s_ftimebonus2 = {TIMEOBJ2PIC,6,NULL,&s_ftimebonus};\r
242 \r
243 /*\r
244 ===============\r
245 =\r
246 = SpawnFTime\r
247 =\r
248 ===============\r
249 */\r
250 void SpawnFTime(int tilex, int tiley)\r
251 {\r
252         SpawnNewObj(tilex,tiley,&s_ftimebonus,TILEGLOBAL/2);\r
253 //      new->tileobject = true;\r
254         new->obclass = freezeobj;\r
255         new->flags |= of_shootable;\r
256 }\r
257 \r
258 /*\r
259 =============================================================================\r
260 \r
261                                           EXPLODING WALL\r
262 \r
263 =============================================================================\r
264 */\r
265 \r
266 \r
267 void T_WallDie (objtype *ob);\r
268 \r
269 extern  statetype s_walldie1;\r
270 extern  statetype s_walldie2;\r
271 extern  statetype s_walldie3;\r
272 extern  statetype s_walldie4;\r
273 extern  statetype s_walldie5;\r
274 extern  statetype s_walldie6;\r
275 \r
276 statetype s_walldie1 = {0,20,NULL,&s_walldie2};\r
277 statetype s_walldie2 = {0,-1,T_WallDie,&s_walldie3};\r
278 statetype s_walldie3 = {0,20,NULL,&s_walldie4};\r
279 statetype s_walldie4 = {0,-1,T_WallDie,&s_walldie5};\r
280 statetype s_walldie5 = {0,20,NULL,&s_walldie6};\r
281 statetype s_walldie6 = {0,-1,T_WallDie,NULL};\r
282 \r
283 \r
284 /*\r
285 ================\r
286 =\r
287 = ExplodeWall\r
288 =\r
289 ================\r
290 */\r
291 \r
292 void ExplodeWall (int tilex, int tiley)\r
293 {\r
294         extern unsigned gcolor;\r
295         unsigned tilenum;\r
296 \r
297         DSpawnNewObj (tilex,tiley,&s_walldie1,0);\r
298         if (new == &dummyobj)\r
299                 return;\r
300         new->obclass = inertobj;\r
301         new->active = always;\r
302         if (gcolor == 0x0101)\r
303                 tilenum = WATEREXP;\r
304         else\r
305                 tilenum = WALLEXP;\r
306         (unsigned)actorat[new->tilex][new->tiley] = tilemap[new->tilex][new->tiley] =\r
307                 *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = tilenum;\r
308         *(mapsegs[2]+farmapylookup[new->tiley]+new->tilex) &= 0xFF;\r
309 }\r
310 \r
311 \r
312 /*\r
313 ================\r
314 =\r
315 = T_WallDie\r
316 =\r
317 ================\r
318 */\r
319 \r
320 void T_WallDie (objtype *ob)\r
321 {\r
322         extern unsigned gcolor;\r
323         unsigned tile,other,spot,x,y;\r
324 \r
325         if (++ob->temp1 == 3)\r
326                 tile = 0;\r
327         else\r
328                 if (gcolor == 0x0101)\r
329                         tile = WATEREXP-1 + ob->temp1;\r
330                 else\r
331                         tile = WALLEXP-1 + ob->temp1;\r
332         x = ob->tilex;\r
333         y = ob->tiley;\r
334 \r
335         (unsigned)actorat[x][y] = tilemap[x][y] = *(mapsegs[0]+farmapylookup[y]+x) = tile;\r
336 \r
337         if (ob->temp1 == 1)\r
338         {\r
339         //\r
340         // blow up nearby walls\r
341         //\r
342                 spot = (*(mapsegs[2]+farmapylookup[y]+(x-1))) >> 8;\r
343                 if (spot == EXP_WALL_CODE)\r
344                         ExplodeWall (x-1,y);\r
345                 spot = (*(mapsegs[2]+farmapylookup[y]+(x+1))) >> 8;\r
346                 if (spot == EXP_WALL_CODE)\r
347                         ExplodeWall (x+1,y);\r
348                 spot = (*(mapsegs[2]+farmapylookup[y-1]+x)) >> 8;\r
349                 if (spot == EXP_WALL_CODE)\r
350                         ExplodeWall (x,y-1);\r
351                 spot = (*(mapsegs[2]+farmapylookup[y+1]+x)) >> 8;\r
352                 if (spot == EXP_WALL_CODE)\r
353                         ExplodeWall (x,y+1);\r
354         }\r
355 }\r
356 /*\r
357 =============================================================================\r
358 \r
359                                                                 OBJ_WARP GATE\r
360 \r
361 =============================================================================\r
362 */\r
363 \r
364 void T_Gate (objtype *ob);\r
365 \r
366 extern  statetype s_obj_gate1;\r
367 extern  statetype s_obj_gate2;\r
368 extern  statetype s_obj_gate3;\r
369 extern  statetype s_obj_gate4;\r
370 \r
371 statetype s_obj_gate1 = {OBJ_WARP1PIC,10,T_Gate,&s_obj_gate2};\r
372 statetype s_obj_gate2 = {OBJ_WARP2PIC,10,T_Gate,&s_obj_gate3};\r
373 statetype s_obj_gate3 = {OBJ_WARP3PIC,10,T_Gate,&s_obj_gate4};\r
374 statetype s_obj_gate4 = {OBJ_WARP4PIC,10,T_Gate,&s_obj_gate1};\r
375 \r
376 extern statetype s_anthill;\r
377 statetype s_anthill = {ANT_HILLPIC, 20, T_Gate, &s_anthill};\r
378 \r
379 //---------------------------------------------------------------------------\r
380 //      SpawnWarp()\r
381 //\r
382 // TYPE : Type param is the gate number (1-what ever) will link you to\r
383 //                       gate of that type.\r
384 //---------------------------------------------------------------------------\r
385 void SpawnWarp (int tilex, int tiley, int type)\r
386 {\r
387 \r
388         if (type)\r
389                 SpawnNewObj (tilex,tiley,&s_obj_gate1,TILEGLOBAL/3);\r
390         else\r
391                 SpawnNewObj (tilex,tiley,&s_anthill,TILEGLOBAL/3);\r
392         new->obclass = gateobj;\r
393         new->temp1 = type;\r
394 }\r
395 \r
396 \r
397 \r
398 /*\r
399 ===============\r
400 =\r
401 = T_Gate\r
402 =\r
403 ===============\r
404 */\r
405 \r
406 #define STATUSCOLOR     4\r
407 \r
408 void T_Gate (objtype *ob)\r
409 {\r
410         objtype *check;\r
411         unsigned        temp,spot;\r
412 \r
413         if (CheckHandAttack (ob) && !playstate)\r
414         {\r
415                 // make\r
416                 //\r
417 //              spot = (*(mapsegs[2]+farmapylookup[ob->tiley+1]+ob->tilex)) >> 8;\r
418 //              if (spot--)\r
419 //                      if (gamestate.keys[spot])\r
420 //                              TakeKey(spot);\r
421 //                      else\r
422 //                              return;\r
423 \r
424                 //\r
425                 // warp\r
426                 //\r
427 \r
428 //              temp = bufferofs;\r
429 //              bufferofs = 0;\r
430 //              VW_Bar (26,4,232,9,STATUSCOLOR);                // clear text description\r
431 //              bufferofs = temp;\r
432 \r
433 //              IN_ClearKeysDown ();\r
434                 if (ob->temp1)\r
435                 {\r
436                         //\r
437                         // teleport inside level\r
438                         //\r
439 \r
440                         for (check=player->next;check;check=check->next)\r
441                                 if (check->obclass==gateobj && check->temp1==ob->temp1 &&\r
442                                         check != ob)\r
443                                 {\r
444                                         player->x = check->x;\r
445                                         player->y = check->y;\r
446                                         Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
447                                         Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
448                                         Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
449                                         fizzlein=true;\r
450                                         SD_PlaySound(WARPSND);\r
451                                 }\r
452                 }\r
453                 else\r
454                 {\r
455                         //\r
456                         // teleport out of level\r
457                         //\r
458 \r
459                         playstate = ex_warped;\r
460                         spot = (*(mapsegs[2]+farmapylookup[ob->tiley+1]+ob->tilex)) >> 8;\r
461                         gamestate.mapon=spot;\r
462                         SD_PlaySound(WARPUPSND);\r
463                 }\r
464         }\r
465 }\r
466 \r
467 \r
468 \r
469 /*\r
470 =============================================================================\r
471 \r
472                                         FAT DEMON\r
473 \r
474 =============================================================================\r
475 */\r
476 \r
477 #define FATCLOUDDAMAGE 2\r
478 \r
479 void T_FatDemon (objtype *ob);\r
480 void T_CheckCnt(objtype *ob);\r
481 void ExplodeSound(objtype *ob);\r
482 \r
483 extern statetype s_fatdemon_pause;\r
484 extern statetype s_fatdemon_walk1;\r
485 extern statetype s_fatdemon_walk2;\r
486 extern statetype s_fatdemon_walk3;\r
487 extern statetype s_fatdemon_walk4;\r
488 extern statetype s_fatdemon_attack1;\r
489 extern statetype s_fatdemon_attack2;\r
490 extern statetype s_fatdemon_blowup2;\r
491 extern statetype s_fatdemon_blowup3;\r
492 extern statetype s_fatdemon_blowup4;\r
493 extern statetype s_fatdemon_blowup5;\r
494 extern statetype s_fatdemon_blowup6;\r
495 extern statetype s_fatdemon_blowup7;\r
496 extern statetype s_fatdemon_explode;\r
497 extern statetype s_fatdemon_feet;\r
498 \r
499 statetype s_fatdemon_pause = {FATDEMON_WALK1PIC,40,NULL,&s_fatdemon_walk2};\r
500 \r
501 statetype s_fatdemon_walk1 = {FATDEMON_WALK1PIC,13,T_FatDemon,&s_fatdemon_walk2};\r
502 statetype s_fatdemon_walk2 = {FATDEMON_WALK2PIC,13,T_FatDemon,&s_fatdemon_walk3};\r
503 statetype s_fatdemon_walk3 = {FATDEMON_WALK3PIC,13,T_FatDemon,&s_fatdemon_walk4};\r
504 statetype s_fatdemon_walk4 = {FATDEMON_WALK4PIC,13,T_FatDemon,&s_fatdemon_walk1};\r
505 \r
506 statetype s_fatdemon_attack1 = {FATDEMON_ATTACK1PIC,20,NULL,&s_fatdemon_attack2};\r
507 statetype s_fatdemon_attack2 = {FATDEMON_ATTACK2PIC,20,T_DoDamage,&s_fatdemon_pause};\r
508 \r
509 statetype s_fatdemon_ouch = {FATDEMON_OUCHPIC,14,NULL,&s_fatdemon_walk1};\r
510 \r
511 statetype s_fatdemon_blowup1 = {FATDEMON_BLOWUP1PIC,25,NULL,&s_fatdemon_blowup2};\r
512 statetype s_fatdemon_blowup2 = {FATDEMON_BLOWUP2PIC,25,NULL,&s_fatdemon_blowup3};\r
513 statetype s_fatdemon_blowup3 = {FATDEMON_BLOWUP1PIC,15,NULL,&s_fatdemon_blowup4};\r
514 statetype s_fatdemon_blowup4 = {FATDEMON_BLOWUP2PIC,15,NULL,&s_fatdemon_blowup5};\r
515 statetype s_fatdemon_blowup5 = {FATDEMON_BLOWUP1PIC,6,NULL,&s_fatdemon_blowup6};\r
516 statetype s_fatdemon_blowup6 = {FATDEMON_BLOWUP2PIC,6,T_CheckCnt,&s_fatdemon_blowup5};\r
517 statetype s_fatdemon_blowup7 = {FATDEMON_BLOWUP3PIC,30,NULL,&s_fatdemon_explode};\r
518 \r
519 \r
520 statetype s_fatdemon_explode = {FATDEMON_EXPLODEPIC,40,ExplodeSound,&s_fatdemon_feet};\r
521 statetype s_fatdemon_feet = {FATDEMON_FEETPIC,30,NULL,&s_fatdemon_feet};\r
522 \r
523 #define cnt             ob->temp1\r
524 #define cloud_delay     ob->temp2\r
525 \r
526 /*\r
527 ===============\r
528 =\r
529 = SpawnFatDemon\r
530 =\r
531 ===============\r
532 */\r
533 \r
534 void SpawnFatDemon (int tilex, int tiley)\r
535 {\r
536         SpawnNewObj(tilex,tiley,&s_fatdemon_walk1,35*PIXRADIUS);\r
537         new->speed = 2500;\r
538         new->obclass = fatdemonobj;\r
539         new->flags |= of_shootable;\r
540         new->hitpoints = EasyHitPoints(10);\r
541         new->temp1 = 25;        //used to "shake" the fat dude??????\r
542 }\r
543 \r
544 \r
545 /*\r
546 ===============\r
547 =\r
548 = T_FatDemon\r
549 =\r
550 ===============\r
551 */\r
552 \r
553 void T_FatDemon (objtype *ob)\r
554 {\r
555         if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))\r
556         {\r
557                 ob->state = &s_fatdemon_attack1;\r
558                 ob->ticcount = ob->state->tictime;\r
559                 return;\r
560         }\r
561 }\r
562 \r
563 \r
564 /*\r
565 ===============\r
566 =\r
567 = T_DecCnt\r
568 =\r
569 ===============\r
570 */\r
571 \r
572 void T_CheckCnt (objtype *ob)\r
573 {\r
574         ob->temp1--;\r
575         if (!ob->temp1)\r
576         {\r
577                 ob->state = &s_fatdemon_blowup7;\r
578                 ob->ticcount = ob->state->tictime;\r
579         }\r
580 }\r
581 \r
582 /*\r
583 ===============\r
584 =\r
585 = ExplodeSound\r
586 =\r
587 ===============\r
588 */\r
589 void ExplodeSound(objtype *ob)\r
590 {\r
591         if (ob->temp1 != 666)                                           // Has this think been called already?\r
592         {\r
593                 SD_PlaySound(BODY_EXPLODESND);\r
594                 ob->temp1 = 666;                        // Has now!\r
595         }\r
596 }\r
597 \r
598 \r
599 /*\r
600 =============================================================================\r
601 \r
602                                 WATER DRAGON\r
603 \r
604 =============================================================================\r
605 */\r
606 \r
607 extern statetype s_dragon_shot1;\r
608 extern statetype s_dragon_shot2;\r
609 \r
610 \r
611 void T_Dragon(objtype *ob);\r
612 void T_DragonShoot(objtype *ob);\r
613 \r
614 \r
615 statetype s_wet_bubbles1 = {DRAGON_BUBBLES1PIC,13,T_Dragon,&s_wet_bubbles2};\r
616 statetype s_wet_bubbles2 = {DRAGON_BUBBLES2PIC,15,T_Dragon,&s_wet_bubbles1};\r
617 statetype s_wet_bubbles3 = {0,35,T_Dragon,&s_wet_bubbles1};\r
618 \r
619 statetype s_wet_peek = {DRAGON_EYESPIC,45,NULL,&s_wet_bubbles1};\r
620 \r
621 statetype s_wet_rise1 = {DRAGON_BUBBLES2PIC,15,NULL,&s_wet_rise3};\r
622 statetype s_wet_rise3 = {DRAGON_EYESPIC,20,NULL,&s_wet_rise4};\r
623 statetype s_wet_rise4 = {DRAGON_RISE1PIC,20,NULL,&s_wet_rise5};\r
624 statetype s_wet_rise5 = {DRAGON_RISE2PIC,20,NULL,&s_wet_walk1};\r
625 \r
626 statetype s_wet_sink1 = {DRAGON_RISE2PIC,20,NULL,&s_wet_sink2};\r
627 statetype s_wet_sink2 = {DRAGON_RISE1PIC,20,NULL,&s_wet_sink3};\r
628 statetype s_wet_sink3 = {DRAGON_EYESPIC,20,NULL,&s_wet_bubbles1};\r
629 \r
630 statetype s_wet_walk1 = {DRAGON_WALK1PIC,12,T_Dragon,&s_wet_walk2};\r
631 statetype s_wet_walk2 = {DRAGON_WALK2PIC,12,T_Dragon,&s_wet_walk3};\r
632 statetype s_wet_walk3 = {DRAGON_WALK3PIC,12,T_Dragon,&s_wet_walk4};\r
633 statetype s_wet_walk4 = {DRAGON_WALK4PIC,12,T_Dragon,&s_wet_walk1};\r
634 \r
635 statetype s_wet_attack1 = {DRAGON_ATTACK1PIC,10,NULL,&s_wet_attack2};\r
636 statetype s_wet_attack2 = {DRAGON_ATTACK2PIC,10,NULL,&s_wet_attack3};\r
637 statetype s_wet_attack3 = {DRAGON_ATTACK2PIC,10,NULL,&s_wet_attack4};\r
638 statetype s_wet_attack4 = {DRAGON_ATTACK3PIC,10,T_DragonShoot,&s_wet_walk1};\r
639 \r
640 statetype s_wet_ouch = {DRAGON_OUCHPIC,10,T_Dragon,&s_wet_walk1};\r
641 \r
642 statetype s_wet_die1 = {DRAGON_DEATH1PIC,27,NULL,&s_wet_die2};\r
643 statetype s_wet_die2 = {DRAGON_DEATH2PIC,29,NULL,&s_wet_die3};\r
644 statetype s_wet_die3 = {DRAGON_DEATH3PIC,44,NULL,&s_wet_die4};\r
645 statetype s_wet_die4 = {DRAGON_BUBBLES2PIC,26,NULL,&s_wet_die5};\r
646 statetype s_wet_die5 = {DRAGON_BUBBLES1PIC,23,NULL,NULL};\r
647 \r
648 statetype s_dragon_shot1 = {PSHOT1PIC,8,&T_ShootPlayer,&s_dragon_shot2};\r
649 statetype s_dragon_shot2 = {PSHOT2PIC,8,&T_ShootPlayer,&s_dragon_shot1};\r
650 \r
651 \r
652 typedef enum {wt_BUBBLES,wt_WALK,wt_CORNER1,wt_CORNER2,wt_CORNER3,wt_CORNER4} DragonTypes;\r
653 \r
654 \r
655 #define WD_TIMEREMAIN   (ob->temp1)\r
656 #define WD_STAGE        (ob->temp2)\r
657 #define WATER_DRAGON_LEAVE      0x04\r
658 \r
659 /*\r
660 ===============\r
661 =\r
662 = SpawnDragon\r
663 =\r
664 ===============\r
665 */\r
666 void SpawnDragon(int tilex, int tiley)\r
667 {\r
668         objtype *ob;\r
669         SpawnNewObj(tilex,tiley,&s_wet_bubbles1,PIXRADIUS*35);\r
670         ob=new;\r
671 \r
672         WD_STAGE = wt_BUBBLES;\r
673         WD_TIMEREMAIN = 80;\r
674 \r
675         new->obclass = wetobj;\r
676         new->speed = 1000;\r
677         new->flags &= ~of_shootable;\r
678         new->hitpoints = EasyHitPoints(20);\r
679 }\r
680 \r
681 \r
682 /*\r
683 ===============\r
684 =\r
685 = T_Dragon\r
686 =\r
687 ===============\r
688 */\r
689 \r
690 void T_Dragon(objtype *ob)\r
691 {\r
692         switch (WD_STAGE)\r
693         {\r
694                 case wt_BUBBLES:\r
695                         ob->flags &= ~of_shootable;\r
696                         if (Chase(ob,true))\r
697                         {\r
698                                 // RISE & GOTO WALK STAGE\r
699                                 //\r
700 \r
701                                 WD_STAGE = wt_WALK;\r
702                                 WD_TIMEREMAIN = 60*8+random(60*5);\r
703                                 ob->state = &s_wet_rise1;\r
704                                 ob->speed = 2200;\r
705                                 ob->ticcount = ob->state->tictime;\r
706                         }\r
707                         else\r
708                         {\r
709                                 // DEC COUNTER - And check for WALK\r
710                                 //\r
711                                 if ((WD_TIMEREMAIN-=realtics) < 0)\r
712                                 {\r
713                                         // RISE & GOTO WALK STAGE\r
714                                         //\r
715 \r
716                                         WD_STAGE = wt_WALK;\r
717                                         WD_TIMEREMAIN = 60*8+random(60*5);\r
718                                         ob->state = &s_wet_rise1;\r
719                                         ob->speed = 2200;\r
720                                         ob->ticcount = ob->state->tictime;\r
721                                 }\r
722                                 else\r
723                                 if (random(1000)<5)\r
724                                 {\r
725                                         // RANDOM PEEK UP OUT OF WATER\r
726                                         //\r
727 \r
728                                         ob->state=&s_wet_peek;\r
729                                         ob->ticcount = ob->state->tictime;\r
730                                 }\r
731                         }\r
732                         break;\r
733 \r
734 \r
735                 case wt_WALK:\r
736                         ob->flags |= of_shootable;\r
737 \r
738                         if (Chase(ob,true) || (CheckHandAttack(ob)))\r
739 \r
740                         {\r
741                                         ob->flags |= WATER_DRAGON_LEAVE;\r
742                                         WD_STAGE = random(wt_CORNER3) + 2;\r
743                                         WD_TIMEREMAIN = 60*2+(random(6)*60);\r
744                                         ob->state = &s_wet_bubbles1;\r
745                                         ob->ticcount = ob->state->tictime;\r
746                         }\r
747                         else\r
748                                 if (AngleNearPlayer(ob) != -1)\r
749                                 {\r
750                                         ob->state = &s_wet_attack1;\r
751                                         ob->ticcount = ob->state->tictime;\r
752                                 }\r
753 \r
754                         else\r
755                         {\r
756                                 // DEC COUNTER - And check for SINK\r
757                                 //\r
758                                 if ((WD_TIMEREMAIN-=realtics) < 0)\r
759                                 {\r
760                                         // SINK & GOTO BUBBLE STAGE\r
761                                         //\r
762 \r
763                                         WD_STAGE = wt_BUBBLES;\r
764                                         WD_TIMEREMAIN = 60*2+random(60*2);\r
765                                         ob->state = &s_wet_sink1;\r
766                                         ob->speed = 1200;\r
767                                         ob->ticcount = ob->state->tictime;\r
768                                         ob->flags &= ~of_shootable;\r
769                                 }\r
770 \r
771                         }\r
772                         break;\r
773                 case wt_CORNER1:\r
774                 case wt_CORNER2:\r
775                 case wt_CORNER3:\r
776                 case wt_CORNER4:\r
777                         ob->flags &= ~of_shootable;\r
778                         if ((WD_TIMEREMAIN -= realtics) < 0)\r
779                         {\r
780                                 WD_STAGE = wt_BUBBLES;\r
781                                 ob->flags &= ~WATER_DRAGON_LEAVE;\r
782                         }\r
783                         else\r
784                         {\r
785                                 fixed tempx,tempy;\r
786                                 unsigned temp_tilex,temp_tiley;\r
787 \r
788                                 tempx = player->x;\r
789                                 tempy = player->y;\r
790                                 temp_tilex = player->tilex;\r
791                                 temp_tiley = player->tiley;\r
792 \r
793                                 player->x = ((long)other_x[WD_STAGE-2]<<TILESHIFT)+TILEGLOBAL/2;\r
794                                 player->y = ((long)other_y[WD_STAGE-2]<<TILESHIFT)+TILEGLOBAL/2;\r
795                                 player->tilex = other_x[WD_STAGE-2];\r
796                                 player->tiley = other_y[WD_STAGE-2];\r
797 \r
798 \r
799                                 Chase(ob,true);\r
800 \r
801                                 player->x = tempx;\r
802                                 player->y = tempy;\r
803                                 player->tilex = temp_tilex;\r
804                                 player->tiley = temp_tiley;\r
805                         }\r
806                         break;\r
807         }\r
808 }\r
809 \r
810 /*\r
811 ===============\r
812 =\r
813 = T_DragonShoot\r
814 =\r
815 ===============\r
816 */\r
817 void T_DragonShoot (objtype *ob)\r
818 {\r
819         ShootPlayer(ob,dshotobj,10000,&s_dragon_shot1);\r
820 }\r