--- /dev/null
+/* 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