]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/hb/c6_act1.c
[16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / src / lib / hb / c6_act1.c
diff --git a/src/lib/hb/c6_act1.c b/src/lib/hb/c6_act1.c
new file mode 100755 (executable)
index 0000000..f94a878
--- /dev/null
@@ -0,0 +1,930 @@
+/* Catacomb Apocalypse Source Code\r
+ * Copyright (C) 1993-2014 Flat Rock Software\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
+// C3_PLAY.C\r
+\r
+#include "DEF.H"\r
+#pragma hdrstop\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+#if 0\r
+#define MSHOTDAMAGE    2\r
+#define MSHOTSPEED     10000\r
+\r
+#define ESHOTDAMAGE    1\r
+#define ESHOTSPEED     5000\r
+\r
+#define SSHOTDAMAGE    3\r
+#define SSHOTSPEED     6500\r
+\r
+#define RANDOM_ATTACK 20\r
+#endif\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);\r
+void T_ShootPlayer(objtype *ob);\r
+\r
+short zombie_base_delay;\r
+\r
+short other_x[] = {0,39,39,0},\r
+               other_y[] = {0,0,27,27};\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+dirtype dirtable[9] = {northwest,north,northeast,west,nodir,east,\r
+       southwest,south,southeast};\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                 BONUS ITEMS\r
+\r
+=============================================================================\r
+*/\r
+\r
+statetype s_boltbonus = {BOLTOBJPIC,8,NULL,&s_boltbonus2};\r
+statetype s_boltbonus2 = {BOLT2OBJPIC,8,NULL,&s_boltbonus3};\r
+statetype s_boltbonus3 = {BOLT3OBJPIC,8,NULL,&s_boltbonus};\r
+\r
+statetype s_nukebonus = {NUKEOBJPIC,8,NULL,&s_nukebonus2};\r
+statetype s_nukebonus2 = {NUKE2OBJPIC,8,NULL,&s_nukebonus3};\r
+statetype s_nukebonus3 = {NUKE3OBJPIC,8,NULL,&s_nukebonus};\r
+\r
+statetype s_potionbonus = {POTIONOBJPIC,0,NULL,&s_potionbonus};\r
+statetype s_rkeybonus = {RKEYOBJPIC,0,NULL,&s_rkeybonus};\r
+statetype s_ykeybonus = {YKEYOBJPIC,0,NULL,&s_ykeybonus};\r
+statetype s_gkeybonus = {GKEYOBJPIC,0,NULL,&s_gkeybonus};\r
+statetype s_bkeybonus = {BKEYOBJPIC,0,NULL,&s_bkeybonus};\r
+statetype s_chestbonus = {CHESTOBJPIC,0,NULL,&s_chestbonus};\r
+statetype s_oldchestbonus = {OLD_CHESTPIC,0,NULL,&s_oldchestbonus};\r
+\r
+statetype s_waterchestbonus1 = {O_WATER_CHEST1PIC, 10, NULL, &s_waterchestbonus2};\r
+statetype s_waterchestbonus2 = {O_WATER_CHEST2PIC, 10, NULL, &s_waterchestbonus3};\r
+statetype s_waterchestbonus3 = {O_WATER_CHEST3PIC, 10, NULL, &s_waterchestbonus1};\r
+\r
+statetype s_rgem1bonus = {RGEM1PIC,30,NULL,&s_rgem1bonus};\r
+statetype s_ygem1bonus = {YGEM1PIC,30,NULL,&s_ygem1bonus};\r
+statetype s_ggem1bonus = {GGEM1PIC,30,NULL,&s_ggem1bonus};\r
+statetype s_bgem1bonus = {BGEM1PIC,30,NULL,&s_bgem1bonus};\r
+statetype s_pgem1bonus = {PGEM1PIC,30,NULL,&s_pgem1bonus};\r
+\r
+statetype s_bonus_die = {0,8,NULL,NULL};\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnBonus\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnBonus (int tilex, int tiley, int number)\r
+{\r
+       extern unsigned gcolor;\r
+\r
+       statetype *state;\r
+\r
+       switch (number)\r
+       {\r
+               case B_BOLT:                    state = &s_boltbonus;           break;\r
+               case B_NUKE:                    state = &s_nukebonus;           break;\r
+               case B_POTION:                  state = &s_potionbonus;         break;\r
+\r
+               case B_RKEY:                    state = &s_rkeybonus;           break;\r
+               case B_YKEY:                    state = &s_ykeybonus;           break;\r
+               case B_GKEY:                    state = &s_gkeybonus;           break;\r
+               case B_BKEY:                    state = &s_bkeybonus;           break;\r
+\r
+               case B_RGEM:                    state = &s_rgem1bonus;          break;\r
+               case B_YGEM:                    state = &s_ygem1bonus;          break;\r
+               case B_GGEM:                    state = &s_ggem1bonus;          break;\r
+               case B_BGEM:                    state = &s_bgem1bonus;          break;\r
+               case B_PGEM:                    state = &s_pgem1bonus;          break;\r
+\r
+               case B_CHEST:\r
+                       if (gcolor == 0x0101)\r
+                               state = &s_waterchestbonus1;\r
+                       else\r
+                               state = &s_chestbonus;\r
+               break;\r
+\r
+               case B_OLDCHEST:                state = &s_oldchestbonus;       break;\r
+\r
+\r
+               default:\r
+                       Quit("SpawnBonus(): INVALID BONUS");\r
+               break;\r
+       }\r
+\r
+       SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);\r
+       new->temp1 = number;\r
+       new->obclass = bonusobj;\r
+\r
+       switch (number)\r
+       {\r
+               case B_POTION:\r
+               case B_OLDCHEST:\r
+               case B_CHEST:\r
+               case B_BOLT:\r
+               case B_NUKE:\r
+                       new->flags |= of_shootable;\r
+               break;\r
+\r
+               default:\r
+                       new->flags &= ~of_shootable;\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+\r
+/*\r
+============================================================================\r
+\r
+                                                                       FREEZE TIME OBJECT\r
+\r
+============================================================================\r
+*/\r
+\r
+extern statetype s_ftimebonus;\r
+extern statetype s_ftimebonus2;\r
+\r
+statetype s_ftimebonus = {TIMEOBJ1PIC,6,NULL,&s_ftimebonus2};\r
+statetype s_ftimebonus2 = {TIMEOBJ2PIC,6,NULL,&s_ftimebonus};\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnFTime\r
+=\r
+===============\r
+*/\r
+void SpawnFTime(int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_ftimebonus,TILEGLOBAL/2);\r
+//     new->tileobject = true;\r
+       new->obclass = freezeobj;\r
+       new->flags |= of_shootable;\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                         EXPLODING WALL\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+void T_WallDie (objtype *ob);\r
+\r
+extern statetype s_walldie1;\r
+extern statetype s_walldie2;\r
+extern statetype s_walldie3;\r
+extern statetype s_walldie4;\r
+extern statetype s_walldie5;\r
+extern statetype s_walldie6;\r
+\r
+statetype s_walldie1 = {0,20,NULL,&s_walldie2};\r
+statetype s_walldie2 = {0,-1,T_WallDie,&s_walldie3};\r
+statetype s_walldie3 = {0,20,NULL,&s_walldie4};\r
+statetype s_walldie4 = {0,-1,T_WallDie,&s_walldie5};\r
+statetype s_walldie5 = {0,20,NULL,&s_walldie6};\r
+statetype s_walldie6 = {0,-1,T_WallDie,NULL};\r
+\r
+\r
+/*\r
+================\r
+=\r
+= ExplodeWall\r
+=\r
+================\r
+*/\r
+\r
+void ExplodeWall (int tilex, int tiley)\r
+{\r
+       extern unsigned gcolor;\r
+       unsigned tilenum;\r
+\r
+       DSpawnNewObj (tilex,tiley,&s_walldie1,0);\r
+       if (new == &dummyobj)\r
+               return;\r
+       new->obclass = inertobj;\r
+       new->active = always;\r
+       if (gcolor == 0x0101)\r
+               tilenum = WATEREXP;\r
+       else\r
+               tilenum = WALLEXP;\r
+       (unsigned)actorat[new->tilex][new->tiley] = tilemap[new->tilex][new->tiley] =\r
+               *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = tilenum;\r
+       *(mapsegs[2]+farmapylookup[new->tiley]+new->tilex) &= 0xFF;\r
+}\r
+\r
+\r
+/*\r
+================\r
+=\r
+= T_WallDie\r
+=\r
+================\r
+*/\r
+\r
+void T_WallDie (objtype *ob)\r
+{\r
+       extern unsigned gcolor;\r
+       unsigned tile,other,spot,x,y;\r
+\r
+       if (++ob->temp1 == 3)\r
+               tile = 0;\r
+       else\r
+               if (gcolor == 0x0101)\r
+                       tile = WATEREXP-1 + ob->temp1;\r
+               else\r
+                       tile = WALLEXP-1 + ob->temp1;\r
+       x = ob->tilex;\r
+       y = ob->tiley;\r
+\r
+       (unsigned)actorat[x][y] = tilemap[x][y] = *(mapsegs[0]+farmapylookup[y]+x) = tile;\r
+\r
+       if (ob->temp1 == 1)\r
+       {\r
+       //\r
+       // blow up nearby walls\r
+       //\r
+               spot = (*(mapsegs[2]+farmapylookup[y]+(x-1))) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x-1,y);\r
+               spot = (*(mapsegs[2]+farmapylookup[y]+(x+1))) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x+1,y);\r
+               spot = (*(mapsegs[2]+farmapylookup[y-1]+x)) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x,y-1);\r
+               spot = (*(mapsegs[2]+farmapylookup[y+1]+x)) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x,y+1);\r
+       }\r
+}\r
+/*\r
+=============================================================================\r
+\r
+                                                               OBJ_WARP GATE\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Gate (objtype *ob);\r
+void T_Gate_Wait (objtype *ob);\r
+\r
+extern statetype s_portal_wait;\r
+statetype s_portal_wait = {0, 10, &T_Gate_Wait, &s_portal_wait};\r
+\r
+statetype s_portal1 = {PORTAL1PIC, 6, &T_Gate, &s_portal2};\r
+statetype s_portal2 = {PORTAL2PIC, 6, &T_Gate, &s_portal3};\r
+statetype s_portal3 = {PORTAL3PIC, 6, &T_Gate, &s_portal4};\r
+statetype s_portal4 = {PORTAL4PIC, 6, &T_Gate, &s_portal5};\r
+statetype s_portal5 = {PORTAL5PIC, 6, &T_Gate, &s_portal6};\r
+statetype s_portal6 = {PORTAL6PIC, 6, &T_Gate, &s_portal1};\r
+\r
+//---------------------------------------------------------------------------\r
+//     SpawnWarp()\r
+//---------------------------------------------------------------------------\r
+void SpawnWarp (int tilex, int tiley)\r
+{\r
+       unsigned spot;\r
+       objtype *ob;\r
+\r
+       spot = (*(mapsegs[2]+farmapylookup[tiley]+tilex+1)) >> 8;\r
+\r
+       if (spot)\r
+       {\r
+               SpawnNewObj (tilex, tiley, &s_portal_wait, TILEGLOBAL/3);\r
+               new->temp1 = spot*70;\r
+       }\r
+       else\r
+               SpawnNewObj (tilex, tiley, &s_portal1, TILEGLOBAL/3);\r
+\r
+       new->obclass = gateobj;\r
+}\r
+\r
+/*\r
+===============\r
+=\r
+= T_Gate_Wait\r
+=\r
+===============\r
+*/\r
+\r
+void T_Gate_Wait (objtype *ob)\r
+{\r
+       if ((ob->temp1 -= tics) <= 0)\r
+       {\r
+               if ((ob->tilex == player->tilex) && (ob->tiley == player->tiley))\r
+                       return;\r
+               if (CheckHandAttack(ob))\r
+                       return;\r
+\r
+               SD_PlaySound(PORTALSND);\r
+               ob->state = &s_portal1;\r
+               ob->ticcount = ob->state->tictime;\r
+\r
+       }\r
+\r
+}\r
+\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Gate\r
+=\r
+===============\r
+*/\r
+\r
+void T_Gate (objtype *ob)\r
+{\r
+       objtype *check;\r
+       unsigned        temp,spot;\r
+\r
+       if (CheckHandAttack (ob) && !playstate)\r
+       {\r
+               //\r
+               // teleport out of level\r
+               //\r
+               playstate = ex_warped;\r
+               spot = (*(mapsegs[2]+farmapylookup[ob->tiley+1]+ob->tilex)) >> 8;\r
+               gamestate.mapon=spot;\r
+               SD_PlaySound(WARPUPSND);\r
+       }\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                                                       AQUAMAN\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_AquaMan(objtype *ob);\r
+\r
+statetype s_aqua_under1 = {EYESTALKUNDER1PIC, 25, &T_AquaMan, &s_aqua_under2};\r
+statetype s_aqua_under2 = {EYESTALKUNDER2PIC, 20, &T_AquaMan, &s_aqua_under3};\r
+statetype s_aqua_under3 = {EYESTALKUNDER3PIC, 20, &T_AquaMan, &s_aqua_under2};\r
+\r
+statetype s_aqua_left = {EYESTALKUNDER4PIC, 40, NULL, &s_aqua_under3};\r
+statetype s_aqua_right = {EYESTALKUNDER5PIC, 40, NULL, &s_aqua_under3};\r
+\r
+statetype s_aqua_rise1 = {EYESTALKRISE1PIC, 20, NULL, &s_aqua_rise2};\r
+statetype s_aqua_rise2 = {EYESTALKRISE2PIC, 15, NULL, &s_aqua_walk1};\r
+\r
+statetype s_aqua_sink1 = {EYESTALKRISE2PIC, 15, NULL, &s_aqua_sink2};\r
+statetype s_aqua_sink2 = {EYESTALKRISE1PIC, 20, NULL, &s_aqua_under1};\r
+\r
+statetype s_aqua_walk1 = {EYESTALKWALK1PIC, 12, &T_AquaMan, &s_aqua_walk2};\r
+statetype s_aqua_walk2 = {EYESTALKWALK2PIC, 12, &T_AquaMan, &s_aqua_walk1};\r
+\r
+statetype s_aqua_attack1 = {EYESTALKATTACKPIC, 10, NULL, &s_aqua_attack2};\r
+statetype s_aqua_attack2 = {EYESTALKWALK1PIC, 10, &T_DoDamage, &s_aqua_walk1};\r
+\r
+statetype s_aqua_die1 = {EYESTALKDEATH1PIC, 8, NULL, &s_aqua_die2};\r
+statetype s_aqua_die2 = {EYESTALKDEATH2PIC, 8, NULL, &s_aqua_die3};\r
+statetype s_aqua_die3 = {EYESTALKDEATH2PIC, -1, &T_AlternateStates, &s_aqua_die1};\r
+statetype s_aqua_die4 = {EYESTALKDEATH2PIC, 30, NULL, &s_aqua_die5};\r
+statetype s_aqua_die5 = {EYESTALKDEATH3PIC, 40, NULL, &s_aqua_die6};\r
+statetype s_aqua_die6 = {EYESTALKDEATH4PIC, 30, &ExplosionSnd, &s_aqua_die7};\r
+statetype s_aqua_die7 = {EYESTALKDEATH5PIC, 20, NULL, NULL};\r
+\r
+typedef enum {wt_UNDER, wt_WALK} AquaManTypes;\r
+\r
+#define AQ_TIMEREMAIN  (ob->temp1)\r
+#define AQ_STAGE                       (ob->temp2)\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnAquaMan\r
+=\r
+===============\r
+*/\r
+void SpawnAquaMan(int tilex, int tiley)\r
+{\r
+       objtype *ob;\r
+       SpawnNewObj(tilex,tiley,&s_aqua_under1,PIXRADIUS*32);\r
+       ob = new;\r
+\r
+       AQ_STAGE = wt_UNDER;\r
+       AQ_TIMEREMAIN = 60*4+random(60*3);\r
+\r
+       new->obclass = aquamanobj;\r
+       new->speed = 1000;\r
+       new->flags &= ~of_shootable;\r
+       new->hitpoints = EasyHitPoints(15);\r
+}\r
+\r
+void ExplosionSnd(objtype *ob)\r
+{\r
+       if (ob->temp1 != SOUNDPLAYED)\r
+       {\r
+               SD_PlaySound(BODY_EXPLODESND);\r
+               ob->temp1 = SOUNDPLAYED;\r
+\r
+       }\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_AquaMan\r
+=\r
+===============\r
+*/\r
+\r
+void T_AquaMan(objtype *ob)\r
+{\r
+       switch (AQ_STAGE)\r
+       {\r
+               case wt_UNDER:\r
+                       ob->flags &= ~of_shootable;\r
+                       if (Chase(ob,true))\r
+                       {\r
+                               // RISE & GOTO WALK STAGE\r
+                               //\r
+\r
+                               AQ_STAGE = wt_WALK;\r
+                               AQ_TIMEREMAIN = 60*5+random(60*5);\r
+                                       ob->state = &s_aqua_rise1;\r
+                               ob->speed = 2200;\r
+                               ob->ticcount = ob->state->tictime;\r
+                       }\r
+                       else\r
+                       {\r
+                               // DEC COUNTER - And check for WALK\r
+                               //\r
+                               if ((AQ_TIMEREMAIN-=realtics) < 0)\r
+                               {\r
+                                       // RISE & GOTO WALK STAGE\r
+                                       //\r
+\r
+                                       if (CheckHandAttack(ob))\r
+                                               break;\r
+\r
+                                       AQ_STAGE = wt_WALK;\r
+                                       AQ_TIMEREMAIN = 60+random(60*2);\r
+                                               ob->state = &s_aqua_rise1;\r
+                                       ob->speed = 2200;\r
+                                       ob->ticcount = ob->state->tictime;\r
+                               }\r
+                               else\r
+                               if (random(1000)<5)\r
+                               {\r
+                                       // RANDOM PEEK UP OUT OF WATER\r
+                                       //\r
+                                               if (random(2) == 0)\r
+                                                       ob->state = &s_aqua_left;\r
+                                               else\r
+                                                       ob->state = &s_aqua_right;\r
+                                       ob->ticcount = ob->state->tictime;\r
+                               }\r
+                       }\r
+                       break;\r
+\r
+\r
+               case wt_WALK:\r
+                       ob->flags |= of_shootable;\r
+                       if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))\r
+                       {\r
+                                       ob->state = &s_aqua_attack1;\r
+                               ob->ticcount = ob->state->tictime;\r
+                       }\r
+                       else\r
+                       {\r
+                               // DEC COUNTER - And check for SINK\r
+                               //\r
+                               if ((AQ_TIMEREMAIN-=realtics) < 0)\r
+                               {\r
+                                       // SINK & GOTO BUBBLE STAGE\r
+                                       //\r
+\r
+                                       AQ_STAGE = wt_UNDER;\r
+                                       AQ_TIMEREMAIN = 60*4+random(60*3);\r
+                                               ob->state = &s_aqua_sink1;\r
+                                       ob->speed = 1200;\r
+                                       ob->ticcount = ob->state->tictime;\r
+                                       ob->flags &= ~of_shootable;\r
+                               }\r
+\r
+                       }\r
+                       break;\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                                                       WIZARD\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Wizard(objtype *ob);\r
+void T_WizardShoot(objtype *ob);\r
+\r
+statetype s_wizard_walk1 = {WIZARDWALK1PIC, 20, &T_Wizard, &s_wizard_walk2};\r
+statetype s_wizard_walk2 = {WIZARDWALK2PIC, 20, &T_Wizard, &s_wizard_walk3};\r
+statetype s_wizard_walk3 = {WIZARDWALK3PIC, 20, &T_Wizard, &s_wizard_walk4};\r
+statetype s_wizard_walk4 = {WIZARDWALK4PIC, 20, &T_Wizard, &s_wizard_walk1};\r
+\r
+statetype s_wizard_attack1 = {WIZARDATTACK1PIC, 20, NULL, &s_wizard_attack2};\r
+statetype s_wizard_attack2 = {WIZARDATTACK2PIC, 20, &T_DoDamage, &s_wizard_walk1};\r
+\r
+statetype s_wizard_ouch = {WIZARDOUCHPIC, 15, NULL, &s_wizard_walk1};\r
+\r
+statetype s_wizard_die1 = {WIZARDDEATH1PIC, 45, &SmallSound, &s_wizard_die2};\r
+statetype s_wizard_die2 = {WIZARDDEATH2PIC, 30, NULL, &s_wizard_die3};\r
+statetype s_wizard_die3 = {WIZARDDEATH3PIC, 15, NULL, &s_wizard_die4};\r
+statetype s_wizard_die4 = {WIZARDDEATH4PIC, 15, NULL, &s_wizard_die4};\r
+\r
+statetype s_wizard_shoot1 = {WIZARDATTACK1PIC, 20, NULL, &s_wizard_shoot2};\r
+statetype s_wizard_shoot2 = {WIZARDATTACK1PIC, -1, &T_WizardShoot, &s_wizard_shoot3};\r
+statetype s_wizard_shoot3 = {WIZARDATTACK2PIC, 20, NULL, &s_wizard_walk1};\r
+\r
+statetype s_wizard_shot1 = {WIZARD_SHOT1PIC, 8, &T_ShootPlayer, &s_wizard_shot2};\r
+statetype s_wizard_shot2 = {WIZARD_SHOT2PIC, 8, &T_ShootPlayer, &s_wizard_shot1};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnWizard\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnWizard (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_wizard_walk1,TILEGLOBAL/2);\r
+       new->obclass    = wizardobj;\r
+       new->speed              = 1536;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints  = EasyHitPoints(10);\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Wizard\r
+=\r
+===============\r
+*/\r
+\r
+void T_Wizard(objtype *ob)\r
+{\r
+       if (Chase (ob,true))// || (random(1000)<RANDOM_ATTACK))\r
+       {\r
+               ob->state = &s_wizard_attack1;\r
+               ob->ticcount = ob->state->tictime;\r
+               return;\r
+       }\r
+       else\r
+               if (AngleNearPlayer(ob) != -1)\r
+               {\r
+                       ob->state = &s_wizard_shoot1;\r
+                       ob->ticcount = ob->state->tictime;\r
+                       return;\r
+               }\r
+}\r
+\r
+/*\r
+===============\r
+=\r
+= T_Wizard\r
+=\r
+===============\r
+*/\r
+void T_WizardShoot(objtype *ob)\r
+{\r
+       ShootPlayer(ob, wshotobj, 10000, &s_wizard_shot1);\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                                                       RAY\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_BlobRay(objtype *ob);\r
+void T_RayShoot (objtype *ob);\r
+\r
+statetype s_ray_under = {0, 20, &T_BlobRay, &s_ray_under};\r
+\r
+statetype s_ray_rise = {RAYRISEPIC, 30, NULL, &s_ray_fly1};\r
+\r
+statetype s_ray_sink = {RAYRISEPIC, 30, NULL, &s_ray_under};\r
+\r
+statetype s_ray_fly1 = {RAYFLY1PIC, 10, &T_BlobRay, &s_ray_fly2};\r
+statetype s_ray_fly2 = {RAYFLY2PIC, 10, &T_BlobRay, &s_ray_fly3};\r
+statetype s_ray_fly3 = {RAYFLY1PIC, 10, &T_BlobRay, &s_ray_fly4};\r
+statetype s_ray_fly4 = {RAYFLY3PIC, 10, &T_BlobRay, &s_ray_fly1};\r
+\r
+statetype s_ray_attack1 = {RAYSHOOT1PIC, 15, NULL, &s_ray_attack2};\r
+statetype s_ray_attack2 = {RAYSHOOT2PIC, -1, &T_RayShoot, &s_ray_attack3};\r
+statetype s_ray_attack3 = {RAYSHOOT2PIC, 20, NULL, &s_ray_fly1};\r
+\r
+statetype s_ray_die1 = {RAYDEATH1PIC, 50, &SmallSound, &s_ray_die2};\r
+statetype s_ray_die2 = {RAYDEATH2PIC, 30, NULL, NULL};\r
+\r
+statetype s_ray_shot1 = {RAYSHOT1PIC, 8, &T_ShootPlayer, &s_ray_shot2};\r
+statetype s_ray_shot2 = {RAYSHOT2PIC, 8, &T_ShootPlayer, &s_ray_shot1};\r
+\r
+\r
+typedef enum {br_GND, br_WALK, br_CORNER1, br_CORNER2, br_CORNER3, br_CORNER4} BlobTypes;\r
+\r
+#define BR_TIMEREMAIN  (ob->temp1)\r
+#define BR_STAGE                       (ob->temp2)\r
+#define BLOB_LEAVE             0x04\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnRay\r
+=\r
+===============\r
+*/\r
+void SpawnRay(int tilex, int tiley)\r
+{\r
+       objtype *ob;\r
+       SpawnNewObj(tilex, tiley, &s_ray_under, PIXRADIUS*25);\r
+       ob=new;\r
+\r
+       BR_STAGE = br_GND;\r
+       BR_TIMEREMAIN = random(60)+random(100);\r
+\r
+       new->obclass    = rayobj;\r
+       new->speed              = 1700;\r
+       new->flags      &= ~of_shootable;\r
+       new->hitpoints  = EasyHitPoints(15);\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                                               BLOB\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+statetype s_blob_gnd1 = {BLOBGND1PIC, 13, T_BlobRay, &s_blob_gnd2};\r
+statetype s_blob_gnd2 = {BLOBGND2PIC, 15, T_BlobRay, &s_blob_gnd1};\r
+\r
+statetype s_blob_rise1 = {BLOBRISE1PIC, 20, NULL, &s_blob_rise2};\r
+statetype s_blob_rise2 = {BLOBRISE2PIC, 20, NULL, &s_blob_walk1};\r
+\r
+statetype s_blob_sink1 = {BLOBRISE2PIC, 20, NULL, &s_blob_sink2};\r
+statetype s_blob_sink2 = {BLOBRISE1PIC, 20, NULL, &s_blob_gnd1};\r
+\r
+statetype s_blob_walk1 = {BLOBWALK1PIC, 15, T_BlobRay, &s_blob_walk2};\r
+statetype s_blob_walk2 = {BLOBWALK2PIC, 15, T_BlobRay, &s_blob_walk3};\r
+statetype s_blob_walk3 = {BLOBWALK3PIC, 15, T_BlobRay, &s_blob_walk1};\r
+\r
+statetype s_blob_ouch = {BLOBRISE2PIC, 10, T_BlobRay, &s_blob_walk1};\r
+\r
+statetype s_blob_die1 = {BLOBDEATH1PIC, 30, &ExplosionSnd, &s_blob_die2};\r
+statetype s_blob_die2 = {BLOBDEATH2PIC, 30, NULL, &s_blob_die3};\r
+statetype s_blob_die3 = {BLOBDEATH3PIC, 30, NULL, NULL};\r
+\r
+statetype s_blob_shot1 = {BLOB_SHOT1PIC, 8, &T_ShootPlayer, &s_blob_shot2};\r
+statetype s_blob_shot2 = {BLOB_SHOT2PIC, 8, &T_ShootPlayer, &s_blob_shot1};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnBlob\r
+=\r
+===============\r
+*/\r
+void SpawnBlob(int tilex, int tiley)\r
+{\r
+       objtype *ob;\r
+       SpawnNewObj(tilex, tiley, &s_blob_gnd1, PIXRADIUS*14);\r
+       ob=new;\r
+\r
+       BR_STAGE = br_GND;\r
+       BR_TIMEREMAIN = random(60)+random(100);\r
+\r
+       new->obclass    = blobobj;\r
+       new->speed              = 1200;\r
+       new->flags      &= ~of_shootable;\r
+       new->hitpoints  = EasyHitPoints(13);\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_BlobRay\r
+=\r
+===============\r
+*/\r
+\r
+void T_BlobRay(objtype *ob)\r
+{\r
+       switch (BR_STAGE)\r
+       {\r
+               case br_GND:\r
+                       ob->flags &= ~of_shootable;\r
+                       if (Chase(ob,true))\r
+                       {\r
+                               // RISE & GOTO WALK STAGE\r
+                               //\r
+\r
+                               BR_STAGE                        = br_WALK;\r
+                               BR_TIMEREMAIN   = 60*8+random(60*5);\r
+                               if (ob->obclass == blobobj)\r
+                                       ob->state       = &s_blob_rise1;\r
+                               else\r
+                                       ob->state       = &s_ray_rise;\r
+                               ob->speed               = 2200;\r
+                               ob->ticcount    = ob->state->tictime;\r
+                       }\r
+                       else\r
+                       {\r
+                               // DEC COUNTER - And check for WALK\r
+                               //\r
+                               if ((BR_TIMEREMAIN -= realtics) < 0)\r
+                               {\r
+                                       // RISE & GOTO WALK STAGE\r
+                                       //\r
+\r
+                                       BR_STAGE                        = br_WALK;\r
+                                       BR_TIMEREMAIN   = 60*8+random(60*5);\r
+                                       if (ob->obclass == blobobj)\r
+                                               ob->state       = &s_blob_rise1;\r
+                                       else\r
+                                               ob->state       = &s_ray_rise;\r
+                                       ob->speed               = 2200;\r
+                                       ob->ticcount    = ob->state->tictime;\r
+                               }\r
+                       }\r
+                       break;\r
+\r
+\r
+               case br_WALK:\r
+                       ob->flags |= of_shootable;\r
+\r
+                       if (Chase(ob,true) || (CheckHandAttack(ob)))\r
+\r
+                       {\r
+                                       ob->flags               |= BLOB_LEAVE;\r
+                                       BR_STAGE                        = random(br_CORNER3) + 2;\r
+                                       BR_TIMEREMAIN   = 60*2+(random(6)*60);\r
+                                       if (ob->obclass == blobobj)\r
+                                               ob->state       = &s_blob_gnd1;\r
+                                       else\r
+                                               ob->state       = &s_ray_under;\r
+                                       ob->ticcount    = ob->state->tictime;\r
+                       }\r
+                       else\r
+                               if (AngleNearPlayer(ob) != -1)\r
+                               {\r
+                                       if (ob->obclass == blobobj)\r
+                                       {\r
+                                               if (!(random(15)))\r
+                                                               ShootPlayer(ob, bshotobj, 10000, &s_blob_shot1);\r
+                                       }\r
+                                       else\r
+                                               if (!(random(7)))\r
+                                               {\r
+                                                       ob->state = &s_ray_attack1;\r
+                                                       ob->ticcount = ob->state->tictime;\r
+                                               }\r
+                               }\r
+\r
+                       else\r
+                       {\r
+                               // DEC COUNTER - And check for SINK\r
+                               //\r
+                               if ((BR_TIMEREMAIN -= realtics) < 0)\r
+                               {\r
+                                       // SINK & GOTO GROUND STAGE\r
+                                       //\r
+\r
+                                       BR_STAGE                        = br_GND;\r
+                                       BR_TIMEREMAIN   = 60*2+random(60*2);\r
+                                       if (ob->obclass == blobobj)\r
+                                       {\r
+                                               ob->state               = &s_blob_sink1;\r
+                                               ob->speed               = 1200;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               ob->state               = &s_ray_sink;\r
+                                               ob->speed               = 1700;\r
+                                       }\r
+                                       ob->ticcount    = ob->state->tictime;\r
+                                       ob->flags               &= ~of_shootable;\r
+                               }\r
+\r
+                       }\r
+                       break;\r
+               case br_CORNER1:\r
+               case br_CORNER2:\r
+               case br_CORNER3:\r
+               case br_CORNER4:\r
+                       ob->flags &= ~of_shootable;\r
+                       if ((BR_TIMEREMAIN -= realtics) < 0)\r
+                       {\r
+                               BR_STAGE = br_GND;\r
+                               ob->flags &= ~BLOB_LEAVE;\r
+                       }\r
+                       else\r
+                       {\r
+                               fixed tempx,tempy;\r
+                               unsigned temp_tilex,temp_tiley;\r
+\r
+                               tempx                   = player->x;\r
+                               tempy                   = player->y;\r
+                               temp_tilex      = player->tilex;\r
+                               temp_tiley      = player->tiley;\r
+\r
+                               player->x = ((long)other_x[BR_STAGE-2]<<TILESHIFT)+TILEGLOBAL/2;\r
+                               player->y = ((long)other_y[BR_STAGE-2]<<TILESHIFT)+TILEGLOBAL/2;\r
+                               player->tilex = other_x[BR_STAGE-2];\r
+                               player->tiley = other_y[BR_STAGE-2];\r
+\r
+\r
+                               Chase(ob,true);\r
+\r
+                               player->x               = tempx;\r
+                               player->y               = tempy;\r
+                               player->tilex   = temp_tilex;\r
+                               player->tiley   = temp_tiley;\r
+                       }\r
+                       break;\r
+       }\r
+}\r
+\r
+/*\r
+===============\r
+=\r
+= T_RayShoot\r
+=\r
+===============\r
+*/\r
+void T_RayShoot (objtype *ob)\r
+{\r
+       ShootPlayer(ob, rshotobj, 10000, &s_ray_shot1);\r
+}
\ No newline at end of file