C5_ACT1.C 20 KB

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