--- /dev/null
+/* Reconstructed Commander Keen 4-6 Source Code\r
+ * Copyright (C) 2021 K1n9_Duk3\r
+ *\r
+ * This file is loosely based on:\r
+ * Keen Dreams Source Code\r
+ * Copyright (C) 2014 Javier M. Chavez\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+ */\r
+\r
+/*\r
+K6_ACT3.C\r
+=========\r
+\r
+Contains the following actor types (in this order):\r
+\r
+- Fleex\r
+- Bobba\r
+- Babobba\r
+- Blorb\r
+- Ceilick\r
+\r
+*/\r
+\r
+#include "CK_DEF.H"\r
+\r
+/*\r
+=============================================================================\r
+\r
+ FLEEX\r
+\r
+temp1 = flash countdown\r
+temp2 = health\r
+\r
+=============================================================================\r
+*/\r
+\r
+statetype s_fleexwalk1 = {FLEEXWALKL1SPR, FLEEXWALKR1SPR, step, false, true, 7, 128, 0, T_FleexWalk, C_Fleex, R_Blooguard, &s_fleexwalk2};\r
+statetype s_fleexwalk2 = {FLEEXWALKL2SPR, FLEEXWALKR2SPR, step, false, true, 7, 128, 0, T_FleexWalk, C_Fleex, R_Blooguard, &s_fleexwalk1};\r
+statetype s_fleexrun1 = {FLEEXWALKL1SPR, FLEEXWALKR1SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexrun2};\r
+statetype s_fleexrun2 = {FLEEXWALKL2SPR, FLEEXWALKR2SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexrun3};\r
+statetype s_fleexrun3 = {FLEEXWALKL1SPR, FLEEXWALKR1SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexrun4};\r
+statetype s_fleexrun4 = {FLEEXWALKL2SPR, FLEEXWALKR2SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexwalk1};\r
+statetype s_fleexlook1 = {FLEEXLOOK1SPR, FLEEXLOOK1SPR, step, false, true, 60, 0, 0, NULL, C_Fleex, R_Blooguard, &s_fleexlook2};\r
+statetype s_fleexlook2 = {FLEEXLOOK2SPR, FLEEXLOOK2SPR, step, false, true, 60, 0, 0, T_FleexLook, C_Fleex, R_Blooguard, &s_fleexrun1};\r
+statetype s_fleexstun = {FLEEXSTUNSPR, FLEEXSTUNSPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, NULL};\r
+\r
+/*\r
+===========================\r
+=\r
+= SpawnFleex\r
+=\r
+===========================\r
+*/\r
+\r
+void SpawnFleex(Uint16 tileX, Uint16 tileY)\r
+{\r
+ GetNewObj(false);\r
+ new->obclass = fleexobj;\r
+ new->active = ac_yes;\r
+ new->priority = 0;\r
+ new->x = CONVERT_TILE_TO_GLOBAL(tileX);\r
+ new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -40*PIXGLOBAL;\r
+ if (US_RndT() < 0x80)\r
+ {\r
+ new->xdir = 1;\r
+ }\r
+ else\r
+ {\r
+ new->xdir = -1;\r
+ }\r
+ new->ydir = 1;\r
+ NewState(new, &s_fleexwalk1);\r
+ new->temp2 = 4; // health\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_FleexWalk\r
+=\r
+===========================\r
+*/\r
+\r
+void T_FleexWalk(objtype *ob)\r
+{\r
+ if (!player->xmove && !ob->temp1)\r
+ {\r
+ ob->state = &s_fleexlook1;\r
+ }\r
+ else\r
+ {\r
+ ob->xdir = (ob->x < player->x)? 1 : -1;\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_FleexLook\r
+=\r
+===========================\r
+*/\r
+\r
+void T_FleexLook(objtype *ob)\r
+{\r
+ ob->xdir = (ob->x < player->x)? 1 : -1;\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= C_Fleex\r
+=\r
+===========================\r
+*/\r
+\r
+void C_Fleex(objtype *ob, objtype *hit)\r
+{\r
+ if (hit->obclass == keenobj)\r
+ {\r
+ KillKeen();\r
+ }\r
+ if (hit->obclass == stunshotobj) // this is not 'else if' in the original code\r
+ {\r
+ if (--ob->temp2 == 0)\r
+ {\r
+ StunObj(ob, hit, &s_fleexstun);\r
+ ob->yspeed = -20;\r
+ }\r
+ else\r
+ {\r
+ ob->temp1 = 2; // draw white twice\r
+ ob->needtoreact = true;\r
+ ExplodeShot(hit);\r
+ if (ob->state == &s_fleexlook1 || ob->state == &s_fleexlook2)\r
+ {\r
+ ob->xdir = (ob->x < player->x)? 1 : -1;\r
+ ChangeState(ob, &s_fleexwalk1);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+ BOBBA\r
+\r
+temp1 = jump counter\r
+\r
+=============================================================================\r
+*/\r
+\r
+statetype s_bobbajump1 = {BOBBAL2SPR, BOBBAR2SPR, stepthink, false, false, 8, 0, 0, T_Projectile, C_Bobba, R_Bobba, &s_bobbajump2};\r
+statetype s_bobbajump2 = {BOBBAL3SPR, BOBBAR3SPR, think, false, false, 8, 0, 0, T_Projectile, C_Bobba, R_Bobba, &s_bobbajump2};\r
+statetype s_bobbastand = {BOBBAL1SPR, BOBBAR1SPR, step, false, false, 20, 0, 0, T_BobbaStand, C_Bobba, R_Draw, &s_bobbajump1};\r
+statetype s_bobbaattack = {BOBBAL1SPR, BOBBAR1SPR, step, false, false, 40, 0, 0, NULL, C_Bobba, R_Draw, &s_bobbajump1};\r
+statetype s_bobbashot1 = {BOBBASHOT1SPR, BOBBASHOT1SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashot2};\r
+statetype s_bobbashot2 = {BOBBASHOT2SPR, BOBBASHOT2SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashot3};\r
+statetype s_bobbashot3 = {BOBBASHOT1SPR, BOBBASHOT1SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashot4};\r
+statetype s_bobbashot4 = {BOBBASHOT2SPR, BOBBASHOT2SPR, step, false, false, 8, 0, 0, T_BobbaShot, NULL, R_Draw, &s_bobbashot5};\r
+statetype s_bobbashot5 = {BOBBASHOT3SPR, BOBBASHOT3SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot6};\r
+statetype s_bobbashot6 = {BOBBASHOT4SPR, BOBBASHOT4SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot7};\r
+statetype s_bobbashot7 = {BOBBASHOT5SPR, BOBBASHOT5SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot8};\r
+statetype s_bobbashot8 = {BOBBASHOT6SPR, BOBBASHOT6SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot5};\r
+statetype s_bobbashotvanish1 = {BOBBASHOT6SPR, BOBBASHOT6SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashotvanish2};\r
+statetype s_bobbashotvanish2 = {BOBBASHOT6SPR, BOBBASHOT6SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashotvanish3};\r
+statetype s_bobbashotvanish3 = {BOBBASHOT6SPR, BOBBASHOT6SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, NULL};\r
+\r
+/*\r
+===========================\r
+=\r
+= SpawnBobba\r
+=\r
+===========================\r
+*/\r
+\r
+void SpawnBobba(Uint16 tileX, Uint16 tileY)\r
+{\r
+ GetNewObj(false);\r
+ new->obclass = bobbaobj;\r
+ new->active = ac_yes;\r
+ new->priority = 0;\r
+ new->x = CONVERT_TILE_TO_GLOBAL(tileX);\r
+ new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -2*TILEGLOBAL;\r
+ if (US_RndT() < 0x80)\r
+ {\r
+ new->xdir = 1;\r
+ }\r
+ else\r
+ {\r
+ new->xdir = -1;\r
+ }\r
+ new->ydir = 1;\r
+ NewState(new, &s_bobbajump1);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_BobbaShot\r
+=\r
+===========================\r
+*/\r
+\r
+#pragma argsused\r
+void T_BobbaShot(objtype *ob)\r
+{\r
+ SD_PlaySound(SND_BOBBASHOT);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_BobbaStand\r
+=\r
+===========================\r
+*/\r
+\r
+void T_BobbaStand(objtype *ob)\r
+{\r
+ Sint16 i;\r
+ Uint16 far *map;\r
+\r
+ if (++ob->temp1 == 3)\r
+ {\r
+ ob->temp1 = 0;\r
+ GetNewObj(true);\r
+ new->active = ac_removable;\r
+ new->obclass = mshotobj;\r
+ new->y = ob->y + 11*PIXGLOBAL;\r
+ new->xdir = ob->xdir;\r
+ if (ob->xdir == 1)\r
+ {\r
+ new->x = ob->x + 16*PIXGLOBAL;\r
+ }\r
+ else\r
+ {\r
+ new->x = ob->x + 11*PIXGLOBAL;\r
+ }\r
+ NewState(new, &s_bobbashot1);\r
+ new->priority = 2;\r
+ ob->state = &s_bobbaattack;\r
+ }\r
+ else\r
+ {\r
+ map = mapsegs[1] + mapbwidthtable[ob->tilebottom+1]/2 + ob->tilemidx;\r
+ for (i=0; i<4; map += ob->xdir, i++)\r
+ {\r
+ if ( !tinf[*map+NORTHWALL]\r
+ && !tinf[*(map-mapwidth)+NORTHWALL]\r
+ && !tinf[*(map+mapwidth)+NORTHWALL] )\r
+ {\r
+ ob->xdir = -ob->xdir;\r
+ break;\r
+ }\r
+ }\r
+ ob->xspeed = ob->xdir << 5;\r
+ ob->yspeed = -32;\r
+ SD_PlaySound(SND_BOBBAJUMP);\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= C_Bobba\r
+=\r
+===========================\r
+*/\r
+\r
+void C_Bobba(objtype *ob, objtype *hit)\r
+{\r
+ if (hit->obclass == keenobj)\r
+ {\r
+ KillKeen();\r
+ }\r
+ else if (hit->obclass == stunshotobj)\r
+ {\r
+ ExplodeShot(hit);\r
+ if (hit->xdir != 0)\r
+ {\r
+ ob->xdir = -hit->xdir;\r
+ }\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= R_Bobba\r
+=\r
+===========================\r
+*/\r
+\r
+void R_Bobba(objtype *ob)\r
+{\r
+ if (ob->hiteast)\r
+ {\r
+ ob->xdir = 1;\r
+ ob->xspeed = -ob->xspeed;\r
+ }\r
+ else if (ob->hitwest)\r
+ {\r
+ ob->xdir = -1;\r
+ ob->xspeed = -ob->xspeed;\r
+ }\r
+\r
+ if (ob->hitsouth)\r
+ ob->yspeed = 0;\r
+\r
+ if (ob->hitnorth)\r
+ {\r
+ SD_PlaySound(SND_BOBBALAND);\r
+ ChangeState(ob, &s_bobbastand);\r
+ }\r
+ RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= R_BobbaShot\r
+=\r
+===========================\r
+*/\r
+\r
+void R_BobbaShot(objtype *ob)\r
+{\r
+ if (ob->hitnorth || ob->hitsouth || ob->hiteast || ob->hitwest)\r
+ {\r
+ ChangeState(ob, &s_bobbashotvanish1);\r
+ }\r
+ RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+ BABOBBA\r
+\r
+temp1 = jump counter (Babobba) / animation counter (Shot)\r
+\r
+=============================================================================\r
+*/\r
+\r
+statetype s_babobbajump1 = {BABOBBAL2SPR, BABOBBAR2SPR, stepthink, false, false, 8, 0, 0, T_Projectile, C_Babobba, R_Babobba, &s_babobbajump2};\r
+statetype s_babobbajump2 = {BABOBBAL3SPR, BABOBBAR3SPR, think, false, false, 8, 0, 0, T_Projectile, C_Babobba, R_Babobba, &s_babobbajump2};\r
+statetype s_babobbastand = {BABOBBAL1SPR, BABOBBAR1SPR, step, false, false, 20, 0, 0, T_BabobbaStand, C_Babobba, R_Draw, &s_babobbajump1};\r
+statetype s_babobbaattack = {BABOBBAL1SPR, BABOBBAR1SPR, step, false, false, 70, 0, 0, NULL, C_Babobba, R_Draw, &s_babobbastand};\r
+statetype s_babobbastun1 = {BABOBBAL2SPR, BABOBBAR2SPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, &s_babobbastun2};\r
+statetype s_babobbastun2 = {BABOBBASTUNSPR, BABOBBASTUNSPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, NULL};\r
+statetype s_babobbasleep1 = {BABOBBASLEEP1SPR, BABOBBASLEEP1SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep2};\r
+statetype s_babobbasleep2 = {BABOBBASLEEP2SPR, BABOBBASLEEP2SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep3};\r
+statetype s_babobbasleep3 = {BABOBBASLEEP3SPR, BABOBBASLEEP3SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep4};\r
+statetype s_babobbasleep4 = {BABOBBASLEEP4SPR, BABOBBASLEEP4SPR, step, false, false, 500, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep5};\r
+statetype s_babobbasleep5 = {BABOBBASLEEP3SPR, BABOBBASLEEP3SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep6};\r
+statetype s_babobbasleep6 = {BABOBBASLEEP2SPR, BABOBBASLEEP2SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep7};\r
+statetype s_babobbasleep7 = {BABOBBASLEEP1SPR, BABOBBASLEEP1SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbastand};\r
+statetype s_babobbashot1 = {BABOBBASHOT1SPR, BABOBBASHOT1SPR, think, false, false, 0, 0, 0, T_Projectile, C_Lethal, R_Bounce, &s_babobbashot2};\r
+statetype s_babobbashot2 = {BABOBBASHOT2SPR, BABOBBASHOT2SPR, step, false, false, 8, 0, 0, T_BabobbaShot, C_Lethal, R_Draw, &s_babobbashot3};\r
+statetype s_babobbashot3 = {BABOBBASHOT1SPR, BABOBBASHOT1SPR, step, false, false, 8, 0, 0, NULL, C_Lethal, R_Draw, &s_babobbashot2};\r
+statetype s_babobbashotvanish1 = {BABOBBASHOT2SPR, BABOBBASHOT2SPR, step, false, false, 8, 0, 0, T_BabobbaShotVanish, C_Lethal, R_Draw, &s_babobbashotvanish2};\r
+statetype s_babobbashotvanish2 = {-1, -1, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_babobbashotvanish1};\r
+\r
+/*\r
+===========================\r
+=\r
+= SpawnBabobba\r
+=\r
+===========================\r
+*/\r
+\r
+void SpawnBabobba(Uint16 tileX, Uint16 tileY)\r
+{\r
+ GetNewObj(false);\r
+ new->obclass = babobbaobj;\r
+ new->active = ac_yes;\r
+ new->priority = 0;\r
+ new->x = CONVERT_TILE_TO_GLOBAL(tileX);\r
+ new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -2*TILEGLOBAL;\r
+ if (US_RndT() < 0x80)\r
+ {\r
+ new->xdir = 1;\r
+ }\r
+ else\r
+ {\r
+ new->xdir = -1;\r
+ }\r
+ new->ydir = 1;\r
+ NewState(new, &s_babobbajump1);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_BabobbaStand\r
+=\r
+===========================\r
+*/\r
+\r
+void T_BabobbaStand(objtype *ob)\r
+{\r
+ Sint16 i;\r
+ Uint16 far *map;\r
+\r
+ if (US_RndT() < 4)\r
+ {\r
+ ob->temp1 = 0;\r
+ ob->state = &s_babobbasleep1;\r
+ }\r
+ else if (++ob->temp1 == 3)\r
+ {\r
+ ob->temp1 = 0;\r
+\r
+ GetNewObj(true);\r
+ new->active = ac_removable;\r
+ new->obclass = mshotobj;\r
+ new->y = ob->y + 4*PIXGLOBAL;\r
+ new->xdir = ob->xdir;\r
+ if (ob->xdir == 1)\r
+ {\r
+ new->x = ob->x + 16*PIXGLOBAL;\r
+ }\r
+ else\r
+ {\r
+ new->x = ob->x + 11*PIXGLOBAL;\r
+ }\r
+ new->xspeed = new->xdir << 5;\r
+ NewState(new, &s_babobbashot1);\r
+ new->priority = 2;\r
+ ob->state = &s_babobbaattack;\r
+ }\r
+ else\r
+ {\r
+ map = mapsegs[1] + mapbwidthtable[ob->tilebottom+1]/2 + ob->tilemidx;\r
+ for (i=0; i<4; map += ob->xdir, i++)\r
+ {\r
+ if ( !tinf[*map+NORTHWALL]\r
+ && !tinf[*(map-mapwidth)+NORTHWALL]\r
+ && !tinf[*(map+mapwidth)+NORTHWALL] )\r
+ {\r
+ ob->xdir = -ob->xdir;\r
+ break;\r
+ }\r
+ }\r
+ ob->xspeed = ob->xdir *24;\r
+ ob->yspeed = -32;\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= C_Babobba\r
+=\r
+===========================\r
+*/\r
+\r
+void C_Babobba(objtype *ob, objtype *hit)\r
+{\r
+ if (hit->obclass == keenobj)\r
+ {\r
+ KillKeen();\r
+ }\r
+ else if (hit->obclass == stunshotobj)\r
+ {\r
+ StunObj(ob, hit, &s_babobbastun1);\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= C_BabobbaSleep\r
+=\r
+===========================\r
+*/\r
+\r
+void C_BabobbaSleep(objtype *ob, objtype *hit)\r
+{\r
+ if (hit->obclass == stunshotobj)\r
+ {\r
+ StunObj(ob, hit, &s_babobbastun1);\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= R_Babobba\r
+=\r
+===========================\r
+*/\r
+\r
+void R_Babobba(objtype *ob)\r
+{\r
+ if (ob->hiteast)\r
+ {\r
+ ob->xdir = 1;\r
+ ob->xspeed = -ob->xspeed;\r
+ }\r
+ else if (ob->hitwest)\r
+ {\r
+ ob->xdir = -1;\r
+ ob->xspeed = -ob->xspeed;\r
+ }\r
+\r
+ if (ob->hitsouth)\r
+ ob->yspeed = 0;\r
+\r
+ if (ob->hitnorth)\r
+ {\r
+ ChangeState(ob, &s_babobbastand);\r
+ }\r
+ RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_BabobbaShot\r
+=\r
+===========================\r
+*/\r
+\r
+void T_BabobbaShot(objtype *ob)\r
+{\r
+ if (++ob->temp1 == 10)\r
+ {\r
+ ob->temp1 = 0;\r
+ ob->state = &s_babobbashotvanish1;\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_BabobbaShotVanish\r
+=\r
+===========================\r
+*/\r
+\r
+void T_BabobbaShotVanish(objtype *ob)\r
+{\r
+ if (++ob->temp1 == 5)\r
+ {\r
+ RemoveObj(ob);\r
+ }\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+ BLORB\r
+\r
+=============================================================================\r
+*/\r
+\r
+statetype s_blorb1 = {BLORB1SPR, BLORB1SPR, slide, false, false, 20, 8, 8, 0, C_Lethal, R_Blorb, &s_blorb2};\r
+statetype s_blorb2 = {BLORB2SPR, BLORB2SPR, slide, false, false, 20, 8, 8, 0, C_Lethal, R_Blorb, &s_blorb3};\r
+statetype s_blorb3 = {BLORB3SPR, BLORB3SPR, slide, false, false, 20, 8, 8, 0, C_Lethal, R_Blorb, &s_blorb1};\r
+\r
+/*\r
+===========================\r
+=\r
+= SpawnBlorb\r
+=\r
+===========================\r
+*/\r
+\r
+void SpawnBlorb(Uint16 tileX, Uint16 tileY)\r
+{\r
+ GetNewObj(false);\r
+ new->obclass = blorbobj;\r
+ new->active = ac_yes;\r
+ new->priority = 0;\r
+ new->x = CONVERT_TILE_TO_GLOBAL(tileX);\r
+ new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -8*PIXGLOBAL;\r
+ if (US_RndT() < 0x80)\r
+ {\r
+ new->xdir = 1;\r
+ }\r
+ else\r
+ {\r
+ new->xdir = -1;\r
+ }\r
+ if (US_RndT() < 0x80)\r
+ {\r
+ new->ydir = 1;\r
+ }\r
+ else\r
+ {\r
+ new->ydir = -1;\r
+ }\r
+ new->needtoclip = cl_fullclip;\r
+ NewState(new, &s_blorb1);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= R_Blorb\r
+=\r
+===========================\r
+*/\r
+\r
+void R_Blorb(objtype *ob)\r
+{\r
+ if (ob->hitnorth)\r
+ {\r
+ ob->ydir = -1;\r
+ SD_PlaySound(SND_BLORBBOUNCE);\r
+ }\r
+ else if (ob->hitsouth)\r
+ {\r
+ ob->ydir = 1;\r
+ SD_PlaySound(SND_BLORBBOUNCE);\r
+ }\r
+ if (ob->hitwest)\r
+ {\r
+ ob->xdir = -1;\r
+ SD_PlaySound(SND_BLORBBOUNCE);\r
+ }\r
+ else if (ob->hiteast)\r
+ {\r
+ ob->xdir = 1;\r
+ SD_PlaySound(SND_BLORBBOUNCE);\r
+ }\r
+ RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+ CEILICK\r
+\r
+temp1 = initial y position\r
+\r
+=============================================================================\r
+*/\r
+\r
+statetype s_ceilickhidden = {TONGUE1SPR, TONGUE1SPR, think, false, false, 20, 0, 0, T_CeilickHidden, NULL, R_Draw, NULL};\r
+statetype s_ceilickattack1 = {TONGUE1SPR, TONGUE1SPR, step, false, false, 6, 0, 0, NULL, NULL, R_Draw, &s_ceilickattack2};\r
+statetype s_ceilickattack2 = {TONGUE2SPR, TONGUE2SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack3};\r
+statetype s_ceilickattack3 = {TONGUE3SPR, TONGUE3SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack4};\r
+statetype s_ceilickattack4 = {TONGUE4SPR, TONGUE4SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack5};\r
+statetype s_ceilickattack5 = {TONGUE5SPR, TONGUE5SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack6};\r
+statetype s_ceilickattack6 = {TONGUE4SPR, TONGUE4SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack7};\r
+statetype s_ceilickattack7 = {TONGUE3SPR, TONGUE3SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack8};\r
+statetype s_ceilickattack8 = {TONGUE4SPR, TONGUE4SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack9};\r
+statetype s_ceilickattack9 = {TONGUE5SPR, TONGUE5SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack10};\r
+statetype s_ceilickattack10 = {TONGUE2SPR, TONGUE2SPR, step, false, false, 10, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack11};\r
+statetype s_ceilickattack11 = {TONGUE1SPR, TONGUE1SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, &s_ceilicklaugh1};\r
+statetype s_ceilicklaugh1 = {CEILICK1SPR, CEILICK1SPR, slide, true, false, 16, 0, 16, T_CeilickLaugh, C_Ceilick, R_Draw, &s_ceilicklaugh2};\r
+statetype s_ceilicklaugh2 = {CEILICK2SPR, CEILICK2SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh3};\r
+statetype s_ceilicklaugh3 = {CEILICK1SPR, CEILICK1SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh4};\r
+statetype s_ceilicklaugh4 = {CEILICK2SPR, CEILICK2SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh5};\r
+statetype s_ceilicklaugh5 = {CEILICK1SPR, CEILICK1SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh6};\r
+statetype s_ceilicklaugh6 = {CEILICK2SPR, CEILICK2SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh7};\r
+statetype s_ceilicklaugh7 = {CEILICK1SPR, CEILICK1SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh8};\r
+statetype s_ceilicklaugh8 = {CEILICK1SPR, CEILICK1SPR, slide, true, false, 16, 0, -16, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh9};\r
+statetype s_ceilicklaugh9 = {-1, -1, step, true, false, 60, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilickhidden};\r
+statetype s_ceilickstun = {CEILICKSTUNSPR, CEILICKSTUNSPR, think, true, false, 0, 0, 0, T_CeilickStunned, NULL, R_Stunned, NULL};\r
+\r
+/*\r
+===========================\r
+=\r
+= SpawnCeilick\r
+=\r
+===========================\r
+*/\r
+\r
+void SpawnCeilick(Uint16 tileX, Uint16 tileY)\r
+{\r
+ GetNewObj(false);\r
+ new->obclass = ceilickobj;\r
+ new->active = ac_yes;\r
+ new->priority = 0;\r
+ new->needtoclip = cl_noclip;\r
+ new->x = CONVERT_TILE_TO_GLOBAL(tileX);\r
+ new->y = new->temp1 = CONVERT_TILE_TO_GLOBAL(tileY);\r
+ new->ydir = 1;\r
+ NewState(new, &s_ceilickhidden);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_CeilickHidden\r
+=\r
+===========================\r
+*/\r
+\r
+void T_CeilickHidden(objtype *ob)\r
+{\r
+ if ( player->y - ob->y <= 40*PIXGLOBAL\r
+ && player->left < ob->right+PIXGLOBAL\r
+ && player->right > ob->left-PIXGLOBAL )\r
+ {\r
+ SD_PlaySound(SND_CEILICKATTACK);\r
+ ob->state = &s_ceilickattack1;\r
+ }\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_CeilickLaugh\r
+=\r
+===========================\r
+*/\r
+\r
+#pragma argsused\r
+void T_CeilickLaugh(objtype *ob)\r
+{\r
+ SD_PlaySound(SND_CEILICKLAUGH);\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= T_CeilickStunned\r
+=\r
+===========================\r
+*/\r
+\r
+void T_CeilickStunned(objtype *ob)\r
+{\r
+ ob->needtoreact = true; // to make sure the stunned stars animate\r
+}\r
+\r
+/*\r
+===========================\r
+=\r
+= C_Ceilick\r
+=\r
+===========================\r
+*/\r
+\r
+void C_Ceilick(objtype *ob, objtype *hit)\r
+{\r
+ if (hit->obclass == stunshotobj)\r
+ {\r
+ ob->y = ob->temp1;\r
+ ExplodeShot(hit);\r
+ ob->temp1 = ob->temp2 = ob->temp3 = 0;\r
+ ob->temp4 = ob->obclass;\r
+ ChangeState(ob, &s_ceilickstun);\r
+ ob->obclass = stunnedobj;\r
+ }\r
+}
\ No newline at end of file