1 /* Keen Dreams Source Code
\r
2 * Copyright (C) 2014 Javier M. Chavez
\r
4 * This program is free software; you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation; either version 2 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License along
\r
15 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
25 =============================================================================
\r
29 =============================================================================
\r
33 #define PLACESPRITE RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum, \
\r
37 =============================================================================
\r
41 =============================================================================
\r
46 =============================================================================
\r
50 =============================================================================
\r
53 int flowertime[4] = {700,700,350,175};
\r
56 =============================================================================
\r
60 =============================================================================
\r
68 = Changes speed and location
\r
74 void DoGravity (objtype *ob)
\r
78 // only accelerate on odd tics, because of limited precision
\r
80 for (i=lasttimecount-tics;i<lasttimecount;i++)
\r
84 if (ob->yspeed < 0 && ob->yspeed >= -ACCGRAVITY)
\r
86 // stop at apex of jump
\r
87 ob->ymove += ob->yspeed;
\r
91 ob->yspeed+=ACCGRAVITY;
\r
92 if (ob->yspeed>SPDMAXY)
\r
95 ob->ymove+=ob->yspeed;
\r
108 void AccelerateX (objtype *ob,int dir,int max)
\r
113 olddir = ob->xspeed & 0x8000;
\r
115 // only accelerate on odd tics, because of limited precision
\r
117 for (i=lasttimecount-tics;i<lasttimecount;i++)
\r
122 if ( (ob->xspeed & 0x8000) != olddir)
\r
124 olddir = ob->xspeed & 0x8000;
\r
125 ob->xdir = olddir ? -1 : 1;
\r
127 if (ob->xspeed>max)
\r
129 else if (ob->xspeed<-max)
\r
132 ob->xmove+=ob->xspeed;
\r
145 void FrictionX (objtype *ob)
\r
151 olddir = ob->xspeed & 0x8000;
\r
153 if (ob->xspeed > 0)
\r
155 else if (ob->xspeed < 0)
\r
160 // only accelerate on odd tics, because of limited precision
\r
162 for (i=lasttimecount-tics;i<lasttimecount;i++)
\r
167 if ( (ob->xspeed & 0x8000) != olddir)
\r
170 ob->xmove+=ob->xspeed;
\r
183 void ProjectileThink (objtype *ob)
\r
186 ob->xmove = tics*ob->xspeed;
\r
197 void VelocityThink (objtype *ob)
\r
199 ob->xmove = tics*ob->xspeed;
\r
200 ob->ymove = tics*ob->yspeed;
\r
211 void DrawReact (objtype *ob)
\r
213 RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,1);
\r
216 void DrawReact2 (objtype *ob)
\r
218 RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,2);
\r
221 void DrawReact3 (objtype *ob)
\r
223 RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,3);
\r
234 void ChangeState (objtype *ob, statetype *state)
\r
238 if (state->rightshapenum)
\r
241 ob->shapenum = state->rightshapenum;
\r
243 ob->shapenum = state->leftshapenum;
\r
249 ob->needtoreact = true; // it will need to be redrawn this frame
\r
255 ====================
\r
259 ====================
\r
262 void WalkReact (objtype *ob)
\r
264 if (ob->xdir == 1 && ob->hitwest)
\r
266 ob->x -= ob->xmove;
\r
268 ob->nothink = US_RndT()>>5;
\r
269 ChangeState (ob,ob->state);
\r
271 else if (ob->xdir == -1 && ob->hiteast)
\r
273 ob->x -= ob->xmove;
\r
275 ob->nothink = US_RndT()>>5;
\r
276 ChangeState (ob,ob->state);
\r
278 else if (!ob->hitnorth)
\r
280 ob->x -= 2*ob->xmove;
\r
281 ob->y -= ob->ymove;
\r
283 ob->xdir = -ob->xdir;
\r
284 ob->nothink = US_RndT()>>5;
\r
285 ChangeState (ob,ob->state);
\r
293 =============================================================================
\r
297 =============================================================================
\r
300 void DoorContact (objtype *ob, objtype *hit);
\r
302 extern statetype s_door;
\r
303 extern statetype s_doorraise;
\r
305 statetype s_door = {DOORSPR,DOORSPR,think,false,
\r
306 false,0, 0,0, NULL, DoorContact, DrawReact, &s_door};
\r
307 statetype s_doorraise = {DOORSPR,DOORSPR,slide,false,
\r
308 false,24, 0,32, NULL, DoorContact, DrawReact, NULL};
\r
311 ======================
\r
315 ======================
\r
318 void SpawnDoor (int tilex, int tiley)
\r
322 new->obclass = doorobj;
\r
323 new->x = tilex<<G_T_SHIFT;
\r
324 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;
\r
327 new->needtoclip = false;
\r
328 NewState (new,&s_door);
\r
332 ======================
\r
336 ======================
\r
339 void DoorContact (objtype *ob, objtype *hit)
\r
341 ClipToSpriteSide (hit,ob);
\r
345 =============================================================================
\r
349 temp1 = original class
\r
350 temp2 = original state
\r
351 temp3 = flower count
\r
353 =============================================================================
\r
356 void ChangeToFlower (objtype *ob);
\r
357 void FlowerThink (objtype *ob);
\r
358 void ChangeFromFlower (objtype *ob);
\r
360 extern statetype s_flower1;
\r
361 extern statetype s_flower2;
\r
362 extern statetype s_flower3;
\r
363 extern statetype s_flower4;
\r
364 extern statetype s_flower5;
\r
365 extern statetype s_flower6;
\r
367 extern statetype s_poofto1;
\r
368 extern statetype s_poofto2;
\r
369 extern statetype s_poofto3;
\r
370 extern statetype s_poofto4;
\r
372 extern statetype s_pooffrom1;
\r
373 extern statetype s_pooffrom2;
\r
374 extern statetype s_pooffrom3;
\r
375 extern statetype s_pooffrom4;
\r
376 extern statetype s_pooffrom5;
\r
377 extern statetype s_pooffrom6;
\r
378 extern statetype s_pooffrom7;
\r
380 extern statetype s_bonus1;
\r
384 statetype s_flower1 = {FLOWER1SPR,FLOWER1SPR,stepthink,false,
\r
385 false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower2};
\r
386 statetype s_flower2 = {FLOWER2SPR,FLOWER2SPR,stepthink,false,
\r
387 false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower3};
\r
388 statetype s_flower3 = {FLOWER3SPR,FLOWER3SPR,stepthink,false,
\r
389 false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower4};
\r
390 statetype s_flower4 = {FLOWER4SPR,FLOWER4SPR,stepthink,false,
\r
391 false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower5};
\r
392 statetype s_flower5 = {FLOWER3SPR,FLOWER3SPR,stepthink,false,
\r
393 false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower6};
\r
394 statetype s_flower6 = {FLOWER2SPR,FLOWER2SPR,stepthink,false,
\r
395 false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower1};
\r
397 statetype s_poofto1 = {POOF1SPR,POOF1SPR,step,false,
\r
398 false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto2};
\r
399 statetype s_poofto2 = {POOF2SPR,POOF2SPR,step,false,
\r
400 false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto3};
\r
401 statetype s_poofto3 = {POOF3SPR,POOF3SPR,step,false,
\r
402 false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto4};
\r
403 statetype s_poofto4 = {POOF4SPR,POOF4SPR,step,false,
\r
404 false,10, 0,0, NULL, NULL, DrawReact2, NULL};
\r
406 statetype s_pooffrom1 = {POOF4SPR,POOF4SPR,step,false,
\r
407 false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom2};
\r
408 statetype s_pooffrom2 = {POOF3SPR,POOF3SPR,step,false,
\r
409 false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom3};
\r
410 statetype s_pooffrom3 = {POOF2SPR,POOF2SPR,step,false,
\r
411 false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom4};
\r
412 statetype s_pooffrom4 = {POOF1SPR,POOF1SPR,step,false,
\r
413 false,20, 0,0, ChangeFromFlower, NULL, DrawReact2, &s_pooffrom5};
\r
414 statetype s_pooffrom5 = {POOF2SPR,POOF2SPR,step,false,
\r
415 false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom6};
\r
416 statetype s_pooffrom6 = {POOF3SPR,POOF3SPR,step,false,
\r
417 false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom7};
\r
418 statetype s_pooffrom7 = {POOF4SPR,POOF4SPR,step,false,
\r
419 false,10, 0,0, NULL, NULL, DrawReact2, NULL};
\r
426 ======================
\r
430 ======================
\r
433 void ChangeToFlower (objtype *ob)
\r
435 SD_PlaySound (FLOWERPOWERSND);
\r
436 ob->y = ob->bottom-TILEGLOBAL*2;
\r
437 ob->temp1 = (int)ob->obclass;
\r
438 ob->temp2 = (int)ob->state;
\r
440 ob->needtoclip = true;
\r
441 ob->obclass = inertobj;
\r
443 ChangeState (ob,&s_flower1);
\r
444 ob->active = allways; // flower never deactivated
\r
448 NewState (new,&s_poofto1);
\r
449 new->active = removable;
\r
454 ======================
\r
458 ======================
\r
461 void FlowerThink (objtype *ob)
\r
463 ProjectileThink (ob);
\r
464 if ( (ob->temp3+=tics) >= flowertime[gamestate.difficulty])
\r
467 new->active = allways;
\r
468 new->temp1 = (int)ob;
\r
471 NewState (new,&s_pooffrom1);
\r
478 ======================
\r
482 ======================
\r
485 void ChangeFromFlower (objtype *ob)
\r
489 unsigned oldbottom;
\r
491 SD_PlaySound (UNFLOWERPOWERSND);
\r
492 flower = (objtype *)ob->temp1;
\r
494 oldbottom = flower->bottom;
\r
495 ChangeState (flower,(statetype *)flower->temp2);
\r
496 flower->y += oldbottom - flower->bottom;
\r
498 flower->obclass = flower->temp1;
\r
499 flower->active = yes; // allow it to unspawn now if off screen
\r
504 =============================================================================
\r
509 temp2 = base shape number
\r
510 temp3 = last animated shape number +1
\r
512 =============================================================================
\r
515 void BonusThink (objtype *ob);
\r
517 extern statetype s_bonus1;
\r
521 statetype s_bonus = {NULL,NULL,step,false,
\r
522 false,20, 0,0, BonusThink, NULL, DrawReact2, &s_bonus};
\r
524 statetype s_bonusrise = {NULL,NULL,slide,false,
\r
525 false,40, 0,8, NULL, NULL, DrawReact3, NULL};
\r
530 ====================
\r
534 ====================
\r
537 int bonusshape[12] = {PEPPERMINT1SPR,COOKIE1SPR,CANDYCANE1SPR,CANDYBAR1SPR,
\r
538 LOLLIPOP1SPR,COTTONCANDY1SPR,EXTRAKEEN1SPR,SUPERBONUS1SPR,FLOWERPOWER1SPR,
\r
539 FLOWERPOWERUP1SPR,BOOBUSBOMB1SPR,MAGICKEY1SPR};
\r
541 void SpawnBonus (int tilex, int tiley, int type)
\r
545 new->needtoclip = false;
\r
546 new->obclass = bonusobj;
\r
547 new->x = tilex<<G_T_SHIFT;
\r
548 new->y = tiley<<G_T_SHIFT;
\r
551 new->y -= 8*PIXGLOBAL; // flower power up one block
\r
553 new->ydir = -1; // bonus stuff flies up when touched
\r
556 new->temp2 = new->shapenum = bonusshape[type];
\r
558 new->temp3 = new->temp2 + 2;
\r
560 new->temp3 = new->temp2 + 4; // super bonus is 4 stage animation
\r
562 NewState (new,&s_bonus);
\r
566 ====================
\r
570 ====================
\r
573 void BonusThink (objtype *ob)
\r
575 if (++ob->shapenum == ob->temp3)
\r
576 ob->shapenum = ob->temp2;
\r
582 =============================================================================
\r
586 =============================================================================
\r
589 void BroccoThink (objtype *ob);
\r
590 void BroccoGetUp (objtype *ob);
\r
592 extern statetype s_broccowalk1;
\r
593 extern statetype s_broccowalk2;
\r
594 extern statetype s_broccowalk3;
\r
595 extern statetype s_broccowalk4;
\r
597 extern statetype s_broccosmash1;
\r
598 extern statetype s_broccosmash2;
\r
599 extern statetype s_broccosmash3;
\r
600 extern statetype s_broccosmash4;
\r
601 extern statetype s_broccosmash5;
\r
602 extern statetype s_broccosmash6;
\r
603 extern statetype s_broccosmash7;
\r
604 extern statetype s_broccosmash8;
\r
605 extern statetype s_broccosmash9;
\r
609 statetype s_broccowalk1 = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,false,
\r
610 true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk2};
\r
611 statetype s_broccowalk2 = {BROCCOLASHRUNL2SPR,BROCCOLASHRUNR2SPR,step,false,
\r
612 true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk3};
\r
613 statetype s_broccowalk3 = {BROCCOLASHRUNL3SPR,BROCCOLASHRUNR3SPR,step,false,
\r
614 true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk4};
\r
615 statetype s_broccowalk4 = {BROCCOLASHRUNL4SPR,BROCCOLASHRUNR4SPR,step,false,
\r
616 true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk1};
\r
618 statetype s_broccosmash1 = {BROCCOLASHSMASHL1SPR,BROCCOLASHSMASHR1SPR,step,true,
\r
619 false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash2};
\r
620 statetype s_broccosmash2 = {BROCCOLASHSMASHL2SPR,BROCCOLASHSMASHR2SPR,step,true,
\r
621 false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash3};
\r
622 statetype s_broccosmash3 = {BROCCOLASHSMASHL3SPR,BROCCOLASHSMASHR3SPR,step,true,
\r
623 false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash4};
\r
624 statetype s_broccosmash4 = {BROCCOLASHSMASHL4SPR,BROCCOLASHSMASHR4SPR,step,false,
\r
625 false,7, 0,0, NULL, NULL, DrawReact, &s_broccosmash5};
\r
626 statetype s_broccosmash5 = {BROCCOLASHSMASHL3SPR,BROCCOLASHSMASHR3SPR,step,true,
\r
627 false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash6};
\r
628 statetype s_broccosmash6 = {BROCCOLASHSMASHL2SPR,BROCCOLASHSMASHR2SPR,step,true,
\r
629 false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash7};
\r
630 statetype s_broccosmash7 = {BROCCOLASHSMASHL1SPR,BROCCOLASHSMASHR1SPR,step,true,
\r
631 false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash8};
\r
632 statetype s_broccosmash8 = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,true,
\r
633 false,6, 0,0, BroccoGetUp, NULL, DrawReact, &s_broccosmash9};
\r
634 statetype s_broccosmash9 = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,true,
\r
635 false,6, 128,0, NULL, NULL, WalkReact, &s_broccowalk1};
\r
640 ====================
\r
644 ====================
\r
647 void SpawnBrocco (int tilex, int tiley)
\r
651 new->obclass = broccoobj;
\r
652 new->x = tilex<<G_T_SHIFT;
\r
653 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;
\r
655 NewState (new,&s_broccowalk1);
\r
659 ====================
\r
663 ====================
\r
666 void BroccoGetUp (objtype *ob)
\r
668 ob->needtoclip = true;
\r
673 ====================
\r
677 ====================
\r
680 void BroccoThink (objtype *ob)
\r
684 if (ob->top > player->bottom || ob->bottom < player->top)
\r
687 delta = player->x - ob->x;
\r
689 if ( ob->xdir == -1 )
\r
691 if (delta < -3*TILEGLOBAL)
\r
693 if (delta > TILEGLOBAL/2)
\r
698 ob->state = &s_broccosmash1;
\r
699 ob->needtoclip = false;
\r
705 delta = player->left - ob->right;
\r
706 if (delta > 3*TILEGLOBAL)
\r
708 if (delta < -TILEGLOBAL/2)
\r
713 ob->state = &s_broccosmash1;
\r
714 ob->needtoclip = false;
\r
722 =============================================================================
\r
726 ob->temp1 = jumptime
\r
728 =============================================================================
\r
731 #define SPDTOMATBOUNCE 30
\r
732 #define TICTOMATJUMP 10
\r
733 #define SPDTOMAT 16
\r
735 void TomatBounceThink (objtype *ob);
\r
736 void TomatReact (objtype *ob);
\r
738 extern statetype s_tomatbounce;
\r
739 extern statetype s_tomatbounce2;
\r
743 statetype s_tomatbounce = {TOMATOOTHL1SPR,TOMATOOTHR1SPR,stepthink,false,
\r
744 false,20, 0,0, TomatBounceThink, NULL, TomatReact, &s_tomatbounce2};
\r
745 statetype s_tomatbounce2 = {TOMATOOTHL2SPR,TOMATOOTHR2SPR,stepthink,false,
\r
746 false,20, 0,0, TomatBounceThink, NULL, TomatReact, &s_tomatbounce};
\r
751 ====================
\r
755 ====================
\r
758 void SpawnTomat (int tilex, int tiley)
\r
762 new->obclass = tomatobj;
\r
763 new->x = tilex<<G_T_SHIFT;
\r
764 new->y = (tiley<<G_T_SHIFT)-1*BLOCKSIZE;
\r
766 NewState (new,&s_tomatbounce);
\r
770 ====================
\r
774 ====================
\r
777 void TomatBounceThink (objtype *ob)
\r
779 AccelerateX (ob,ob->x > player->x ? -1 : 1,SPDTOMAT);
\r
780 if (ob->xspeed > 0)
\r
787 if (ob->temp1<tics)
\r
789 ob->ymove = ob->yspeed*ob->temp1;
\r
794 ob->ymove = ob->yspeed*tics;
\r
805 ====================
\r
809 ====================
\r
812 void TomatReact (objtype *ob)
\r
814 if (ob->hiteast || ob->hitwest)
\r
816 ob->xdir = -ob->xdir;
\r
817 ob->xspeed = -ob->xspeed;
\r
822 if (ob->tileright >= originxtile
\r
823 && ob->tileleft <= originxtilemax
\r
824 && ob->tiletop >= originytile
\r
825 && ob->tilebottom <= originytilemax)
\r
826 SD_PlaySound (BOUNCESND);
\r
827 ob->yspeed = -ob->yspeed;
\r
832 if (ob->tileright >= originxtile
\r
833 && ob->tileleft <= originxtilemax
\r
834 && ob->tiletop >= originytile
\r
835 && ob->tilebottom <= originytilemax)
\r
836 SD_PlaySound (BOUNCESND);
\r
837 ob->yspeed = -SPDTOMATBOUNCE-(US_RndT()>>4);
\r
838 ob->temp1 = TICTOMATJUMP;
\r
846 =============================================================================
\r
850 =============================================================================
\r
853 #define SPDCARROTLEAPX 32
\r
854 #define SPDCARROTLEAPY 40
\r
856 void CarrotThink (objtype *ob);
\r
857 void CarrotReact (objtype *ob);
\r
858 void CarrotAirReact (objtype *ob);
\r
860 extern statetype s_carrotwalk1;
\r
861 extern statetype s_carrotwalk2;
\r
862 extern statetype s_carrotwalk3;
\r
863 extern statetype s_carrotwalk4;
\r
865 extern statetype s_carrotleap;
\r
869 statetype s_carrotwalk1 = {CARROTRUNL1SPR,CARROTRUNR1SPR,step,false,
\r
870 true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk2};
\r
871 statetype s_carrotwalk2 = {CARROTRUNL2SPR,CARROTRUNR2SPR,step,false,
\r
872 true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk3};
\r
873 statetype s_carrotwalk3 = {CARROTRUNL3SPR,CARROTRUNR3SPR,step,false,
\r
874 true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk4};
\r
875 statetype s_carrotwalk4 = {CARROTRUNL4SPR,CARROTRUNR4SPR,step,false,
\r
876 true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk1};
\r
878 statetype s_carrotleap = {CARROTLEAPL1SPR,CARROTLEAPR1SPR,think,false,
\r
879 false,0, 0,0, ProjectileThink, NULL, CarrotAirReact, NULL};
\r
884 ====================
\r
888 ====================
\r
891 void SpawnCarrot (int tilex, int tiley)
\r
895 new->obclass = carrotobj;
\r
896 new->x = tilex<<G_T_SHIFT;
\r
897 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;
\r
900 NewState (new,&s_carrotwalk1);
\r
906 ====================
\r
910 ====================
\r
913 void CarrotReact (objtype *ob)
\r
915 unsigned x, width, bot, far *map;
\r
917 if (ob->xdir == 1 && ob->hitwest)
\r
921 else if (ob->xdir == -1 && ob->hiteast)
\r
925 else if (!ob->hitnorth)
\r
927 ob->x -= ob->xmove;
\r
928 ob->y -= ob->ymove;
\r
930 ob->yspeed = -SPDCARROTLEAPY;
\r
931 ob->xspeed = SPDCARROTLEAPX*ob->xdir;
\r
932 ChangeState (ob,&s_carrotleap);
\r
940 ====================
\r
944 ====================
\r
947 void CarrotAirReact (objtype *ob)
\r
953 ChangeState (ob,&s_carrotwalk1);
\r
961 =============================================================================
\r
965 =============================================================================
\r
968 void AsparThink (objtype *ob);
\r
970 extern statetype s_asparwalk1;
\r
971 extern statetype s_asparwalk2;
\r
972 extern statetype s_asparwalk3;
\r
973 extern statetype s_asparwalk4;
\r
977 statetype s_asparwalk1 = {ASPARAGUSRUNL1SPR,ASPARAGUSRUNR1SPR,step,true,
\r
978 true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk2};
\r
979 statetype s_asparwalk2 = {ASPARAGUSRUNL2SPR,ASPARAGUSRUNR2SPR,step,false,
\r
980 true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk3};
\r
981 statetype s_asparwalk3 = {ASPARAGUSRUNL3SPR,ASPARAGUSRUNR3SPR,step,true,
\r
982 true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk4};
\r
983 statetype s_asparwalk4 = {ASPARAGUSRUNL4SPR,ASPARAGUSRUNR4SPR,step,false,
\r
984 true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk1};
\r
989 ====================
\r
993 ====================
\r
996 void SpawnAspar (int tilex, int tiley)
\r
1000 new->obclass = asparobj;
\r
1001 new->x = tilex<<G_T_SHIFT;
\r
1002 new->y = tiley<<G_T_SHIFT;
\r
1004 NewState (new,&s_asparwalk1);
\r
1009 =============================================================================
\r
1013 =============================================================================
\r
1016 void GrapeThink (objtype *ob);
\r
1017 void GrapeRiseReact (objtype *ob);
\r
1018 void GrapeFallReact (objtype *ob);
\r
1020 extern statetype s_grapewait;
\r
1021 extern statetype s_grapefall;
\r
1022 extern statetype s_grapesit;
\r
1023 extern statetype s_graperise;
\r
1027 statetype s_grapewait = {GRAPEONVINESPR,GRAPEONVINESPR,think,false,
\r
1028 false,0, 0,0, GrapeThink, NULL, DrawReact, NULL};
\r
1030 statetype s_grapefall = {GRAPEFALLINGSPR,GRAPEFALLINGSPR,think,false,
\r
1031 false,0, 0,0, ProjectileThink, NULL, GrapeFallReact, NULL};
\r
1033 statetype s_grapesit = {GRAPEONVINESPR,GRAPEONVINESPR,step,false,
\r
1034 false,30, 0,0, NULL, NULL, DrawReact, &s_graperise};
\r
1035 statetype s_graperise = {GRAPEONVINESPR,GRAPEONVINESPR,slide,false,
\r
1036 false,0, 0,-16, NULL, NULL, GrapeRiseReact, NULL};
\r
1041 ====================
\r
1045 ====================
\r
1048 void SpawnGrape (int tilex, int tiley)
\r
1050 GetNewObj (false);
\r
1052 new->obclass = grapeobj;
\r
1053 new->x = tilex<<G_T_SHIFT;
\r
1054 new->y = tiley<<G_T_SHIFT;
\r
1057 NewState (new,&s_grapewait);
\r
1062 ====================
\r
1066 ====================
\r
1069 void GrapeThink (objtype *ob)
\r
1071 unsigned y,starty,endy, far *map;
\r
1073 if (player->left > ob->right
\r
1074 || player->right < ob->left
\r
1075 || player->y < ob->y )
\r
1079 // see if there are any walls between grape and player
\r
1081 starty = ob->tilebottom;
\r
1082 endy = player->tiletop;
\r
1084 map = mapsegs[1] + mapbwidthtable[starty]/2 + ob->tilemidx;
\r
1085 for (y = starty ; y<endy ; y++,map+=mapwidth)
\r
1086 if (tinf[NORTHWALL+*map])
\r
1089 ob->state = &s_grapefall;
\r
1090 SD_PlaySound (GRAPESCREAMSND);
\r
1096 ====================
\r
1100 ====================
\r
1103 void GrapeRiseReact (objtype *ob)
\r
1106 ChangeState(ob,&s_grapewait);
\r
1112 ====================
\r
1116 ====================
\r
1119 void GrapeFallReact (objtype *ob)
\r
1123 SD_PlaySound (BOUNCESND);
\r
1124 ob->yspeed = -(ob->yspeed<<1)/3;
\r
1125 if (ob->yspeed > -32)
\r
1126 ChangeState(ob,&s_grapesit);
\r