]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/hb/kd_act1.c
[16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / src / lib / hb / kd_act1.c
diff --git a/src/lib/hb/kd_act1.c b/src/lib/hb/kd_act1.c
new file mode 100755 (executable)
index 0000000..d2cf917
--- /dev/null
@@ -0,0 +1,1130 @@
+/* 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
+// KD_ACT1.C\r
+#include "KD_DEF.H"\r
+#pragma hdrstop\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+#define PLACESPRITE RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum, \\r
+       spritedraw,0);\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+int    flowertime[4] = {700,700,350,175};\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                               MISC ACTOR STUFF\r
+\r
+=============================================================================\r
+*/\r
+\r
+/*\r
+==================\r
+=\r
+= DoGravity\r
+=\r
+= Changes speed and location\r
+=\r
+==================\r
+*/\r
+\r
+\r
+void DoGravity (objtype *ob)\r
+{\r
+       long    i;\r
+//\r
+// only accelerate on odd tics, because of limited precision\r
+//\r
+       for (i=lasttimecount-tics;i<lasttimecount;i++)\r
+       {\r
+               if (i&1)\r
+               {\r
+                       if (ob->yspeed < 0 && ob->yspeed >= -ACCGRAVITY)\r
+                       {\r
+                       // stop at apex of jump\r
+                               ob->ymove += ob->yspeed;\r
+                               ob->yspeed = 0;\r
+                               return;\r
+                       }\r
+                       ob->yspeed+=ACCGRAVITY;\r
+                       if (ob->yspeed>SPDMAXY)\r
+                         ob->yspeed=SPDMAXY;\r
+               }\r
+               ob->ymove+=ob->yspeed;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= AccelerateX\r
+=\r
+===============\r
+*/\r
+\r
+void AccelerateX (objtype *ob,int dir,int max)\r
+{\r
+       long    i;\r
+       unsigned        olddir;\r
+\r
+       olddir = ob->xspeed & 0x8000;\r
+//\r
+// only accelerate on odd tics, because of limited precision\r
+//\r
+       for (i=lasttimecount-tics;i<lasttimecount;i++)\r
+       {\r
+               if (i&1)\r
+               {\r
+                       ob->xspeed+=dir;\r
+                       if ( (ob->xspeed & 0x8000) != olddir)\r
+                       {\r
+                               olddir = ob->xspeed & 0x8000;\r
+                               ob->xdir = olddir ? -1 : 1;\r
+                       }\r
+                       if (ob->xspeed>max)\r
+                         ob->xspeed=max;\r
+                       else if (ob->xspeed<-max)\r
+                         ob->xspeed=-max;\r
+               }\r
+               ob->xmove+=ob->xspeed;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= FrictionX\r
+=\r
+===============\r
+*/\r
+\r
+void FrictionX (objtype *ob)\r
+{\r
+       long    i;\r
+       int             dir;\r
+       unsigned        olddir;\r
+\r
+       olddir = ob->xspeed & 0x8000;\r
+\r
+       if (ob->xspeed > 0)\r
+               dir = -1;\r
+       else if (ob->xspeed < 0)\r
+               dir = 1;\r
+       else\r
+               dir = 0;\r
+//\r
+// only accelerate on odd tics, because of limited precision\r
+//\r
+       for (i=lasttimecount-tics;i<lasttimecount;i++)\r
+       {\r
+               if (i&1)\r
+               {\r
+                       ob->xspeed+=dir;\r
+                       if ( (ob->xspeed & 0x8000) != olddir)\r
+                               ob->xspeed = 0;\r
+               }\r
+               ob->xmove+=ob->xspeed;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= ProjectileThink\r
+=\r
+===============\r
+*/\r
+\r
+void ProjectileThink (objtype *ob)\r
+{\r
+       DoGravity (ob);\r
+       ob->xmove = tics*ob->xspeed;\r
+}\r
+\r
+/*\r
+===============\r
+=\r
+= VelocityThink\r
+=\r
+===============\r
+*/\r
+\r
+void VelocityThink (objtype *ob)\r
+{\r
+       ob->xmove = tics*ob->xspeed;\r
+       ob->ymove = tics*ob->yspeed;\r
+}\r
+\r
+/*\r
+===============\r
+=\r
+= DrawReact\r
+=\r
+===============\r
+*/\r
+\r
+void DrawReact (objtype *ob)\r
+{\r
+       RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,1);\r
+}\r
+\r
+void DrawReact2 (objtype *ob)\r
+{\r
+       RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,2);\r
+}\r
+\r
+void DrawReact3 (objtype *ob)\r
+{\r
+       RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,3);\r
+}\r
+\r
+/*\r
+==================\r
+=\r
+= ChangeState\r
+=\r
+==================\r
+*/\r
+\r
+void ChangeState (objtype *ob, statetype *state)\r
+{\r
+       ob->state = state;\r
+       ob->ticcount = 0;\r
+       if (state->rightshapenum)\r
+       {\r
+               if (ob->xdir>0)\r
+                       ob->shapenum = state->rightshapenum;\r
+               else\r
+                       ob->shapenum = state->leftshapenum;\r
+       }\r
+\r
+       ob->xmove = 0;\r
+       ob->ymove = 0;\r
+\r
+       ob->needtoreact = true;                 // it will need to be redrawn this frame\r
+       ClipToWalls (ob);\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= WalkReact\r
+=\r
+====================\r
+*/\r
+\r
+void WalkReact (objtype *ob)\r
+{\r
+       if (ob->xdir == 1 && ob->hitwest)\r
+       {\r
+               ob->x -= ob->xmove;\r
+               ob->xdir = -1;\r
+               ob->nothink = US_RndT()>>5;\r
+               ChangeState (ob,ob->state);\r
+       }\r
+       else if (ob->xdir == -1 && ob->hiteast)\r
+       {\r
+               ob->x -= ob->xmove;\r
+               ob->xdir = 1;\r
+               ob->nothink = US_RndT()>>5;\r
+               ChangeState (ob,ob->state);\r
+       }\r
+       else if (!ob->hitnorth)\r
+       {\r
+               ob->x -= 2*ob->xmove;\r
+               ob->y -= ob->ymove;\r
+\r
+               ob->xdir = -ob->xdir;\r
+               ob->nothink = US_RndT()>>5;\r
+               ChangeState (ob,ob->state);\r
+       }\r
+\r
+       PLACESPRITE;\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       DOOR\r
+\r
+=============================================================================\r
+*/\r
+\r
+void   DoorContact (objtype *ob, objtype *hit);\r
+\r
+extern statetype s_door;\r
+extern statetype s_doorraise;\r
+\r
+statetype s_door        = {DOORSPR,DOORSPR,think,false,\r
+       false,0, 0,0, NULL, DoorContact, DrawReact, &s_door};\r
+statetype s_doorraise = {DOORSPR,DOORSPR,slide,false,\r
+       false,24, 0,32, NULL, DoorContact, DrawReact, NULL};\r
+\r
+/*\r
+======================\r
+=\r
+= SpawnDoor\r
+=\r
+======================\r
+*/\r
+\r
+void   SpawnDoor (int tilex, int tiley)\r
+{\r
+       GetNewObj (false);\r
+\r
+       new->obclass = doorobj;\r
+       new->x = tilex<<G_T_SHIFT;\r
+       new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;\r
+       new->xdir = 1;\r
+       new->ydir = -1;\r
+       new->needtoclip = false;\r
+       NewState (new,&s_door);\r
+}\r
+\r
+/*\r
+======================\r
+=\r
+= DoorContact\r
+=\r
+======================\r
+*/\r
+\r
+void   DoorContact (objtype *ob, objtype *hit)\r
+{\r
+       ClipToSpriteSide (hit,ob);\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       FLOWER\r
+\r
+temp1 = original class\r
+temp2 = original state\r
+temp3 = flower count\r
+\r
+=============================================================================\r
+*/\r
+\r
+void ChangeToFlower (objtype *ob);\r
+void FlowerThink (objtype *ob);\r
+void ChangeFromFlower (objtype *ob);\r
+\r
+extern statetype s_flower1;\r
+extern statetype s_flower2;\r
+extern statetype s_flower3;\r
+extern statetype s_flower4;\r
+extern statetype s_flower5;\r
+extern statetype s_flower6;\r
+\r
+extern statetype s_poofto1;\r
+extern statetype s_poofto2;\r
+extern statetype s_poofto3;\r
+extern statetype s_poofto4;\r
+\r
+extern statetype s_pooffrom1;\r
+extern statetype s_pooffrom2;\r
+extern statetype s_pooffrom3;\r
+extern statetype s_pooffrom4;\r
+extern statetype s_pooffrom5;\r
+extern statetype s_pooffrom6;\r
+extern statetype s_pooffrom7;\r
+\r
+extern statetype s_bonus1;\r
+\r
+#pragma warn -sus\r
+\r
+statetype s_flower1     = {FLOWER1SPR,FLOWER1SPR,stepthink,false,\r
+       false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower2};\r
+statetype s_flower2     = {FLOWER2SPR,FLOWER2SPR,stepthink,false,\r
+       false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower3};\r
+statetype s_flower3     = {FLOWER3SPR,FLOWER3SPR,stepthink,false,\r
+       false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower4};\r
+statetype s_flower4     = {FLOWER4SPR,FLOWER4SPR,stepthink,false,\r
+       false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower5};\r
+statetype s_flower5     = {FLOWER3SPR,FLOWER3SPR,stepthink,false,\r
+       false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower6};\r
+statetype s_flower6     = {FLOWER2SPR,FLOWER2SPR,stepthink,false,\r
+       false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower1};\r
+\r
+statetype s_poofto1             = {POOF1SPR,POOF1SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto2};\r
+statetype s_poofto2             = {POOF2SPR,POOF2SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto3};\r
+statetype s_poofto3             = {POOF3SPR,POOF3SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto4};\r
+statetype s_poofto4             = {POOF4SPR,POOF4SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, NULL};\r
+\r
+statetype s_pooffrom1           = {POOF4SPR,POOF4SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom2};\r
+statetype s_pooffrom2           = {POOF3SPR,POOF3SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom3};\r
+statetype s_pooffrom3           = {POOF2SPR,POOF2SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom4};\r
+statetype s_pooffrom4           = {POOF1SPR,POOF1SPR,step,false,\r
+       false,20, 0,0, ChangeFromFlower, NULL, DrawReact2, &s_pooffrom5};\r
+statetype s_pooffrom5           = {POOF2SPR,POOF2SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom6};\r
+statetype s_pooffrom6           = {POOF3SPR,POOF3SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom7};\r
+statetype s_pooffrom7           = {POOF4SPR,POOF4SPR,step,false,\r
+       false,10, 0,0, NULL, NULL, DrawReact2, NULL};\r
+\r
+\r
+#pragma warn +sus\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= ChangeToFlower\r
+=\r
+======================\r
+*/\r
+\r
+void ChangeToFlower (objtype *ob)\r
+{\r
+       SD_PlaySound (FLOWERPOWERSND);\r
+       ob->y = ob->bottom-TILEGLOBAL*2;\r
+       ob->temp1 = (int)ob->obclass;\r
+       ob->temp2 = (int)ob->state;\r
+       ob->temp3 = 0;\r
+       ob->needtoclip = true;\r
+       ob->obclass = inertobj;\r
+       ob->xspeed = 0;\r
+       ChangeState (ob,&s_flower1);\r
+       ob->active = allways;                   // flower never deactivated\r
+       GetNewObj (true);\r
+       new->x = ob->x;\r
+       new->y = ob->y;\r
+       NewState (new,&s_poofto1);\r
+       new->active = removable;\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= FlowerThink\r
+=\r
+======================\r
+*/\r
+\r
+void FlowerThink (objtype *ob)\r
+{\r
+       ProjectileThink (ob);\r
+       if ( (ob->temp3+=tics) >= flowertime[gamestate.difficulty])\r
+       {\r
+               GetNewObj (true);\r
+               new->active = allways;\r
+               new->temp1 = (int)ob;\r
+               new->x = ob->x;\r
+               new->y = ob->y;\r
+               NewState (new,&s_pooffrom1);\r
+               ob->temp3 = 0;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= ChangeFromFlower\r
+=\r
+======================\r
+*/\r
+\r
+void ChangeFromFlower (objtype *ob)\r
+{\r
+       objtype *flower;\r
+       statetype *state;\r
+       unsigned        oldbottom;\r
+\r
+       SD_PlaySound (UNFLOWERPOWERSND);\r
+       flower = (objtype *)ob->temp1;\r
+\r
+       oldbottom = flower->bottom;\r
+       ChangeState (flower,(statetype *)flower->temp2);\r
+       flower->y += oldbottom - flower->bottom;\r
+\r
+       flower->obclass = flower->temp1;\r
+       flower->active = yes;                   // allow it to unspawn now if off screen\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       BONUS\r
+\r
+temp1 = bonus type\r
+temp2 = base shape number\r
+temp3 = last animated shape number +1\r
+\r
+=============================================================================\r
+*/\r
+\r
+void BonusThink (objtype *ob);\r
+\r
+extern statetype s_bonus1;\r
+\r
+#pragma warn -sus\r
+\r
+statetype s_bonus       = {NULL,NULL,step,false,\r
+       false,20, 0,0, BonusThink, NULL, DrawReact2, &s_bonus};\r
+\r
+statetype s_bonusrise           = {NULL,NULL,slide,false,\r
+       false,40, 0,8, NULL, NULL, DrawReact3, NULL};\r
+\r
+#pragma warn +sus\r
+\r
+/*\r
+====================\r
+=\r
+= SpawnBonus\r
+=\r
+====================\r
+*/\r
+\r
+int bonusshape[12] = {PEPPERMINT1SPR,COOKIE1SPR,CANDYCANE1SPR,CANDYBAR1SPR,\r
+       LOLLIPOP1SPR,COTTONCANDY1SPR,EXTRAKEEN1SPR,SUPERBONUS1SPR,FLOWERPOWER1SPR,\r
+       FLOWERPOWERUP1SPR,BOOBUSBOMB1SPR,MAGICKEY1SPR};\r
+\r
+void SpawnBonus (int tilex, int tiley, int type)\r
+{\r
+       GetNewObj (false);\r
+\r
+       new->needtoclip = false;\r
+       new->obclass = bonusobj;\r
+       new->x = tilex<<G_T_SHIFT;\r
+       new->y = tiley<<G_T_SHIFT;\r
+\r
+       if (type == 9)\r
+               new->y -= 8*PIXGLOBAL;  // flower power up one block\r
+\r
+       new->ydir = -1;                 // bonus stuff flies up when touched\r
+\r
+       new->temp1 = type;\r
+       new->temp2 = new->shapenum = bonusshape[type];\r
+       if (type != 7)\r
+               new->temp3 = new->temp2 + 2;\r
+       else\r
+               new->temp3 = new->temp2 + 4;    // super bonus is 4 stage animation\r
+\r
+       NewState (new,&s_bonus);\r
+}\r
+\r
+/*\r
+====================\r
+=\r
+= BonusThink\r
+=\r
+====================\r
+*/\r
+\r
+void BonusThink (objtype *ob)\r
+{\r
+       if (++ob->shapenum == ob->temp3)\r
+               ob->shapenum = ob->temp2;\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                               BROCCOLASH\r
+\r
+=============================================================================\r
+*/\r
+\r
+void BroccoThink (objtype *ob);\r
+void BroccoGetUp (objtype *ob);\r
+\r
+extern statetype s_broccowalk1;\r
+extern statetype s_broccowalk2;\r
+extern statetype s_broccowalk3;\r
+extern statetype s_broccowalk4;\r
+\r
+extern statetype s_broccosmash1;\r
+extern statetype s_broccosmash2;\r
+extern statetype s_broccosmash3;\r
+extern statetype s_broccosmash4;\r
+extern statetype s_broccosmash5;\r
+extern statetype s_broccosmash6;\r
+extern statetype s_broccosmash7;\r
+extern statetype s_broccosmash8;\r
+extern statetype s_broccosmash9;\r
+\r
+#pragma warn -sus\r
+\r
+statetype s_broccowalk1         = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,false,\r
+       true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk2};\r
+statetype s_broccowalk2         = {BROCCOLASHRUNL2SPR,BROCCOLASHRUNR2SPR,step,false,\r
+       true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk3};\r
+statetype s_broccowalk3         = {BROCCOLASHRUNL3SPR,BROCCOLASHRUNR3SPR,step,false,\r
+       true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk4};\r
+statetype s_broccowalk4         = {BROCCOLASHRUNL4SPR,BROCCOLASHRUNR4SPR,step,false,\r
+       true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk1};\r
+\r
+statetype s_broccosmash1 = {BROCCOLASHSMASHL1SPR,BROCCOLASHSMASHR1SPR,step,true,\r
+       false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash2};\r
+statetype s_broccosmash2 = {BROCCOLASHSMASHL2SPR,BROCCOLASHSMASHR2SPR,step,true,\r
+       false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash3};\r
+statetype s_broccosmash3 = {BROCCOLASHSMASHL3SPR,BROCCOLASHSMASHR3SPR,step,true,\r
+       false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash4};\r
+statetype s_broccosmash4 = {BROCCOLASHSMASHL4SPR,BROCCOLASHSMASHR4SPR,step,false,\r
+       false,7, 0,0, NULL, NULL, DrawReact, &s_broccosmash5};\r
+statetype s_broccosmash5 = {BROCCOLASHSMASHL3SPR,BROCCOLASHSMASHR3SPR,step,true,\r
+       false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash6};\r
+statetype s_broccosmash6 = {BROCCOLASHSMASHL2SPR,BROCCOLASHSMASHR2SPR,step,true,\r
+       false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash7};\r
+statetype s_broccosmash7 = {BROCCOLASHSMASHL1SPR,BROCCOLASHSMASHR1SPR,step,true,\r
+       false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash8};\r
+statetype s_broccosmash8 = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,true,\r
+       false,6, 0,0, BroccoGetUp, NULL, DrawReact, &s_broccosmash9};\r
+statetype s_broccosmash9 = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,true,\r
+       false,6, 128,0, NULL, NULL, WalkReact, &s_broccowalk1};\r
+\r
+#pragma warn +sus\r
+\r
+/*\r
+====================\r
+=\r
+= SpawnBrocco\r
+=\r
+====================\r
+*/\r
+\r
+void SpawnBrocco (int tilex, int tiley)\r
+{\r
+       GetNewObj (false);\r
+\r
+       new->obclass = broccoobj;\r
+       new->x = tilex<<G_T_SHIFT;\r
+       new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;\r
+       new->xdir = 1;\r
+       NewState (new,&s_broccowalk1);\r
+}\r
+\r
+/*\r
+====================\r
+=\r
+= BroccoGetUp\r
+=\r
+====================\r
+*/\r
+\r
+void BroccoGetUp (objtype *ob)\r
+{\r
+       ob->needtoclip = true;\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= BroccoThink\r
+=\r
+====================\r
+*/\r
+\r
+void BroccoThink (objtype *ob)\r
+{\r
+       int delta;\r
+\r
+       if (ob->top > player->bottom || ob->bottom < player->top)\r
+               return;\r
+\r
+       delta = player->x - ob->x;\r
+\r
+       if ( ob->xdir == -1 )\r
+       {\r
+               if (delta < -3*TILEGLOBAL)\r
+                       return;\r
+               if (delta > TILEGLOBAL/2)\r
+               {\r
+                       ob->xdir = 1;\r
+                       return;\r
+               }\r
+               ob->state = &s_broccosmash1;\r
+               ob->needtoclip = false;\r
+               ob->xmove = 0;\r
+               return;\r
+       }\r
+       else\r
+       {\r
+               delta = player->left - ob->right;\r
+               if (delta > 3*TILEGLOBAL)\r
+                       return;\r
+               if (delta < -TILEGLOBAL/2)\r
+               {\r
+                       ob->xdir = -1;\r
+                       return;\r
+               }\r
+               ob->state = &s_broccosmash1;\r
+               ob->needtoclip = false;\r
+               ob->xmove = 0;\r
+               return;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                TOMATOOTH\r
+\r
+ob->temp1 = jumptime\r
+\r
+=============================================================================\r
+*/\r
+\r
+#define        SPDTOMATBOUNCE  30\r
+#define TICTOMATJUMP   10\r
+#define SPDTOMAT               16\r
+\r
+void TomatBounceThink (objtype *ob);\r
+void TomatReact (objtype *ob);\r
+\r
+extern statetype s_tomatbounce;\r
+extern statetype s_tomatbounce2;\r
+\r
+#pragma warn -sus\r
+\r
+statetype s_tomatbounce         = {TOMATOOTHL1SPR,TOMATOOTHR1SPR,stepthink,false,\r
+       false,20, 0,0, TomatBounceThink, NULL, TomatReact, &s_tomatbounce2};\r
+statetype s_tomatbounce2 = {TOMATOOTHL2SPR,TOMATOOTHR2SPR,stepthink,false,\r
+       false,20, 0,0, TomatBounceThink, NULL, TomatReact, &s_tomatbounce};\r
+\r
+#pragma warn +sus\r
+\r
+/*\r
+====================\r
+=\r
+= SpawnTomat\r
+=\r
+====================\r
+*/\r
+\r
+void SpawnTomat (int tilex, int tiley)\r
+{\r
+       GetNewObj (false);\r
+\r
+       new->obclass = tomatobj;\r
+       new->x = tilex<<G_T_SHIFT;\r
+       new->y = (tiley<<G_T_SHIFT)-1*BLOCKSIZE;\r
+       new->xdir = 1;\r
+       NewState (new,&s_tomatbounce);\r
+}\r
+\r
+/*\r
+====================\r
+=\r
+= TomatBounceThink\r
+=\r
+====================\r
+*/\r
+\r
+void TomatBounceThink (objtype *ob)\r
+{\r
+       AccelerateX (ob,ob->x > player->x ? -1 : 1,SPDTOMAT);\r
+       if (ob->xspeed > 0)\r
+               ob->xdir = 1;\r
+       else\r
+               ob->xdir = -1;\r
+\r
+       if (ob->temp1)\r
+       {\r
+               if (ob->temp1<tics)\r
+               {\r
+                       ob->ymove = ob->yspeed*ob->temp1;\r
+                       ob->temp1 = 0;\r
+               }\r
+               else\r
+               {\r
+                       ob->ymove = ob->yspeed*tics;\r
+                       ob->temp1-=tics;\r
+               }\r
+       }\r
+       else\r
+               DoGravity(ob);\r
+\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= TomatReactThink\r
+=\r
+====================\r
+*/\r
+\r
+void TomatReact (objtype *ob)\r
+{\r
+       if (ob->hiteast || ob->hitwest)\r
+       {\r
+               ob->xdir = -ob->xdir;\r
+               ob->xspeed = -ob->xspeed;\r
+       }\r
+\r
+       if (ob->hitsouth)\r
+       {\r
+               if (ob->tileright >= originxtile\r
+               && ob->tileleft <= originxtilemax\r
+               && ob->tiletop >= originytile\r
+               && ob->tilebottom <= originytilemax)\r
+                       SD_PlaySound (BOUNCESND);\r
+               ob->yspeed = -ob->yspeed;\r
+       }\r
+\r
+       if (ob->hitnorth)\r
+       {\r
+               if (ob->tileright >= originxtile\r
+               && ob->tileleft <= originxtilemax\r
+               && ob->tiletop >= originytile\r
+               && ob->tilebottom <= originytilemax)\r
+                       SD_PlaySound (BOUNCESND);\r
+               ob->yspeed = -SPDTOMATBOUNCE-(US_RndT()>>4);\r
+               ob->temp1 = TICTOMATJUMP;\r
+       }\r
+\r
+       PLACESPRITE;\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                CARROT COURIER\r
+\r
+=============================================================================\r
+*/\r
+\r
+#define        SPDCARROTLEAPX  32\r
+#define SPDCARROTLEAPY  40\r
+\r
+void CarrotThink (objtype *ob);\r
+void CarrotReact (objtype *ob);\r
+void CarrotAirReact (objtype *ob);\r
+\r
+extern statetype s_carrotwalk1;\r
+extern statetype s_carrotwalk2;\r
+extern statetype s_carrotwalk3;\r
+extern statetype s_carrotwalk4;\r
+\r
+extern statetype s_carrotleap;\r
+\r
+#pragma warn -sus\r
+\r
+statetype s_carrotwalk1         = {CARROTRUNL1SPR,CARROTRUNR1SPR,step,false,\r
+       true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk2};\r
+statetype s_carrotwalk2         = {CARROTRUNL2SPR,CARROTRUNR2SPR,step,false,\r
+       true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk3};\r
+statetype s_carrotwalk3         = {CARROTRUNL3SPR,CARROTRUNR3SPR,step,false,\r
+       true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk4};\r
+statetype s_carrotwalk4         = {CARROTRUNL4SPR,CARROTRUNR4SPR,step,false,\r
+       true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk1};\r
+\r
+statetype s_carrotleap  = {CARROTLEAPL1SPR,CARROTLEAPR1SPR,think,false,\r
+       false,0, 0,0, ProjectileThink, NULL, CarrotAirReact, NULL};\r
+\r
+#pragma warn +sus\r
+\r
+/*\r
+====================\r
+=\r
+= SpawnCarrot\r
+=\r
+====================\r
+*/\r
+\r
+void SpawnCarrot (int tilex, int tiley)\r
+{\r
+       GetNewObj (false);\r
+\r
+       new->obclass = carrotobj;\r
+       new->x = tilex<<G_T_SHIFT;\r
+       new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;\r
+       new->xdir = 1;\r
+       new->ydir = 1;\r
+       NewState (new,&s_carrotwalk1);\r
+       new->hitnorth = 1;\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= CarrotReact\r
+=\r
+====================\r
+*/\r
+\r
+void CarrotReact (objtype *ob)\r
+{\r
+       unsigned x, width, bot, far *map;\r
+\r
+       if (ob->xdir == 1 && ob->hitwest)\r
+       {\r
+               ob->xdir = -1;\r
+       }\r
+       else if (ob->xdir == -1 && ob->hiteast)\r
+       {\r
+               ob->xdir = 1;\r
+       }\r
+       else if (!ob->hitnorth)\r
+       {\r
+               ob->x -= ob->xmove;\r
+               ob->y -= ob->ymove;\r
+\r
+               ob->yspeed = -SPDCARROTLEAPY;\r
+               ob->xspeed = SPDCARROTLEAPX*ob->xdir;\r
+               ChangeState (ob,&s_carrotleap);\r
+       }\r
+\r
+       PLACESPRITE;\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= CarrotAirReact\r
+=\r
+====================\r
+*/\r
+\r
+void CarrotAirReact (objtype *ob)\r
+{\r
+       if (ob->hitsouth)\r
+               ob->yspeed = 0;\r
+\r
+       if (ob->hitnorth)\r
+               ChangeState (ob,&s_carrotwalk1);\r
+\r
+       PLACESPRITE;\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  ASPARAGUSTO\r
+\r
+=============================================================================\r
+*/\r
+\r
+void AsparThink (objtype *ob);\r
+\r
+extern statetype s_asparwalk1;\r
+extern statetype s_asparwalk2;\r
+extern statetype s_asparwalk3;\r
+extern statetype s_asparwalk4;\r
+\r
+#pragma warn -sus\r
+\r
+statetype s_asparwalk1  = {ASPARAGUSRUNL1SPR,ASPARAGUSRUNR1SPR,step,true,\r
+       true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk2};\r
+statetype s_asparwalk2  = {ASPARAGUSRUNL2SPR,ASPARAGUSRUNR2SPR,step,false,\r
+       true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk3};\r
+statetype s_asparwalk3  = {ASPARAGUSRUNL3SPR,ASPARAGUSRUNR3SPR,step,true,\r
+       true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk4};\r
+statetype s_asparwalk4  = {ASPARAGUSRUNL4SPR,ASPARAGUSRUNR4SPR,step,false,\r
+       true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk1};\r
+\r
+#pragma warn +sus\r
+\r
+/*\r
+====================\r
+=\r
+= SpawnAspar\r
+=\r
+====================\r
+*/\r
+\r
+void SpawnAspar (int tilex, int tiley)\r
+{\r
+       GetNewObj (false);\r
+\r
+       new->obclass = asparobj;\r
+       new->x = tilex<<G_T_SHIFT;\r
+       new->y = tiley<<G_T_SHIFT;\r
+       new->xdir = 1;\r
+       NewState (new,&s_asparwalk1);\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  SOUR GRAPE\r
+\r
+=============================================================================\r
+*/\r
+\r
+void GrapeThink (objtype *ob);\r
+void GrapeRiseReact (objtype *ob);\r
+void GrapeFallReact (objtype *ob);\r
+\r
+extern statetype s_grapewait;\r
+extern statetype s_grapefall;\r
+extern statetype s_grapesit;\r
+extern statetype s_graperise;\r
+\r
+#pragma warn -sus\r
+\r
+statetype s_grapewait  = {GRAPEONVINESPR,GRAPEONVINESPR,think,false,\r
+       false,0, 0,0, GrapeThink, NULL, DrawReact, NULL};\r
+\r
+statetype s_grapefall  = {GRAPEFALLINGSPR,GRAPEFALLINGSPR,think,false,\r
+       false,0, 0,0, ProjectileThink, NULL, GrapeFallReact, NULL};\r
+\r
+statetype s_grapesit   = {GRAPEONVINESPR,GRAPEONVINESPR,step,false,\r
+       false,30, 0,0, NULL, NULL, DrawReact, &s_graperise};\r
+statetype s_graperise  = {GRAPEONVINESPR,GRAPEONVINESPR,slide,false,\r
+       false,0, 0,-16, NULL, NULL, GrapeRiseReact, NULL};\r
+\r
+#pragma warn +sus\r
+\r
+/*\r
+====================\r
+=\r
+= SpawnGrape\r
+=\r
+====================\r
+*/\r
+\r
+void SpawnGrape (int tilex, int tiley)\r
+{\r
+       GetNewObj (false);\r
+\r
+       new->obclass = grapeobj;\r
+       new->x = tilex<<G_T_SHIFT;\r
+       new->y = tiley<<G_T_SHIFT;\r
+       new->xdir = 1;\r
+       new->ydir = 1;\r
+       NewState (new,&s_grapewait);\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= GrapeThink\r
+=\r
+====================\r
+*/\r
+\r
+void GrapeThink (objtype *ob)\r
+{\r
+       unsigned y,starty,endy, far *map;\r
+\r
+       if (player->left > ob->right\r
+               || player->right < ob->left\r
+               || player->y < ob->y )\r
+               return;\r
+\r
+//\r
+// see if there are any walls between grape and player\r
+//\r
+       starty = ob->tilebottom;\r
+       endy = player->tiletop;\r
+\r
+       map = mapsegs[1] + mapbwidthtable[starty]/2 + ob->tilemidx;\r
+       for (y = starty ; y<endy ; y++,map+=mapwidth)\r
+               if (tinf[NORTHWALL+*map])\r
+                       return;\r
+\r
+       ob->state = &s_grapefall;\r
+       SD_PlaySound (GRAPESCREAMSND);\r
+\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= GrapeRiseReact\r
+=\r
+====================\r
+*/\r
+\r
+void GrapeRiseReact (objtype *ob)\r
+{\r
+       if (ob->hitsouth)\r
+               ChangeState(ob,&s_grapewait);\r
+       PLACESPRITE;\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= GrapeFallReact\r
+=\r
+====================\r
+*/\r
+\r
+void GrapeFallReact (objtype *ob)\r
+{\r
+       if (ob->hitnorth)\r
+       {\r
+               SD_PlaySound (BOUNCESND);\r
+               ob->yspeed = -(ob->yspeed<<1)/3;\r
+               if (ob->yspeed > -32)\r
+                       ChangeState(ob,&s_grapesit);\r
+       }\r
+       PLACESPRITE;\r
+}\r
+\r