]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/hp/act/c3_act1.c
not done making demohp.c. i gotta get the files to the other lappy4
[16.git] / src / lib / hp / act / c3_act1.c
diff --git a/src/lib/hp/act/c3_act1.c b/src/lib/hp/act/c3_act1.c
new file mode 100755 (executable)
index 0000000..2706b4f
--- /dev/null
@@ -0,0 +1,1259 @@
+/* Catacomb 3-D 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 "C3_DEF.H"\r
+#pragma hdrstop\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\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
+\r
+                                                 BONUS ITEMS\r
+\r
+=============================================================================\r
+*/\r
+\r
+extern statetype       s_boltbonus2;\r
+extern statetype       s_nukebonus2;\r
+\r
+statetype s_boltbonus = {BOLTOBJPIC,8,NULL,&s_boltbonus2};\r
+statetype s_boltbonus2 = {BOLTOBJ2PIC,8,NULL,&s_boltbonus};\r
+\r
+statetype s_nukebonus = {NUKEOBJPIC,8,NULL,&s_nukebonus2};\r
+statetype s_nukebonus2 = {NUKEOBJ2PIC,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_scrollbonus = {SCROLLOBJPIC,0,NULL,&s_scrollbonus};\r
+statetype s_chestbonus = {CHESTOBJPIC,0,NULL,&s_chestbonus};\r
+statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnBonus\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnBonus (int tilex, int tiley, int number)\r
+{\r
+       statetype *state;\r
+\r
+       if (number == B_BOLT)\r
+               state = &s_boltbonus;\r
+       else if (number == B_NUKE)\r
+               state = &s_nukebonus;\r
+       else if (number == B_POTION)\r
+               state = &s_potionbonus;\r
+       else if (number == B_RKEY)\r
+               state = &s_rkeybonus;\r
+       else if (number == B_YKEY)\r
+               state = &s_ykeybonus;\r
+       else if (number == B_GKEY)\r
+               state = &s_gkeybonus;\r
+       else if (number == B_BKEY)\r
+               state = &s_bkeybonus;\r
+       else if (number >= B_SCROLL1 && number <= B_SCROLL8)\r
+               state = &s_scrollbonus;\r
+       else if (number == B_CHEST)\r
+               state = &s_chestbonus;\r
+       else if (number == B_GOAL)\r
+               state = &s_goalbonus;\r
+\r
+       SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);\r
+       new->tileobject = true;\r
+       new->temp1 = number;\r
+       new->obclass = bonusobj;\r
+       new->shootable = false;\r
+}\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
+= ExplodeWall\r
+=\r
+================\r
+*/\r
+\r
+void ExplodeWall (int tilex, int tiley)\r
+{\r
+       SpawnNewObj (tilex,tiley,&s_walldie1,0);\r
+       new->obclass = inertobj;\r
+       new->active = true;\r
+       (unsigned)actorat[new->tilex][new->tiley] = tilemap[new->tilex][new->tiley] =\r
+       *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = WALLEXP;\r
+}\r
+\r
+\r
+/*\r
+================\r
+=\r
+= T_WallDie\r
+=\r
+================\r
+*/\r
+\r
+void T_WallDie (objtype *ob)\r
+{\r
+       unsigned tile,other;\r
+\r
+       if (++ob->temp1 == 3)\r
+               tile = 0;\r
+       else\r
+               tile = WALLEXP-1 + ob->temp1;\r
+\r
+       (unsigned)actorat[ob->tilex][ob->tiley] = tilemap[ob->tilex][ob->tiley] =\r
+       *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex) = tile;\r
+\r
+       if (ob->temp1 == 1)\r
+       {\r
+       //\r
+       // blow up nearby walls\r
+       //\r
+               other = tilemap[ob->tilex-1][ob->tiley];\r
+               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
+                       ExplodeWall (ob->tilex-1,ob->tiley);\r
+               other = tilemap[ob->tilex+1][ob->tiley];\r
+               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
+                       ExplodeWall (ob->tilex+1,ob->tiley);\r
+               other = tilemap[ob->tilex][ob->tiley-1];\r
+               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
+                       ExplodeWall (ob->tilex,ob->tiley-1);\r
+               other = tilemap[ob->tilex][ob->tiley+1];\r
+               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
+                       ExplodeWall (ob->tilex,ob->tiley+1);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                WARP GATE\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Gate (objtype *ob);\r
+\r
+extern statetype s_gate1;\r
+extern statetype s_gate2;\r
+extern statetype s_gate3;\r
+extern statetype s_gate4;\r
+\r
+extern statetype s_fgate1;\r
+extern statetype s_fgate2;\r
+extern statetype s_fgate3;\r
+extern statetype s_fgate4;\r
+\r
+statetype s_gate1 = {WARP1PIC,12,T_Gate,&s_gate2};\r
+statetype s_gate2 = {WARP2PIC,12,T_Gate,&s_gate3};\r
+statetype s_gate3 = {WARP3PIC,12,T_Gate,&s_gate4};\r
+statetype s_gate4 = {WARP4PIC,12,T_Gate,&s_gate1};\r
+\r
+statetype s_fgate1 = {WARP1PIC,6,T_Gate,&s_fgate2};\r
+statetype s_fgate2 = {WARP2PIC,6,T_Gate,&s_fgate3};\r
+statetype s_fgate3 = {WARP3PIC,6,T_Gate,&s_fgate4};\r
+statetype s_fgate4 = {WARP4PIC,6,T_Gate,&s_fgate1};\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnWarp\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnWarp (int tilex, int tiley, int type)\r
+{\r
+       if (type)\r
+               SpawnNewObj (tilex,tiley,&s_fgate1,TILEGLOBAL/3);\r
+       else\r
+               SpawnNewObj (tilex,tiley,&s_gate1,TILEGLOBAL/3);\r
+       new->obclass = gateobj;\r
+       new->temp1 = type;\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Gate\r
+=\r
+===============\r
+*/\r
+\r
+#define STATUSCOLOR    4\r
+\r
+void T_Gate (objtype *ob)\r
+{\r
+       int     spot;\r
+       objtype *check;\r
+       unsigned        temp;\r
+\r
+       if (CheckHandAttack (ob) && !playstate)\r
+       {\r
+       //\r
+       // warp\r
+       //\r
+               temp = bufferofs;\r
+               bufferofs = 0;\r
+               VW_Bar (26,4,232,9,STATUSCOLOR);                // clear text description\r
+               bufferofs = temp;\r
+               IN_ClearKeysDown ();\r
+               if (ob->temp1)\r
+               {\r
+               //\r
+               // teleport inside level\r
+               //\r
+                       for (check=player->next;check;check=check->next)\r
+                               if (check->obclass==gateobj && check->temp1==ob->temp1 &&\r
+                                       check != ob)\r
+                               {\r
+                                       player->x = check->x;\r
+                                       player->y = check->y;\r
+                                       Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
+                                       Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
+                                       Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
+                                       fizzlein=true;\r
+                               }\r
+               }\r
+               else\r
+               {\r
+               //\r
+               // teleport out of level\r
+               //\r
+                       playstate = ex_warped;\r
+                       spot = *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex)-NAMESTART;\r
+                       if (spot<1)\r
+                               gamestate.mapon++;\r
+                       else\r
+                               gamestate.mapon=spot-1;\r
+                       SD_PlaySound(WARPUPSND);\r
+               }\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  TROLLS\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Troll (objtype *ob);\r
+\r
+extern statetype s_trollpause;\r
+\r
+extern statetype s_troll1;\r
+extern statetype s_troll2;\r
+extern statetype s_troll3;\r
+extern statetype s_troll4;\r
+\r
+extern statetype s_trollattack1;\r
+extern statetype s_trollattack2;\r
+extern statetype s_trollattack3;\r
+\r
+extern statetype s_trollouch;\r
+\r
+extern statetype s_trolldie1;\r
+extern statetype s_trolldie2;\r
+extern statetype s_trolldie3;\r
+\r
+\r
+statetype s_trollpause = {TROLL1PIC,40,NULL,&s_troll2};\r
+\r
+statetype s_troll1 = {TROLL1PIC,13,T_Troll,&s_troll2};\r
+statetype s_troll2 = {TROLL2PIC,13,T_Troll,&s_troll3};\r
+statetype s_troll3 = {TROLL3PIC,13,T_Troll,&s_troll4};\r
+statetype s_troll4 = {TROLL4PIC,13,T_Troll,&s_troll1};\r
+\r
+statetype s_trollattack1 = {TROLLATTACK1PIC,20,NULL,&s_trollattack2};\r
+statetype s_trollattack2 = {TROLLATTACK2PIC,10,T_DoDamage,&s_trollattack3};\r
+statetype s_trollattack3 = {TROLLATTACK2PIC,40,NULL,&s_trollpause};\r
+\r
+statetype s_trollouch = {TROLLOUCHPIC,8,NULL,&s_troll1};\r
+\r
+statetype s_trolldie1 = {TROLLDIE1PIC,8,NULL,&s_trolldie2};\r
+statetype s_trolldie2 = {TROLLDIE2PIC,8,NULL,&s_trolldie3};\r
+statetype s_trolldie3 = {TROLLDIE3PIC,0,NULL,&s_trolldie3};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnTroll\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnTroll (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_troll1,40*PIXRADIUS);\r
+       new->speed = 2500;\r
+       new->obclass = trollobj;\r
+       new->shootable = true;\r
+       new->hitpoints = 10;\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Troll\r
+=\r
+===============\r
+*/\r
+\r
+void T_Troll (objtype *ob)\r
+{\r
+       if (Chase (ob,true))\r
+       {\r
+               ob->state = &s_trollattack1;\r
+               ob->ticcount = ob->state->tictime;\r
+               return;\r
+       }\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  ORCS\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Orc (objtype *ob);\r
+\r
+extern statetype s_orcpause;\r
+\r
+extern statetype s_orc1;\r
+extern statetype s_orc2;\r
+extern statetype s_orc3;\r
+extern statetype s_orc4;\r
+\r
+extern statetype s_orcattack1;\r
+extern statetype s_orcattack2;\r
+extern statetype s_orcattack3;\r
+\r
+extern statetype s_orcouch;\r
+\r
+extern statetype s_orcdie1;\r
+extern statetype s_orcdie2;\r
+extern statetype s_orcdie3;\r
+\r
+\r
+\r
+statetype s_orcpause = {ORC1PIC,40,NULL,&s_orc2};\r
+\r
+statetype s_orc1 = {ORC1PIC,20,T_Orc,&s_orc2};\r
+statetype s_orc2 = {ORC2PIC,20,T_Orc,&s_orc3};\r
+statetype s_orc3 = {ORC3PIC,20,T_Orc,&s_orc4};\r
+statetype s_orc4 = {ORC4PIC,20,T_Orc,&s_orc1};\r
+\r
+statetype s_orcattack1 = {ORCATTACK1PIC,20,NULL,&s_orcattack2};\r
+statetype s_orcattack2 = {ORCATTACK2PIC,10,T_DoDamage,&s_orcattack3};\r
+statetype s_orcattack3 = {ORCATTACK2PIC,40,NULL,&s_orcpause};\r
+\r
+statetype s_orcouch = {ORCOUCHPIC,10,NULL,&s_orc1};\r
+\r
+statetype s_orcdie1 = {ORCDIE1PIC,8,NULL,&s_orcdie2};\r
+statetype s_orcdie2 = {ORCDIE2PIC,8,NULL,&s_orcdie3};\r
+statetype s_orcdie3 = {ORCDIE3PIC,0,NULL,&s_orcdie3};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnOrc\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnOrc (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_orc1,PIXRADIUS*32);\r
+       new->obclass = orcobj;\r
+       new->speed = 1536;\r
+       new->shootable = true;\r
+       new->hitpoints = 3;\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Orc\r
+=\r
+===============\r
+*/\r
+\r
+void T_Orc (objtype *ob)\r
+{\r
+       if (Chase (ob,true))\r
+       {\r
+               ob->state = &s_orcattack1;\r
+               ob->ticcount = ob->state->tictime;\r
+               return;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  DEMON\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Demon (objtype *ob);\r
+\r
+\r
+extern statetype s_demonpause;\r
+\r
+extern statetype s_demon1;\r
+extern statetype s_demon2;\r
+extern statetype s_demon3;\r
+extern statetype s_demon4;\r
+\r
+extern statetype s_demonattack1;\r
+extern statetype s_demonattack2;\r
+extern statetype s_demonattack3;\r
+\r
+extern statetype s_demonouch;\r
+\r
+extern statetype s_demondie1;\r
+extern statetype s_demondie2;\r
+extern statetype s_demondie3;\r
+\r
+\r
+statetype s_demonpause = {DEMON1PIC,40,NULL,&s_demon2};\r
+\r
+statetype s_demon1 = {DEMON1PIC,20,T_Demon,&s_demon2};\r
+statetype s_demon2 = {DEMON2PIC,20,T_Demon,&s_demon3};\r
+statetype s_demon3 = {DEMON3PIC,20,T_Demon,&s_demon4};\r
+statetype s_demon4 = {DEMON4PIC,20,T_Demon,&s_demon1};\r
+\r
+statetype s_demonattack1 = {DEMONATTACK1PIC,20,NULL,&s_demonattack2};\r
+statetype s_demonattack2 = {DEMONATTACK2PIC,20,T_DoDamage,&s_demonattack3};\r
+statetype s_demonattack3 = {DEMONATTACK3PIC,30,NULL,&s_demonpause};\r
+\r
+statetype s_demonouch = {DEMONOUCHPIC,10,NULL,&s_demon1};\r
+\r
+statetype s_demondie1 = {DEMONDIE1PIC,20,NULL,&s_demondie2};\r
+statetype s_demondie2 = {DEMONDIE2PIC,20,NULL,&s_demondie3};\r
+statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};\r
+\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnDemon\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnDemon (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_demon1,TILEGLOBAL/2);\r
+       new->obclass = demonobj;\r
+       new->speed = 2048;\r
+       new->shootable = true;\r
+       new->hitpoints = 50;\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Demon\r
+=\r
+===============\r
+*/\r
+\r
+void T_Demon (objtype *ob)\r
+{\r
+       if (Chase (ob,true))\r
+       {\r
+               ob->state = &s_demonattack1;\r
+               ob->ticcount = ob->state->tictime;\r
+               return;\r
+       }\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       MSHOTS\r
+\r
+temp1 = dir\r
+\r
+=============================================================================\r
+*/\r
+\r
+#define MSHOTDAMAGE    2\r
+#define MSHOTSPEED     10000\r
+\r
+void T_Mshot (objtype *ob);\r
+\r
+\r
+extern statetype s_mshot1;\r
+extern statetype s_mshot2;\r
+\r
+statetype s_mshot1 = {PSHOT1PIC,8,&T_Mshot,&s_mshot2};\r
+statetype s_mshot2 = {PSHOT2PIC,8,&T_Mshot,&s_mshot1};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Mshot\r
+=\r
+===============\r
+*/\r
+\r
+void T_Mshot (objtype *ob)\r
+{\r
+       objtype *check;\r
+       long    xmove,ymove,speed;\r
+\r
+       xmove = ymove = 0;\r
+\r
+       switch (ob->dir)\r
+       {\r
+       case north:\r
+               ymove = -ob->speed*tics;\r
+               break;\r
+       case east:\r
+               xmove = ob->speed*tics;\r
+               break;\r
+       case south:\r
+               ymove = ob->speed*tics;\r
+               break;\r
+       case west:\r
+               xmove = -ob->speed*tics;\r
+               break;\r
+       }\r
+\r
+       ob->x+=xmove;\r
+       ob->y+=ymove;\r
+\r
+       CalcBounds (ob);\r
+\r
+       ob->tilex = ob->x>>TILESHIFT;\r
+       ob->tiley = ob->y>>TILESHIFT;\r
+\r
+       if (tilemap[ob->tilex][ob->tiley])\r
+       {\r
+               SD_PlaySound (SHOOTWALLSND);\r
+               ob->state = NULL;\r
+               return;\r
+       }\r
+\r
+//\r
+// check final position for monsters hit\r
+//\r
+       if ( ob->xl <= player->xh\r
+       && ob->xh >= player->xl\r
+       && ob->yl <= player->yh\r
+       && ob->yh >= player->yl)\r
+       {\r
+               TakeDamage (MSHOTDAMAGE*2);\r
+               ob->state = NULL;\r
+               return;\r
+       }\r
+\r
+       for (check = player->next; check; check=check->next)\r
+               if (ob->shootable && ob->obclass != mageobj\r
+               && ob->xl <= check->xh\r
+               && ob->xh >= check->xl\r
+               && ob->yl <= check->yh\r
+               && ob->yh >= check->yl)\r
+               {\r
+                       ShootActor (check,MSHOTDAMAGE);\r
+                       ob->state = NULL;\r
+                       return;\r
+               }\r
+}\r
+\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       MAGE\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+void T_Mage (objtype *ob);\r
+void T_MageShoot (objtype *ob);\r
+\r
+extern statetype s_magepause;\r
+\r
+extern statetype s_mage1;\r
+extern statetype s_mage2;\r
+\r
+extern statetype s_mageattack1;\r
+extern statetype s_mageattack2;\r
+extern statetype s_mageattack3;\r
+\r
+extern statetype s_mageouch;\r
+\r
+extern statetype s_magedie1;\r
+extern statetype s_magedie2;\r
+\r
+\r
+statetype s_magepause = {MAGE1PIC,100,NULL,&s_mage2};\r
+\r
+statetype s_mage1 = {MAGE1PIC,20,T_Mage,&s_mage2};\r
+statetype s_mage2 = {MAGE2PIC,20,T_Mage,&s_mage1};\r
+\r
+statetype s_mageattack1 = {MAGEATTACKPIC,20,NULL,&s_mageattack2};\r
+statetype s_mageattack2 = {MAGEATTACKPIC,-1,T_MageShoot,&s_mageattack3};\r
+statetype s_mageattack3 = {MAGEATTACKPIC,30,NULL,&s_magepause};\r
+\r
+statetype s_mageouch = {MAGEOUCHPIC,10,NULL,&s_mage1};\r
+\r
+statetype s_magedie1 = {MAGEDIE1PIC,20,NULL,&s_magedie2};\r
+statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnMage\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnMage (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_mage1,TILEGLOBAL/2);\r
+       new->obclass = mageobj;\r
+       new->speed = 2048;\r
+       new->shootable = true;\r
+       new->hitpoints = 5;\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Mage\r
+=\r
+===============\r
+*/\r
+\r
+void T_Mage (objtype *ob)\r
+{\r
+       Chase (ob,false);\r
+//\r
+// check for line up with player\r
+//\r
+\r
+       if (ob->x-PIXRADIUS*14 < player->xh\r
+       && ob->x+PIXRADIUS > player->xl)\r
+       {\r
+               ob->temp1 = 1;\r
+               ob->state = &s_mageattack1;\r
+       }\r
+       else if (ob->y-PIXRADIUS*14 < player->yh\r
+       && ob->y+PIXRADIUS > player->yl)\r
+       {\r
+               ob->temp1 = 0;\r
+               ob->state = &s_mageattack1;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_MageShoot\r
+=\r
+===============\r
+*/\r
+\r
+void T_MageShoot (objtype *ob)\r
+{\r
+       SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);\r
+       new->obclass = mshotobj;\r
+       new->speed = MSHOTSPEED;\r
+       if (ob->temp1)\r
+       {\r
+               if (ob->tiley < player->tiley)\r
+                       new->dir = south;\r
+               else\r
+                       new->dir = north;\r
+       }\r
+       else\r
+       {\r
+               if (ob->tilex < player->tilex)\r
+                       new->dir = east;\r
+               else\r
+                       new->dir = west;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       nemesis\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+void T_Nemesis (objtype *ob);\r
+void T_NemesisShoot (objtype *ob);\r
+\r
+extern statetype s_grelpause;\r
+\r
+extern statetype s_grel1;\r
+extern statetype s_grel2;\r
+\r
+extern statetype s_grelattack1;\r
+extern statetype s_grelattack2;\r
+extern statetype s_grelattack3;\r
+\r
+extern statetype s_grelouch;\r
+\r
+extern statetype s_greldie1;\r
+extern statetype s_greldie2;\r
+extern statetype s_greldie3;\r
+extern statetype s_greldie4;\r
+extern statetype s_greldie5;\r
+extern statetype s_greldie6;\r
+\r
+\r
+statetype s_grelpause = {GREL1PIC,50,NULL,&s_grel2};\r
+\r
+statetype s_grel1 = {GREL1PIC,20,T_Nemesis,&s_grel2};\r
+statetype s_grel2 = {GREL2PIC,20,T_Nemesis,&s_grel1};\r
+\r
+statetype s_grelattack1 = {GRELATTACKPIC,20,NULL,&s_grelattack2};\r
+statetype s_grelattack2 = {GRELATTACKPIC,-1,T_NemesisShoot,&s_grelattack3};\r
+statetype s_grelattack3 = {GRELATTACKPIC,30,NULL,&s_grelpause};\r
+\r
+statetype s_grelouch = {GRELHITPIC,6,NULL,&s_grel1};\r
+\r
+statetype s_greldie1 = {GRELDIE1PIC,20,NULL,&s_greldie2};\r
+statetype s_greldie2 = {GRELDIE2PIC,20,NULL,&s_greldie3};\r
+statetype s_greldie3 = {GRELDIE3PIC,20,NULL,&s_greldie4};\r
+statetype s_greldie4 = {GRELDIE4PIC,20,NULL,&s_greldie5};\r
+statetype s_greldie5 = {GRELDIE5PIC,20,NULL,&s_greldie6};\r
+statetype s_greldie6 = {GRELDIE6PIC,0,NULL,&s_greldie6};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnNemesis\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnNemesis (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*56);\r
+       new->obclass = grelmobj;\r
+       new->speed = 2048;\r
+       new->shootable = true;\r
+       new->hitpoints = 100;\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Nemesis\r
+=\r
+===============\r
+*/\r
+\r
+void T_Nemesis (objtype *ob)\r
+{\r
+       Chase (ob,false);\r
+//\r
+// check for line up with player\r
+//\r
+       if (ob->tilex == player->tilex)\r
+       {\r
+               ob->temp1 = 1;\r
+               ob->state = &s_grelattack1;\r
+       }\r
+       else if (ob->tiley == player->tiley)\r
+       {\r
+               ob->temp1 = 0;\r
+               ob->state = &s_grelattack1;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_NemesisShoot\r
+=\r
+===============\r
+*/\r
+\r
+void T_NemesisShoot (objtype *ob)\r
+{\r
+       SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);\r
+       new->obclass = mshotobj;\r
+       new->speed = MSHOTSPEED;\r
+       if (ob->temp1)\r
+       {\r
+               if (ob->tiley < player->tiley)\r
+                       new->dir = south;\r
+               else\r
+                       new->dir = north;\r
+       }\r
+       else\r
+       {\r
+               if (ob->tilex < player->tilex)\r
+                       new->dir = east;\r
+               else\r
+                       new->dir = west;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  BAT\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Bat (objtype *ob);\r
+void T_BatPast (objtype *ob);\r
+\r
+extern statetype s_bat1;\r
+extern statetype s_bat2;\r
+extern statetype s_bat3;\r
+extern statetype s_bat4;\r
+\r
+extern statetype s_batdie1;\r
+extern statetype s_batdie2;\r
+\r
+\r
+statetype s_bat1 = {BAT1PIC,6,T_Bat,&s_bat2};\r
+statetype s_bat2 = {BAT2PIC,6,T_Bat,&s_bat3};\r
+statetype s_bat3 = {BAT3PIC,6,T_Bat,&s_bat4};\r
+statetype s_bat4 = {BAT4PIC,6,T_Bat,&s_bat1};\r
+\r
+statetype s_batpast = {BAT4PIC,80,T_BatPast,&s_bat1};\r
+\r
+statetype s_batdie1 = {BATDIE1PIC,8,NULL,&s_batdie2};\r
+statetype s_batdie2 = {BATDIE2PIC,8,NULL,NULL};\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnBat\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnBat (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*24);\r
+       new->obclass =batobj;\r
+       new->shootable = true;\r
+\r
+       new->hitpoints = 1;\r
+       new->speed = 2000;\r
+}\r
+\r
+\r
+/*\r
+==================================\r
+=\r
+= BatChaseThink\r
+=\r
+==================================\r
+*/\r
+\r
+void BatChaseThink (objtype *obj)\r
+{\r
+       int deltax,deltay;\r
+\r
+       deltax=player->tilex - obj->tilex;\r
+       deltay=player->tiley - obj->tiley;\r
+\r
+       if (deltax>0)\r
+               deltax = 2;\r
+       else if (deltax<0)\r
+               deltax = 0;\r
+       else deltax = 1;\r
+\r
+       if (deltay>0)\r
+               deltay = 2;\r
+       else if (deltay<0)\r
+               deltay = 0;\r
+       else deltay = 1;\r
+\r
+       obj->dir = dirtable[deltay*3+deltax];\r
+       if (Walk(obj))\r
+               return;\r
+\r
+       obj->dir = dirtable[3+deltax];\r
+       if (Walk(obj))\r
+               return;\r
+\r
+       obj->dir = dirtable[deltay*3+1];\r
+       if (Walk(obj))\r
+               return;\r
+\r
+       obj->dir = nodir;\r
+}\r
+\r
+\r
+void BatRunThink (objtype *obj)\r
+{\r
+       int deltax,deltay;\r
+\r
+       deltax=player->tilex - obj->tilex;\r
+       deltay=player->tiley - obj->tiley;\r
+\r
+       if (deltax>=0)\r
+               deltax = 0;\r
+       else\r
+               deltax = 2;\r
+\r
+       if (deltay>=0)\r
+               deltay = 0;\r
+       else\r
+               deltay = 2;\r
+\r
+       obj->dir = dirtable[deltay*3+deltax];\r
+       if (Walk(obj))\r
+               return;\r
+\r
+       obj->dir = dirtable[3+deltax];\r
+       if (Walk(obj))\r
+               return;\r
+\r
+       obj->dir = dirtable[deltay*3+1];\r
+       Walk(obj);\r
+}\r
+\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Bat\r
+=\r
+===============\r
+*/\r
+\r
+void T_Bat (objtype *ob)\r
+{\r
+       long move;\r
+       long deltax,deltay,size;\r
+\r
+       move = ob->speed*tics;\r
+       size = (long)ob->size + player->size + move;\r
+\r
+\r
+       do\r
+       {\r
+               deltax = ob->x - player->x;\r
+               deltay = ob->y - player->y;\r
+\r
+               if (deltax <= size && deltax >= -size\r
+               && deltay <= size && deltay >= -size && !ob->temp1)\r
+               {\r
+                       TakeDamage (4);\r
+                       ob->temp1 = 2;\r
+               }\r
+\r
+               if (move < ob->distance)\r
+               {\r
+                       MoveObj (ob,move);\r
+                       break;\r
+               }\r
+\r
+               actorat[ob->tilex][ob->tiley] = 0;      // pick up marker from goal\r
+               if (ob->dir == nodir)\r
+                       ob->dir = north;\r
+\r
+               ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;\r
+               ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;\r
+               move -= ob->distance;\r
+\r
+               if (ob->temp1)\r
+               {\r
+                       Walk (ob);                              // go straight\r
+                       if (!--ob->temp1)\r
+                       {\r
+                               ob->state = &s_batpast;\r
+                               ob->ticcount = ob->state->tictime;\r
+                       }\r
+               }\r
+               else\r
+                       BatChaseThink (ob);             // head towards player\r
+\r
+               actorat[ob->tilex][ob->tiley] = ob;     // set down a new goal marker\r
+       } while (0);    // just once\r
+       CalcBounds (ob);\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_BatPast\r
+=\r
+===============\r
+*/\r
+\r
+void T_BatPast (objtype *ob)\r
+{\r
+       long move;\r
+       long deltax,deltay,size;\r
+\r
+       move = ob->speed*tics;\r
+\r
+       do\r
+       {\r
+               if (move < ob->distance)\r
+               {\r
+                       MoveObj (ob,move);\r
+                       break;\r
+               }\r
+               actorat[ob->tilex][ob->tiley] = 0;      // pick up marker from goal\r
+\r
+               ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;\r
+               ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;\r
+               move -= ob->distance;\r
+\r
+               BatRunThink (ob);\r
+\r
+               actorat[ob->tilex][ob->tiley] = ob;     // set down a new goal marker\r
+       } while (0);    //(move)\r
+       CalcBounds (ob);\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  BOUNCE\r
+\r
+temp2 = set when hit player, reset when hit wall\r
+\r
+=============================================================================\r
+*/\r
+\r
+#define SPDBOUNCE      4096\r
+#define DMGBOUNCE      10\r
+\r
+void T_Bounce (objtype *ob);\r
+\r
+extern statetype s_bounce1;\r
+extern statetype s_bounce2;\r
+\r
+\r
+statetype s_bounce1 = {BIGPSHOT1PIC,8,T_Bounce,&s_bounce2};\r
+statetype s_bounce2 = {BIGPSHOT2PIC,8,T_Bounce,&s_bounce1};\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnBounce\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnBounce (int tilex, int tiley, boolean towest)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_bounce1,24*PIXRADIUS);\r
+       new->obclass = bounceobj;\r
+       if (towest)\r
+               new->dir = west;\r
+       else\r
+               new->dir = north;\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Bounce\r
+=\r
+===============\r
+*/\r
+\r
+void T_Bounce (objtype *ob)\r
+{\r
+       long move;\r
+       long deltax,deltay,size;\r
+\r
+       move = SPDBOUNCE*tics;\r
+       size = (long)ob->size + player->size + move;\r
+\r
+       while (move)\r
+       {\r
+               deltax = ob->x - player->x;\r
+               deltay = ob->y - player->y;\r
+\r
+               if (deltax <= size && deltax >= -size\r
+               && deltay <= size && deltay >= -size && !ob->temp2)\r
+               {\r
+                       ob->temp2 = 1;\r
+                       TakeDamage (DMGBOUNCE);\r
+               }\r
+\r
+               if (move < ob->distance)\r
+               {\r
+                       MoveObj (ob,move);\r
+                       break;\r
+               }\r
+               actorat[ob->tilex][ob->tiley] = 0;      // pick up marker from goal\r
+\r
+               ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;\r
+               ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;\r
+               move -= ob->distance;\r
+\r
+               //\r
+               // bounce if hit wall\r
+               //\r
+               switch (ob->dir)\r
+               {\r
+               case north:\r
+                       if (tilemap[ob->tilex][--ob->tiley])\r
+                       {\r
+                               ob->dir = south;\r
+                               ob->tiley+=2;\r
+                               ob->temp2 = 0;\r
+                       }\r
+                       break;\r
+               case east:\r
+                       if (tilemap[++ob->tilex][ob->tiley])\r
+                       {\r
+                               ob->dir = west;\r
+                               ob->tilex-=2;\r
+                               ob->temp2 = 0;\r
+                       }\r
+                       break;\r
+               case south:\r
+                       if (tilemap[ob->tilex][++ob->tiley])\r
+                       {\r
+                               ob->dir = north;\r
+                               ob->tiley-=2;\r
+                               ob->temp2 = 0;\r
+                       }\r
+                       break;\r
+               case west:\r
+                       if (tilemap[--ob->tilex][ob->tiley])\r
+                       {\r
+                               ob->dir = east;\r
+                               ob->tilex+=2;\r
+                               ob->temp2 = 0;\r
+                       }\r
+                       break;\r
+               }\r
+\r
+               ob->distance = TILEGLOBAL;\r
+\r
+               actorat[ob->tilex][ob->tiley] = ob;     // set down a new goal marker\r
+       }\r
+       CalcBounds (ob);\r
+}\r
+\r