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
26 player->temp1 = pausetime / pointer to zees when sleeping
\r
27 player->temp2 = pausecount / stagecount
\r
36 =============================================================================
\r
40 =============================================================================
\r
43 #define KEENPRIORITY 1
\r
45 #define PLACESPRITE RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum, \
\r
46 spritedraw,KEENPRIORITY);
\r
48 #define MINPOLEJUMPTICS 19 // wait tics before allowing a pole regram
\r
50 #define SPDRUNJUMP 16
\r
51 #define SPDPOLESIDEJUMP 8
\r
52 #define WALKAIRSPEED 8
\r
53 #define DIVESPEED 32
\r
55 #define POLEJUMPTIME 10
\r
57 #define SPDDIVEUP 16
\r
58 #define SPDPOLEJUMP 20
\r
60 #define SPDPOWERUP -64
\r
62 #define SPDPOWERY -20
\r
63 #define POWERCOUNT 50
\r
65 #define MAXXSPEED 24
\r
68 =============================================================================
\r
72 =============================================================================
\r
76 unsigned bounceangle[8][8] =
\r
80 {5,4,3,2,1,0,15,14},
\r
81 {5,4,3,2,1,0,15,14},
\r
82 {3,2,1,0,15,14,13,12},
\r
90 =============================================================================
\r
94 =============================================================================
\r
98 long leavepoletime; // TimeCount when jumped off pole
\r
101 =============================================================================
\r
105 =============================================================================
\r
108 void SpawnScore (void);
\r
109 void ScoreThink (objtype *ob);
\r
110 void ScoreReact (objtype *ob);
\r
112 void MemDrawChar (int char8,byte far *dest,unsigned width,unsigned planesize);
\r
114 statetype s_score = {NULL,NULL,think,false,
\r
115 false,0, 0,0, ScoreThink , NULL, ScoreReact, NULL};
\r
119 ======================
\r
123 ======================
\r
126 void SpawnScore (void)
\r
128 scoreobj->obclass = inertobj;
\r
129 scoreobj->active = allways;
\r
130 scoreobj->needtoclip = false;
\r
131 *((long *)&(scoreobj->temp1)) = -1; // force score to be updated
\r
132 scoreobj->temp3 = -1; // and flower power
\r
133 scoreobj->temp4 = -1; // and lives
\r
134 NewState (scoreobj,&s_score);
\r
138 void FixScoreBox (void)
\r
140 unsigned width, planesize;
\r
141 unsigned smallplane,bigplane;
\r
142 spritetype _seg *block;
\r
145 // draw boobus bomb if on level 15, else flower power
\r
146 block = (spritetype _seg *)grsegs[SCOREBOXSPR];
\r
147 width = block->width[0];
\r
148 planesize = block->planesize[0];
\r
149 dest = (byte far *)grsegs[SCOREBOXSPR]+block->sourceoffset[0]
\r
150 + planesize + width*16 + 4*CHARWIDTH;
\r
153 MemDrawChar (20,dest,width,planesize);
\r
154 MemDrawChar (21,dest+CHARWIDTH,width,planesize);
\r
155 MemDrawChar (22,dest+width*8,width,planesize);
\r
156 MemDrawChar (23,dest+width*8+CHARWIDTH,width,planesize);
\r
160 MemDrawChar (28,dest,width,planesize);
\r
161 MemDrawChar (29,dest+CHARWIDTH,width,planesize);
\r
162 MemDrawChar (30,dest+width*8,width,planesize);
\r
163 MemDrawChar (31,dest+width*8+CHARWIDTH,width,planesize);
\r
170 ======================
\r
174 ======================
\r
177 #if GRMODE == EGAGR
\r
179 void MemDrawChar (int char8,byte far *dest,unsigned width,unsigned planesize)
\r
186 asm shl si,1 // index into char 8 segment
\r
188 asm mov ds,[WORD PTR grsegs+STARTTILE8*2]
\r
189 asm mov es,[WORD PTR dest+2]
\r
191 asm mov cx,4 // draw four planes
\r
197 asm mov di,[WORD PTR dest]
\r
215 asm mov ax,[planesize]
\r
216 asm add [WORD PTR dest],ax
\r
226 #if GRMODE == CGAGR
\r
227 void MemDrawChar (int char8,byte far *dest,unsigned width,unsigned planesize)
\r
233 asm shl si,1 // index into char 8 segment
\r
235 asm mov ds,[WORD PTR grsegs+STARTTILE8*2]
\r
236 asm mov es,[WORD PTR dest+2]
\r
241 asm mov di,[WORD PTR dest]
\r
262 planesize++; // shut the compiler up
\r
268 ====================
\r
272 ====================
\r
274 #if GRMODE == EGAGR
\r
275 void ShiftScore (void)
\r
277 spritetabletype far *spr;
\r
278 spritetype _seg *dest;
\r
280 spr = &spritetable[SCOREBOXSPR-STARTSPRITES];
\r
281 dest = (spritetype _seg *)grsegs[SCOREBOXSPR];
\r
283 CAL_ShiftSprite (FP_SEG(dest),dest->sourceoffset[0],
\r
284 dest->sourceoffset[1],spr->width,spr->height,2);
\r
286 CAL_ShiftSprite (FP_SEG(dest),dest->sourceoffset[0],
\r
287 dest->sourceoffset[2],spr->width,spr->height,4);
\r
289 CAL_ShiftSprite (FP_SEG(dest),dest->sourceoffset[0],
\r
290 dest->sourceoffset[3],spr->width,spr->height,6);
\r
302 void ScoreThink (objtype *ob)
\r
305 spritetype _seg *block;
\r
307 unsigned i, length, width, planesize, number;
\r
312 if ((gamestate.score>>16) != ob->temp1
\r
313 || (unsigned)gamestate.score != ob->temp2 )
\r
315 block = (spritetype _seg *)grsegs[SCOREBOXSPR];
\r
316 width = block->width[0];
\r
317 planesize = block->planesize[0];
\r
318 dest = (byte far *)grsegs[SCOREBOXSPR]+block->sourceoffset[0]
\r
319 + planesize + width*4 + 1*CHARWIDTH;
\r
321 ltoa (gamestate.score,str,10);
\r
323 // erase leading spaces
\r
324 length = strlen(str);
\r
325 for (i=6;i>length;i--)
\r
326 MemDrawChar (0,dest+=CHARWIDTH,width,planesize);
\r
331 MemDrawChar (*ch++ - '0'+1,dest+=CHARWIDTH,width,planesize);
\r
333 #if GRMODE == EGAGR
\r
336 ob->needtoreact = true;
\r
337 ob->temp1 = gamestate.score>>16;
\r
338 ob->temp2 = gamestate.score;
\r
342 // flower power changed
\r
345 number = gamestate.boobusbombs;
\r
347 number = gamestate.flowerpowers;
\r
348 if (number != ob->temp3)
\r
350 block = (spritetype _seg *)grsegs[SCOREBOXSPR];
\r
351 width = block->width[0];
\r
352 planesize = block->planesize[0];
\r
353 dest = (byte far *)grsegs[SCOREBOXSPR]+block->sourceoffset[0]
\r
354 + planesize + width*20 + 5*CHARWIDTH;
\r
359 ltoa (number,str,10);
\r
361 // erase leading spaces
\r
362 length = strlen(str);
\r
363 for (i=2;i>length;i--)
\r
364 MemDrawChar (0,dest+=CHARWIDTH,width,planesize);
\r
369 MemDrawChar (*ch++ - '0'+1,dest+=CHARWIDTH,width,planesize);
\r
371 #if GRMODE == EGAGR
\r
374 ob->needtoreact = true;
\r
375 ob->temp3 = gamestate.flowerpowers;
\r
381 if (gamestate.lives != ob->temp4)
\r
383 block = (spritetype _seg *)grsegs[SCOREBOXSPR];
\r
384 width = block->width[0];
\r
385 planesize = block->planesize[0];
\r
386 dest = (byte far *)grsegs[SCOREBOXSPR]+block->sourceoffset[0]
\r
387 + planesize + width*20 + 2*CHARWIDTH;
\r
389 if (gamestate.lives>9)
\r
390 MemDrawChar ('9' - '0'+1,dest,width,planesize);
\r
392 MemDrawChar (gamestate.lives +1,dest,width,planesize);
\r
394 #if GRMODE == EGAGR
\r
397 ob->needtoreact = true;
\r
398 ob->temp4 = gamestate.lives;
\r
401 if (originxglobal != ob->x || originyglobal != ob->y)
\r
402 ob->needtoreact = true;
\r
414 void ScoreReact (objtype *ob)
\r
416 ob->x = originxglobal;
\r
417 ob->y = originyglobal;
\r
419 #if GRMODE == EGAGR
\r
420 RF_PlaceSprite (&ob->sprite
\r
427 #if GRMODE == CGAGR
\r
428 RF_PlaceSprite (&ob->sprite
\r
439 =============================================================================
\r
441 FLOWER POWER ROUTINES
\r
443 temp1 = 8, same as power bonus
\r
444 temp2 = initial direction
\r
446 =============================================================================
\r
449 void PowerCount (objtype *ob);
\r
450 void PowerContact (objtype *ob, objtype *hit);
\r
451 void PowerReact (objtype *ob);
\r
453 extern statetype s_flowerpower1;
\r
454 extern statetype s_flowerpower2;
\r
456 extern statetype s_boobusbomb1;
\r
457 extern statetype s_boobusbomb2;
\r
459 extern statetype s_bombexplode;
\r
460 extern statetype s_bombexplode2;
\r
461 extern statetype s_bombexplode3;
\r
462 extern statetype s_bombexplode4;
\r
463 extern statetype s_bombexplode5;
\r
464 extern statetype s_bombexplode6;
\r
466 extern statetype s_powerblink1;
\r
467 extern statetype s_powerblink2;
\r
469 statetype s_flowerpower1 = {FLOWERPOWER1SPR,FLOWERPOWER1SPR,stepthink,false,
\r
470 false,10, 0,0, ProjectileThink, PowerContact, PowerReact, &s_flowerpower2};
\r
471 statetype s_flowerpower2 = {FLOWERPOWER2SPR,FLOWERPOWER2SPR,stepthink,false,
\r
472 false,10, 0,0, ProjectileThink, PowerContact, PowerReact, &s_flowerpower1};
\r
474 statetype s_boobusbomb1 = {BOOBUSBOMB1SPR,BOOBUSBOMB1SPR,stepthink,false,
\r
475 false,5, 0,0, ProjectileThink, PowerContact, PowerReact, &s_boobusbomb2};
\r
476 statetype s_boobusbomb2 = {BOOBUSBOMB3SPR,BOOBUSBOMB3SPR,stepthink,false,
\r
477 false,5, 0,0, ProjectileThink, PowerContact, PowerReact, &s_boobusbomb1};
\r
479 statetype s_bombexplode = {BOOBUSBOOM1SPR,BOOBUSBOOM1SPR,step,false,
\r
480 false,5, 0,0, NULL, NULL, DrawReact, &s_bombexplode2};
\r
481 statetype s_bombexplode2= {BOOBUSBOOM2SPR,BOOBUSBOOM2SPR,step,false,
\r
482 false,5, 0,0, NULL, NULL, DrawReact, &s_bombexplode3};
\r
483 statetype s_bombexplode3= {BOOBUSBOOM1SPR,BOOBUSBOOM1SPR,step,false,
\r
484 false,5, 0,0, NULL, NULL, DrawReact, &s_bombexplode4};
\r
485 statetype s_bombexplode4= {BOOBUSBOOM2SPR,BOOBUSBOOM2SPR,step,false,
\r
486 false,5, 0,0, NULL, NULL, DrawReact, &s_bombexplode5};
\r
487 statetype s_bombexplode5= {BOOBUSBOOM1SPR,BOOBUSBOOM1SPR,step,false,
\r
488 false,5, 0,0, NULL, NULL, DrawReact, &s_bombexplode6};
\r
489 statetype s_bombexplode6= {BOOBUSBOOM2SPR,BOOBUSBOOM2SPR,step,false,
\r
490 false,5, 0,0, NULL, NULL, DrawReact, NULL};
\r
492 statetype s_powerblink1 = {FLOWERPOWER1SPR,FLOWERPOWER1SPR,step,false,
\r
493 false,5, 0,0, PowerCount, NULL, DrawReact, &s_powerblink2};
\r
494 statetype s_powerblink2 = {-1,-1,step,false,
\r
495 false,5, 0,0, PowerCount, NULL, DrawReact, &s_powerblink1};
\r
506 void ThrowPower (unsigned x, unsigned y, int dir)
\r
508 statetype *startstate;
\r
512 if (!gamestate.boobusbombs)
\r
514 SD_PlaySound (NOWAYSND);
\r
515 return; // no bombs to throw
\r
517 SD_PlaySound (THROWBOMBSND);
\r
518 gamestate.bombsthislevel--;
\r
519 gamestate.boobusbombs--;
\r
523 if (!gamestate.flowerpowers)
\r
525 SD_PlaySound (NOWAYSND);
\r
526 return; // no flower power to throw
\r
528 SD_PlaySound (THROWSND);
\r
529 gamestate.flowerpowers--;
\r
535 new->obclass = powerobj;
\r
539 new->tileleft = new->tileright = x>>G_T_SHIFT;
\r
540 new->tiletop = new->tilebottom = y>>G_T_SHIFT;
\r
547 new->yspeed = SPDPOWERUP;
\r
550 new->xspeed = SPDPOWER;
\r
551 new->yspeed = SPDPOWERY;
\r
555 new->yspeed = SPDPOWER;
\r
558 new->xspeed = -SPDPOWER;
\r
559 new->yspeed = SPDPOWERY;
\r
562 Quit ("ThrowPower: Bad dir!");
\r
567 new->temp1 = 8; // flower power bonus
\r
568 startstate = &s_flowerpower1;
\r
572 new->temp1 = 10; // boobus bomb bonus
\r
573 startstate = &s_boobusbomb1;
\r
575 new->active = removable;
\r
578 new->x -= 5*new->xspeed; // make sure they hit nearby walls
\r
579 new->y -= 5*new->yspeed;
\r
581 NewState (new,startstate);
\r
583 new->xmove = 5*new->xspeed;
\r
584 new->ymove = 5*new->yspeed;
\r
590 ============================
\r
594 ============================
\r
597 void PowerCount (objtype *ob)
\r
603 if (ob->temp2 > POWERCOUNT)
\r
609 ============================
\r
611 = CalcSingleGravity
\r
613 ============================
\r
616 void CalcSingleGravity (void)
\r
621 // only accelerate on odd tics, because of limited precision
\r
625 for (i=lasttimecount-tics;i<lasttimecount;i++)
\r
633 singlegravity+=speed;
\r
641 ============================
\r
645 ============================
\r
648 void PowerContact (objtype *ob, objtype *hit)
\r
650 unsigned x,y,yspot,xspot;
\r
652 switch (hit->obclass)
\r
665 ChangeToFlower (hit);
\r
672 GivePoints (50000);
\r
673 GivePoints (50000);
\r
674 hit->obclass = inertobj;
\r
675 ChangeState (hit,&s_boobusdie);
\r
676 hit->temp1 = 0; // death count
\r
678 SD_PlaySound (BOMBBOOMSND);
\r
679 ChangeState (ob,&s_bombexplode);
\r
686 ============================
\r
690 ============================
\r
693 void PowerReact (objtype *ob)
\r
695 unsigned wall,absx,absy,angle,newangle;
\r
696 unsigned long speed;
\r
699 if (ob->hiteast || ob->hitwest)
\r
701 ob->xspeed= -ob->xspeed/2;
\r
702 ob->obclass = bonusobj;
\r
707 if ( ob->hitsouth == 17) // go through pole holes
\r
709 if (ob->temp2 != dir_North)
\r
710 ob->obclass = bonusobj;
\r
714 ob->x = ob->tilemidx*TILEGLOBAL + 4*PIXGLOBAL;
\r
718 ob->yspeed= -ob->yspeed/2;
\r
723 wall = ob->hitnorth;
\r
724 if ( wall == 17) // go through pole holes
\r
726 if (ob->temp2 != dir_South)
\r
727 ob->obclass = bonusobj;
\r
731 ob->x = ob->tilemidx*TILEGLOBAL + 4*PIXGLOBAL;
\r
735 ob->obclass = bonusobj;
\r
736 if (ob->yspeed < 0)
\r
739 absx = abs(ob->xspeed);
\r
743 if (absx>absy*2) // 22 degrees
\r
746 speed = absx*286; // x*sqrt(5)/2
\r
751 speed = absx*362; // x*sqrt(2)
\r
756 if (absy>absx*2) // 90 degrees
\r
763 angle = 2; // 67 degrees
\r
764 speed = absy*286; // y*sqrt(5)/2
\r
767 if (ob->xspeed > 0)
\r
771 newangle = bounceangle[ob->hitnorth][angle];
\r
775 ob->xspeed = speed / 286;
\r
776 ob->yspeed = -ob->xspeed / 2;
\r
779 ob->xspeed = speed / 362;
\r
780 ob->yspeed = -ob->xspeed;
\r
783 ob->yspeed = -(speed / 286);
\r
784 ob->xspeed = -ob->yspeed / 2;
\r
790 ob->yspeed = -(speed / 256);
\r
793 ob->yspeed = -(speed / 286);
\r
794 ob->xspeed = ob->yspeed / 2;
\r
797 ob->xspeed = ob->yspeed = -(speed / 362);
\r
800 ob->xspeed = -(speed / 286);
\r
801 ob->yspeed = ob->xspeed / 2;
\r
805 ob->xspeed = -(speed / 286);
\r
806 ob->yspeed = -ob->xspeed / 2;
\r
809 ob->xspeed = -(speed / 362);
\r
810 ob->yspeed = -ob->xspeed;
\r
813 ob->yspeed = speed / 286;
\r
814 ob->xspeed = -ob->yspeed / 2;
\r
820 ob->yspeed = -(speed / 256);
\r
823 ob->yspeed = speed / 286;
\r
824 ob->xspeed = ob->yspeed / 2;
\r
827 ob->xspeed = speed / 362;
\r
828 ob->yspeed = speed / 362;
\r
831 ob->xspeed = speed / 286;
\r
832 ob->yspeed = ob->xspeed / 2;
\r
836 if (speed < 256*16)
\r
840 ob->ydir = -1; // bonus stuff flies up when touched
\r
841 ob->temp2 = ob->shapenum = BOOBUSBOMB1SPR;
\r
842 ob->temp3 = ob->temp2 + 2;
\r
843 ob->needtoclip = 0;
\r
844 ChangeState (ob,&s_bonus);
\r
848 ChangeState (ob,&s_powerblink1);
\r
849 ob->needtoclip = 0;
\r
850 ob->temp2 = 0; // blink time
\r
858 =============================================================================
\r
862 player->temp1 = dir
\r
863 player->temp2 = animation stage
\r
865 #define WORLDKEENSLEEP1SPR 238
\r
866 #define WORLDKEENSLEEP2SPR 239
\r
867 #define WORLDKEENWAVE1SPR 240
\r
868 #define WORLDKEENWAVE2SPR 241
\r
869 =============================================================================
\r
872 void SpawnWorldKeen (int tilex, int tiley);
\r
873 void KeenWorldThink (objtype *ob);
\r
874 void KeenWorldWalk (objtype *ob);
\r
876 extern statetype s_worldkeen;
\r
878 extern statetype s_worldkeenwave1;
\r
879 extern statetype s_worldkeenwave2;
\r
880 extern statetype s_worldkeenwave3;
\r
881 extern statetype s_worldkeenwave4;
\r
882 extern statetype s_worldkeenwave5;
\r
884 extern statetype s_worldkeenwait;
\r
886 extern statetype s_worldkeensleep1;
\r
887 extern statetype s_worldkeensleep2;
\r
889 extern statetype s_worldwalk;
\r
893 statetype s_worldkeen = {NULL,NULL,stepthink,false,
\r
894 false,360, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeenwave1};
\r
896 statetype s_worldkeenwave1= {WORLDKEENWAVE1SPR,WORLDKEENWAVE1SPR,stepthink,false,
\r
897 false,20, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeenwave2};
\r
898 statetype s_worldkeenwave2= {WORLDKEENWAVE2SPR,WORLDKEENWAVE2SPR,stepthink,false,
\r
899 false,20, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeenwave3};
\r
900 statetype s_worldkeenwave3= {WORLDKEENWAVE1SPR,WORLDKEENWAVE1SPR,stepthink,false,
\r
901 false,20, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeenwave4};
\r
902 statetype s_worldkeenwave4= {WORLDKEENWAVE2SPR,WORLDKEENWAVE2SPR,stepthink,false,
\r
903 false,20, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeenwave5};
\r
904 statetype s_worldkeenwave5= {WORLDKEENWAVE1SPR,WORLDKEENWAVE1SPR,stepthink,false,
\r
905 false,20, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeenwait};
\r
907 statetype s_worldkeenwait = {WORLDKEEND3SPR,WORLDKEEND3SPR,stepthink,false,
\r
908 false,400, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeensleep1};
\r
910 statetype s_worldkeensleep1 = {WORLDKEENSLEEP1SPR,WORLDKEENSLEEP1SPR,stepthink,false,
\r
911 false,30, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeensleep2};
\r
912 statetype s_worldkeensleep2 = {WORLDKEENSLEEP2SPR,WORLDKEENSLEEP2SPR,stepthink,false,
\r
913 false,90, 0,0, KeenWorldThink, NULL, DrawReact, &s_worldkeensleep2};
\r
915 statetype s_worldwalk = {NULL,NULL,slide,false,
\r
916 false,4, 16,16, KeenWorldWalk, NULL, DrawReact, &s_worldwalk};
\r
921 ======================
\r
925 ======================
\r
928 void SpawnWorldKeen (int tilex, int tiley)
\r
930 player->obclass = keenobj;
\r
931 if (!gamestate.worldx)
\r
933 player->x = tilex<<G_T_SHIFT;
\r
934 player->y = tiley<<G_T_SHIFT;
\r
938 player->x = gamestate.worldx;
\r
939 player->y = gamestate.worldy;
\r
942 player->active = yes;
\r
943 player->needtoclip = true;
\r
946 player->temp1 = dir_West;
\r
948 player->shapenum = 3+WORLDKEENL1SPR-1; // feet together
\r
949 NewState (player,&s_worldkeen);
\r
954 ======================
\r
958 ======================
\r
961 void CheckEnterLevel (objtype *ob)
\r
965 for (y=ob->tiletop;y<=ob->tilebottom;y++)
\r
966 for (x=ob->tileleft;x<=ob->tileright;x++)
\r
968 tile = *((unsigned _seg *)mapsegs[2]+mapbwidthtable[y]/2+x);
\r
969 if (tile >= 3 && tile <=18)
\r
976 if (gamestate.boobusbombs < 12)
\r
978 VW_FixRefreshBuffer ();
\r
979 US_CenterWindow (26,6);
\r
981 US_CPrint ("You can't possibly\n"
\r
982 "defeat King Boobus Tuber\n"
\r
983 "with less than 12 bombs!");
\r
984 VW_UpdateScreen ();
\r
986 RF_ForceRefresh ();
\r
990 gamestate.worldx = ob->x;
\r
991 gamestate.worldy = ob->y;
\r
992 gamestate.mapon = tile-2;
\r
993 playstate = levelcomplete;
\r
994 SD_PlaySound (ENTERLEVELSND);
\r
1001 ======================
\r
1005 ======================
\r
1008 void KeenWorldThink (objtype *ob)
\r
1010 if (c.dir!=dir_None)
\r
1012 ob->state = &s_worldwalk;
\r
1014 KeenWorldWalk (ob);
\r
1017 if (c.button0 || c.button1)
\r
1018 CheckEnterLevel(ob);
\r
1023 ======================
\r
1027 ======================
\r
1030 int worldshapes[8] = {WORLDKEENU1SPR-1,WORLDKEENUR1SPR-1,WORLDKEENR1SPR-1,
\r
1031 WORLDKEENDR1SPR-1,WORLDKEEND1SPR-1,WORLDKEENDL1SPR-1,WORLDKEENL1SPR-1,
\r
1032 WORLDKEENUL1SPR-1};
\r
1034 int worldanims[4] ={2,3,1,3};
\r
1036 void KeenWorldWalk (objtype *ob)
\r
1038 ob->xdir = c.xaxis;
\r
1039 ob->ydir = c.yaxis;
\r
1041 if (++ob->temp2==4)
\r
1044 if (c.button0 || c.button1)
\r
1045 CheckEnterLevel(ob);
\r
1047 if (c.dir == dir_None)
\r
1049 ob->state = &s_worldkeen;
\r
1050 ob->shapenum = worldshapes[ob->temp1]+3;
\r
1054 ob->temp1 = c.dir;
\r
1055 ob->shapenum = worldshapes[ob->temp1]+worldanims[ob->temp2];
\r
1060 =============================================================================
\r
1064 player->temp1 = pausetime / pointer to zees when sleeping
\r
1065 player->temp2 = pausecount / stagecount
\r
1067 player->temp4 = pole x location
\r
1069 =============================================================================
\r
1072 void KeenStandThink (objtype *ob);
\r
1073 void KeenPauseThink (objtype *ob);
\r
1074 void KeenGoSleepThink (objtype *ob);
\r
1075 void KeenSleepThink (objtype *ob);
\r
1076 void KeenDieThink (objtype *ob);
\r
1077 void KeenDuckThink (objtype *ob);
\r
1078 void KeenDropDownThink (objtype *ob);
\r
1079 void KeenWalkThink (objtype *ob);
\r
1080 void KeenAirThink (objtype *ob);
\r
1081 void KeenPoleThink (objtype *ob);
\r
1082 void KeenClimbThink (objtype *ob);
\r
1083 void KeenDropThink (objtype *ob);
\r
1084 void KeenDive (objtype *ob);
\r
1085 void KeenThrow (objtype *ob);
\r
1087 void KeenContact (objtype *ob, objtype *hit);
\r
1088 void KeenSimpleReact (objtype *ob);
\r
1089 void KeenStandReact (objtype *ob);
\r
1090 void KeenWalkReact (objtype *ob);
\r
1091 void KeenPoleReact (objtype *ob);
\r
1092 void KeenAirReact (objtype *ob);
\r
1093 void KeenDiveReact (objtype *ob);
\r
1094 void KeenSlideReact (objtype *ob);
\r
1096 //-------------------
\r
1098 extern statetype s_keenzee1;
\r
1099 extern statetype s_keenzee2;
\r
1100 extern statetype s_keenzee3;
\r
1101 extern statetype s_keenzee4;
\r
1102 extern statetype s_keenzee5;
\r
1104 //-------------------
\r
1106 extern statetype s_keenstand;
\r
1107 extern statetype s_keenpauselook;
\r
1108 extern statetype s_keenyawn1;
\r
1109 extern statetype s_keenyawn2;
\r
1110 extern statetype s_keenyawn3;
\r
1111 extern statetype s_keenyawn4;
\r
1113 extern statetype s_keenwait1;
\r
1114 extern statetype s_keenwait2;
\r
1115 extern statetype s_keenwait3;
\r
1116 extern statetype s_keenwait4;
\r
1117 extern statetype s_keenwait5;
\r
1118 extern statetype s_keenwait6;
\r
1120 extern statetype s_keenmoon1;
\r
1121 extern statetype s_keenmoon2;
\r
1122 extern statetype s_keenmoon3;
\r
1124 extern statetype s_keengosleep1;
\r
1125 extern statetype s_keengosleep2;
\r
1126 extern statetype s_keensleep1;
\r
1127 extern statetype s_keensleep2;
\r
1129 extern statetype s_keendie1;
\r
1130 extern statetype s_keendie2;
\r
1131 extern statetype s_keendie3;
\r
1132 extern statetype s_keendie4;
\r
1134 extern statetype s_keenlookup;
\r
1135 extern statetype s_keenduck;
\r
1136 extern statetype s_keendrop;
\r
1138 //-------------------
\r
1140 extern statetype s_keenreach;
\r
1142 extern statetype s_keenpole;
\r
1144 extern statetype s_keenclimb1;
\r
1145 extern statetype s_keenclimb2;
\r
1146 extern statetype s_keenclimb3;
\r
1148 extern statetype s_keenslide1;
\r
1149 extern statetype s_keenslide2;
\r
1150 extern statetype s_keenslide3;
\r
1151 extern statetype s_keenslide4;
\r
1153 extern statetype s_keenpolethrow1;
\r
1154 extern statetype s_keenpolethrow2;
\r
1155 extern statetype s_keenpolethrow3;
\r
1157 extern statetype s_keenpolethrowup1;
\r
1158 extern statetype s_keenpolethrowup2;
\r
1159 extern statetype s_keenpolethrowup3;
\r
1161 extern statetype s_keenpolethrowdown1;
\r
1162 extern statetype s_keenpolethrowdown2;
\r
1163 extern statetype s_keenpolethrowdown3;
\r
1165 //-------------------
\r
1167 extern statetype s_keenwalk1;
\r
1168 extern statetype s_keenwalk2;
\r
1169 extern statetype s_keenwalk3;
\r
1170 extern statetype s_keenwalk4;
\r
1172 extern statetype s_keenthrow1;
\r
1173 extern statetype s_keenthrow2;
\r
1174 extern statetype s_keenthrow3;
\r
1175 extern statetype s_keenthrow4;
\r
1177 extern statetype s_keenthrowup1;
\r
1178 extern statetype s_keenthrowup2;
\r
1179 extern statetype s_keenthrowup3;
\r
1181 extern statetype s_keendive1;
\r
1182 extern statetype s_keendive2;
\r
1183 extern statetype s_keendive3;
\r
1185 //-------------------
\r
1187 extern statetype s_keenjumpup1;
\r
1188 extern statetype s_keenjumpup2;
\r
1189 extern statetype s_keenjumpup3;
\r
1191 extern statetype s_keenjump1;
\r
1192 extern statetype s_keenjump2;
\r
1193 extern statetype s_keenjump3;
\r
1195 extern statetype s_keenairthrow1;
\r
1196 extern statetype s_keenairthrow2;
\r
1197 extern statetype s_keenairthrow3;
\r
1199 extern statetype s_keenairthrowup1;
\r
1200 extern statetype s_keenairthrowup2;
\r
1201 extern statetype s_keenairthrowup3;
\r
1203 extern statetype s_keenairthrowdown1;
\r
1204 extern statetype s_keenairthrowdown2;
\r
1205 extern statetype s_keenairthrowdown3;
\r
1209 //-------------------
\r
1211 statetype s_keenzee1 = {KEENZEES1SPR,KEENZEES1SPR,step,false,
\r
1212 false,30, 0,0, NULL, NULL, DrawReact, &s_keenzee2};
\r
1213 statetype s_keenzee2 = {KEENZEES2SPR,KEENZEES2SPR,step,false,
\r
1214 false,30, 0,0, NULL, NULL, DrawReact, &s_keenzee3};
\r
1215 statetype s_keenzee3 = {KEENZEES3SPR,KEENZEES3SPR,step,false,
\r
1216 false,30, 0,0, NULL, NULL, DrawReact, &s_keenzee1};
\r
1218 //-------------------
\r
1220 statetype s_keenstand = {KEENSTANDLSPR,KEENSTANDRSPR,stepthink,false,
\r
1221 true,4, 0,16, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};
\r
1222 statetype s_keenpauselook= {KEENLOOKULSPR,KEENLOOKURSPR,stepthink,false,
\r
1223 true,60, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};
\r
1224 statetype s_keenyawn1 = {KEENYAWN1SPR,KEENYAWN1SPR,stepthink,false,
\r
1225 true,40, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenyawn2};
\r
1226 statetype s_keenyawn2 = {KEENYAWN2SPR,KEENYAWN2SPR,stepthink,false,
\r
1227 true,40, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenyawn3};
\r
1228 statetype s_keenyawn3 = {KEENYAWN3SPR,KEENYAWN3SPR,stepthink,false,
\r
1229 true,40, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenyawn4};
\r
1230 statetype s_keenyawn4 = {KEENYAWN4SPR,KEENYAWN4SPR,stepthink,false,
\r
1231 true,40, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};
\r
1233 statetype s_keenwait1 = {KEENWAITL2SPR,KEENWAITR2SPR,stepthink,false,
\r
1234 true,90, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait2};
\r
1235 statetype s_keenwait2 = {KEENWAITL1SPR,KEENWAITR1SPR,stepthink,false,
\r
1236 true,10, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait3};
\r
1237 statetype s_keenwait3 = {KEENWAITL2SPR,KEENWAITR2SPR,stepthink,false,
\r
1238 true,90, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait4};
\r
1239 statetype s_keenwait4 = {KEENWAITL1SPR,KEENWAITR1SPR,stepthink,false,
\r
1240 true,10, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait5};
\r
1241 statetype s_keenwait5 = {KEENWAITL2SPR,KEENWAITR2SPR,stepthink,false,
\r
1242 true,90, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait6};
\r
1243 statetype s_keenwait6 = {KEENWAITL3SPR,KEENWAITR3SPR,stepthink,false,
\r
1244 true,70, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};
\r
1246 statetype s_keengosleep1= {KEENSLEEP1SPR,KEENSLEEP1SPR,stepthink,false,
\r
1247 true,20, 0,0, KeenPauseThink, KeenContact, KeenStandReact, &s_keengosleep2};
\r
1248 statetype s_keengosleep2= {KEENSLEEP2SPR,KEENSLEEP2SPR,step,false,
\r
1249 true,20, 0,0, KeenGoSleepThink, KeenContact, KeenStandReact, &s_keensleep1};
\r
1250 statetype s_keensleep1= {KEENSLEEP3SPR,KEENSLEEP3SPR,stepthink,false,
\r
1251 true,120, 0,0, KeenSleepThink, KeenContact, KeenStandReact, &s_keensleep2};
\r
1252 statetype s_keensleep2= {KEENSLEEP4SPR,KEENSLEEP4SPR,stepthink,false,
\r
1253 true,120, 0,0, KeenSleepThink, KeenContact, KeenStandReact, &s_keensleep1};
\r
1255 statetype s_keengetup = {KEENGETUPLSPR,KEENGETUPRSPR,step,false,
\r
1256 true,15, 0,0, NULL, KeenContact, KeenSimpleReact, &s_keenstand};
\r
1258 statetype s_keendie1 = {KEENDREAM1SPR,KEENDREAM1SPR,step,false,
\r
1259 false,20, 0,0, NULL, NULL, KeenSimpleReact, &s_keendie2};
\r
1260 statetype s_keendie2 = {KEENDREAM2SPR,KEENDREAM2SPR,step,false,
\r
1261 false,20, 0,0, NULL, NULL, KeenSimpleReact, &s_keendie3};
\r
1262 statetype s_keendie3 = {KEENDREAM3SPR,KEENDREAM3SPR,step,false,
\r
1263 false,120, 0,0, KeenDieThink, NULL, KeenSimpleReact, &s_keendie3};
\r
1265 statetype s_keenlookup = {KEENLOOKULSPR,KEENLOOKURSPR,think,false,
\r
1266 true,0, 0,0, KeenStandThink, KeenContact, KeenStandReact, &s_keenlookup};
\r
1268 statetype s_keenduck = {KEENDUCKLSPR,KEENDUCKRSPR,think,false,
\r
1269 true,0, 0,0, KeenDuckThink, KeenContact, KeenStandReact, &s_keenduck};
\r
1271 statetype s_keendrop = {KEENDUCKLSPR,KEENDUCKRSPR,step,false,
\r
1272 false,0, 0,0, KeenDropDownThink, KeenContact, KeenSimpleReact, &s_keenjumpup3};
\r
1274 //-------------------
\r
1276 statetype s_keenpole = {KEENSHINNYL1SPR,KEENSHINNYR1SPR,think,false,
\r
1277 false,0, 0,0, KeenPoleThink, KeenContact, KeenSimpleReact, &s_keenpole};
\r
1279 statetype s_keenclimb1 = {KEENSHINNYL1SPR,KEENSHINNYR1SPR,slidethink,false,
\r
1280 false,8, 0,8, KeenClimbThink, KeenContact, KeenSimpleReact, &s_keenclimb2};
\r
1281 statetype s_keenclimb2 = {KEENSHINNYL2SPR,KEENSHINNYR2SPR,slidethink,false,
\r
1282 false,8, 0,8, KeenClimbThink, KeenContact, KeenSimpleReact, &s_keenclimb3};
\r
1283 statetype s_keenclimb3 = {KEENSHINNYL3SPR,KEENSHINNYR3SPR,slidethink,false,
\r
1284 false,8, 0,8, KeenClimbThink, KeenContact, KeenSimpleReact, &s_keenclimb1};
\r
1286 statetype s_keenslide1 = {KEENSLIDED1SPR,KEENSLIDED1SPR,slide,false,
\r
1287 false,8, 0,24, KeenDropThink, KeenContact, KeenSimpleReact, &s_keenslide2};
\r
1288 statetype s_keenslide2 = {KEENSLIDED2SPR,KEENSLIDED2SPR,slide,false,
\r
1289 false,8, 0,24, KeenDropThink, KeenContact, KeenSimpleReact, &s_keenslide3};
\r
1290 statetype s_keenslide3 = {KEENSLIDED3SPR,KEENSLIDED3SPR,slide,false,
\r
1291 false,8, 0,24, KeenDropThink, KeenContact, KeenSimpleReact, &s_keenslide4};
\r
1292 statetype s_keenslide4 = {KEENSLIDED4SPR,KEENSLIDED4SPR,slide,false,
\r
1293 false,8, 0,24, KeenDropThink, KeenContact, KeenSimpleReact, &s_keenslide1};
\r
1295 statetype s_keenpolethrow1 = {KEENPTHROWL1SPR,KEENPTHROWR1SPR,step,false,
\r
1296 false,8, 0,0, NULL, KeenContact, KeenSimpleReact, &s_keenpolethrow2};
\r
1297 statetype s_keenpolethrow2 = {KEENPTHROWL2SPR,KEENPTHROWR2SPR,step,true,
\r
1298 false,1, 0,0, KeenThrow, KeenContact, KeenSimpleReact, &s_keenpolethrow3};
\r
1299 statetype s_keenpolethrow3 = {KEENPTHROWL2SPR,KEENPTHROWR2SPR,step,false,
\r
1300 false,10, 0,0, NULL, KeenContact, KeenSimpleReact, &s_keenpole};
\r
1302 statetype s_keenpolethrowup1 = {KEENPLTHROWU1SPR,KEENPRTHROWU1SPR,step,false,
\r
1303 false,8, 0,0, NULL, KeenContact, KeenSimpleReact, &s_keenpolethrowup2};
\r
1304 statetype s_keenpolethrowup2 = {KEENPLTHROWU2SPR,KEENPRTHROWU2SPR,step,true,
\r
1305 false,1, 0,0, KeenThrow, KeenContact, KeenSimpleReact, &s_keenpolethrowup3};
\r
1306 statetype s_keenpolethrowup3 = {KEENPLTHROWU2SPR,KEENPRTHROWU2SPR,step,false,
\r
1307 false,10, 0,0, NULL, KeenContact, KeenSimpleReact, &s_keenpole};
\r
1309 statetype s_keenpolethrowdown1 = {KEENPLTHROWD1SPR,KEENPRTHROWD1SPR,step,false,
\r
1310 false,8, 0,0, NULL, KeenContact, KeenSimpleReact, &s_keenpolethrowdown2};
\r
1311 statetype s_keenpolethrowdown2 = {KEENPLTHROWD2SPR,KEENPRTHROWD2SPR,step,true,
\r
1312 false,1, 0,0, KeenThrow, KeenContact, KeenSimpleReact, &s_keenpolethrowdown3};
\r
1313 statetype s_keenpolethrowdown3 = {KEENPLTHROWD2SPR,KEENPRTHROWD2SPR,step,false,
\r
1314 false,10, 0,0, NULL, KeenContact, KeenSimpleReact, &s_keenpole};
\r
1317 //-------------------
\r
1319 statetype s_keenwalk1 = {KEENRUNL1SPR,KEENRUNR1SPR,slidethink,true,
\r
1320 true,6, 24,0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk2};
\r
1321 statetype s_keenwalk2 = {KEENRUNL2SPR,KEENRUNR2SPR,slidethink,true,
\r
1322 true,6, 24,0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk3};
\r
1323 statetype s_keenwalk3 = {KEENRUNL3SPR,KEENRUNR3SPR,slidethink,true,
\r
1324 true,6, 24,0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk4};
\r
1325 statetype s_keenwalk4 = {KEENRUNL4SPR,KEENRUNR4SPR,slidethink,true,
\r
1326 true,6, 24,0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk1};
\r
1328 statetype s_keenthrow1 = {KEENTHROWL1SPR,KEENTHROWR1SPR,step,true,
\r
1329 true,4, 0,0, NULL, KeenContact, KeenStandReact, &s_keenthrow2};
\r
1330 statetype s_keenthrow2 = {KEENTHROWL2SPR,KEENTHROWR2SPR,step,false,
\r
1331 true,4, 0,0, NULL, KeenContact, KeenStandReact, &s_keenthrow3};
\r
1332 statetype s_keenthrow3 = {KEENTHROWL3SPR,KEENTHROWR3SPR,step,true,
\r
1333 true,1, 0,0, KeenThrow, KeenContact, KeenStandReact, &s_keenthrow4};
\r
1334 statetype s_keenthrow4 = {KEENTHROWL3SPR,KEENTHROWR3SPR,step,false,
\r
1335 true,10, 0,0, NULL, KeenContact, KeenStandReact, &s_keenstand};
\r
1337 statetype s_keenthrowup1 = {KEENTHROWU1SPR,KEENTHROWU1SPR,step,false,
\r
1338 true,8, 0,0, NULL, KeenContact, KeenStandReact, &s_keenthrowup2};
\r
1339 statetype s_keenthrowup2 = {KEENTHROWU2SPR,KEENTHROWU2SPR,step,true,
\r
1340 true,1, 0,0, KeenThrow, KeenContact, KeenStandReact, &s_keenthrowup3};
\r
1341 statetype s_keenthrowup3 = {KEENTHROWU2SPR,KEENTHROWU2SPR,step,false,
\r
1342 true,10, 0,0, NULL, KeenContact, KeenStandReact, &s_keenstand};
\r
1344 //-------------------
\r
1346 statetype s_keenjumpup1 = {KEENJUMPUL1SPR,KEENJUMPUR1SPR,think,false,
\r
1347 false,0, 0,0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjumpup2};
\r
1348 statetype s_keenjumpup2 = {KEENJUMPUL2SPR,KEENJUMPUR2SPR,think,false,
\r
1349 false,0, 0,0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjumpup3};
\r
1350 statetype s_keenjumpup3 = {KEENJUMPUL1SPR,KEENJUMPUR1SPR,think,false,
\r
1351 false,0, 0,0, KeenAirThink, KeenContact, KeenAirReact, &s_keenstand};
\r
1353 statetype s_keenjump1 = {KEENJUMPL1SPR,KEENJUMPR1SPR,think,false,
\r
1354 false,0, 0,0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump2};
\r
1355 statetype s_keenjump2 = {KEENJUMPL2SPR,KEENJUMPR2SPR,think,false,
\r
1356 false,0, 0,0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump3};
\r
1357 statetype s_keenjump3 = {KEENJUMPL3SPR,KEENJUMPR3SPR,think,false,
\r
1358 false,0, 0,0, KeenAirThink, KeenContact, KeenAirReact, &s_keenstand};
\r
1360 statetype s_keenairthrow1= {KEENJLTHROWL1SPR,KEENJRTHROWR1SPR,stepthink,false,
\r
1361 false,8, 0,0, ProjectileThink, KeenContact, KeenAirReact, &s_keenairthrow2};
\r
1362 statetype s_keenairthrow2= {KEENJLTHROWL2SPR,KEENJRTHROWR2SPR,step,true,
\r
1363 false,1, 0,0, KeenThrow, KeenContact, KeenAirReact, &s_keenairthrow3};
\r
1364 statetype s_keenairthrow3= {KEENJLTHROWL2SPR,KEENJRTHROWR2SPR,stepthink,false,
\r
1365 false,10, 0,0, ProjectileThink, KeenContact, KeenAirReact, &s_keenjumpup3};
\r
1367 statetype s_keenairthrowup1= {KEENJLTHROWU1SPR,KEENJRTHROWU1SPR,stepthink,false,
\r
1368 false,8, 0,0, ProjectileThink, KeenContact, KeenAirReact, &s_keenairthrowup2};
\r
1369 statetype s_keenairthrowup2= {KEENJLTHROWU2SPR,KEENJRTHROWU2SPR,step,true,
\r
1370 false,1, 0,0, KeenThrow, KeenContact, KeenAirReact, &s_keenairthrowup3};
\r
1371 statetype s_keenairthrowup3= {KEENJLTHROWU2SPR,KEENJRTHROWU2SPR,stepthink,false,
\r
1372 false,10, 0,0, ProjectileThink, KeenContact, KeenAirReact, &s_keenjumpup3};
\r
1374 statetype s_keenairthrowdown1= {KEENJLTHROWD1SPR,KEENJRTHROWD1SPR,stepthink,false,
\r
1375 false,8, 0,0, ProjectileThink, KeenContact, KeenAirReact, &s_keenairthrowdown2};
\r
1376 statetype s_keenairthrowdown2= {KEENJLTHROWD2SPR,KEENJRTHROWD2SPR,step,true,
\r
1377 false,1, 0,0, KeenThrow, KeenContact, KeenAirReact, &s_keenairthrowdown3};
\r
1378 statetype s_keenairthrowdown3= {KEENJLTHROWD2SPR,KEENJRTHROWD2SPR,stepthink,false,
\r
1379 false,10, 0,0, ProjectileThink, KeenContact, KeenAirReact, &s_keenjumpup3};
\r
1382 //===========================================================================
\r
1395 void SpawnKeen (int tilex, int tiley, int dir)
\r
1397 player->obclass = keenobj;
\r
1398 player->active = yes;
\r
1399 player->needtoclip = true;
\r
1400 player->x = tilex<<G_T_SHIFT;
\r
1401 player->y = (tiley<<G_T_SHIFT) - BLOCKSIZE*2;
\r
1403 player->xdir = dir;
\r
1405 NewState (player,&s_keenstand);
\r
1408 //==========================================================================
\r
1411 ======================
\r
1415 ======================
\r
1418 boolean CheckGrabPole (objtype *ob)
\r
1421 unsigned far *map;
\r
1424 // kludgy bit to not let you grab a pole the instant you jump off it
\r
1426 if (TimeCount < leavepoletime)
\r
1427 leavepoletime = 0;
\r
1428 else if (TimeCount - leavepoletime < MINPOLEJUMPTICS)
\r
1431 if (c.yaxis == -1)
\r
1432 map = (unsigned _seg *)mapsegs[1]+
\r
1433 mapbwidthtable[(ob->top+6*PIXGLOBAL)/TILEGLOBAL]/2;
\r
1435 map = (unsigned _seg *)mapsegs[1]+
\r
1436 mapbwidthtable[ob->tilebottom]/2;
\r
1438 x = (ob->left + (ob->right - ob->left)/2) >>G_T_SHIFT;
\r
1442 if ((tinf[INTILE+*map]&0x7f) == 1)
\r
1444 ob->xmove = ((x<<G_T_SHIFT)-8*PIXGLOBAL) - ob->x;
\r
1445 ob->ymove = c.yaxis*32;
\r
1446 ob->temp4 = x; // for future reference
\r
1447 ob->needtoclip = false; // can climb through pole holes
\r
1448 ob->state = &s_keenpole;
\r
1455 //==========================================================================
\r
1459 ============================
\r
1463 ============================
\r
1466 void KeenStandThink (objtype *ob)
\r
1470 // started walking
\r
1471 ob->xdir = c.xaxis;
\r
1472 ob->state = &s_keenwalk1;
\r
1473 ob->xmove = ob->xdir*s_keenwalk1.xmove*tics;
\r
1474 KeenWalkThink(ob);
\r
1478 if (c.button0 && !button0held)
\r
1480 // jump straight up
\r
1481 SD_PlaySound (JUMPSND);
\r
1483 ob->yspeed = -SPDJUMP;
\r
1485 ob->ymove = 0; // ob->yspeed*tics; // DEBUG
\r
1486 jumptime = JUMPTIME; // -tics;
\r
1487 ob->state = &s_keenjumpup1;
\r
1488 button0held = true;
\r
1492 if (c.button1 && !button1held)
\r
1494 // throw current xdir
\r
1495 if (c.yaxis == -1)
\r
1496 ob->state = &s_keenthrowup1;
\r
1498 ob->state = &s_keenthrow1;
\r
1499 button1held = true;
\r
1506 if (!CheckGrabPole(ob)) // try to go up/down pole first
\r
1507 ob->state = &s_keenlookup;
\r
1510 ob->state = &s_keenstand;
\r
1513 if (!CheckGrabPole(ob)) // try to go up/down pole first
\r
1514 ob->state = &s_keenduck;
\r
1519 //===========================================================================
\r
1522 =======================
\r
1526 = Do special animations in time
\r
1528 =======================
\r
1531 void KeenPauseThink (objtype *ob)
\r
1533 if (c.dir != dir_None || c.button0 || c.button1)
\r
1535 ob->temp1 = ob->temp2 = 0; // not paused any more
\r
1536 ob->state = &s_keenstand;
\r
1537 KeenStandThink(ob);
\r
1541 if ((ob->hitnorth & ~7) != 24) // if it is 0 now, keen is standing on a sprite
\r
1542 ob->temp1 += tics;
\r
1544 switch (ob->temp2)
\r
1547 if (ob->temp1 > 200)
\r
1550 ob->state = &s_keenpauselook;
\r
1555 if (ob->temp1 > 300)
\r
1558 ob->state = &s_keenwait1;
\r
1563 if (ob->temp1 > 700)
\r
1566 ob->state = &s_keenyawn1;
\r
1571 if (ob->temp1 > 400)
\r
1574 ob->state = &s_keenpauselook;
\r
1579 if (ob->temp1 > 700)
\r
1582 ob->state = &s_keenyawn1;
\r
1587 if (ob->temp1 > 400)
\r
1590 ob->state = &s_keengosleep1;
\r
1597 //===========================================================================
\r
1600 =======================
\r
1602 = KeenGoSleepThink
\r
1604 =======================
\r
1607 void KeenGoSleepThink (objtype *ob)
\r
1610 // spawn the zees above keens head
\r
1614 new->obclass = inertobj;
\r
1615 new->x = player->x;
\r
1616 new->y = player->y-4*PIXGLOBAL;
\r
1619 NewState (new,&s_keenzee1);
\r
1621 ob->temp1 = (int)new; // so they can be removed later
\r
1625 //===========================================================================
\r
1628 =======================
\r
1632 =======================
\r
1635 void KeenSleepThink (objtype *ob)
\r
1637 if (c.dir != dir_None || c.button0 || c.button1)
\r
1639 if (ob->temp1 != (unsigned)&dummyobj)
\r
1640 RemoveObj ((objtype *)ob->temp1); // remove the zees
\r
1641 ob->temp1 = ob->temp2 = 0; // not paused any more
\r
1642 ob->state = &s_keengetup;
\r
1647 //===========================================================================
\r
1650 =======================
\r
1654 =======================
\r
1657 void KeenDieThink (objtype *ob)
\r
1659 ob++; // shut up compiler
\r
1664 //===========================================================================
\r
1667 =======================
\r
1671 =======================
\r
1674 void KeenDuckThink (objtype *ob)
\r
1676 unsigned far *map, tile;
\r
1677 int midtile,bottomtile,move;
\r
1681 ob->state = &s_keenstand;
\r
1682 KeenStandThink(ob);
\r
1687 ob->xdir = c.xaxis;
\r
1689 if (c.button0 && !button0held)
\r
1692 // drop down a level
\r
1694 button0held = true;
\r
1696 midtile = (ob->tileleft + ob->tileright) >> 1;
\r
1697 bottomtile = ob->tilebottom;
\r
1698 map = (unsigned far *)mapsegs[1] + mapbwidthtable[bottomtile]/2
\r
1701 if (tinf[WESTWALL+tile] || tinf[EASTWALL+tile]
\r
1702 || tinf[SOUTHWALL+tile])
\r
1703 return; // wall prevents drop down
\r
1707 if (tinf[WESTWALL+tile] || tinf[EASTWALL+tile]
\r
1708 || tinf[SOUTHWALL+tile])
\r
1709 return; // wall prevents drop down
\r
1711 move = PIXGLOBAL*(tics<4 ? 4: tics);
\r
1712 ob->bottom += move;
\r
1714 ob->xmove = ob->ymove = 0;
\r
1715 ob->state = &s_keenjumpup3;
\r
1716 ob->temp2 = 1; // allready in last stage
\r
1717 ob->xspeed = ob->yspeed = 0;
\r
1718 SD_PlaySound (PLUMMETSND);
\r
1723 //===========================================================================
\r
1726 =======================
\r
1728 = KeenDropDownThink
\r
1730 =======================
\r
1733 void KeenDropDownThink (objtype *ob)
\r
1735 ob->needtoclip = true;
\r
1739 //===========================================================================
\r
1742 =======================
\r
1746 =======================
\r
1749 unsigned slopespeed[8] = {0,0,4,4,8,-4,-4,-8};
\r
1751 void KeenWalkThink (objtype *ob)
\r
1758 // stopped running
\r
1760 KeenStandThink (ob);
\r
1764 ob->xdir = c.xaxis;
\r
1766 if (c.yaxis && CheckGrabPole(ob)) // try to go up/down pole
\r
1769 if (c.button0 && !button0held)
\r
1774 SD_PlaySound (JUMPSND);
\r
1775 ob->xspeed = ob->xdir * SPDRUNJUMP;
\r
1776 ob->yspeed = -SPDJUMP;
\r
1778 ob->ymove = 0; // ob->yspeed*tics;
\r
1779 button0held = true;
\r
1780 jumptime = JUMPTIME; //-tics; // DEBUG
\r
1781 ob->state = &s_keenjump1;
\r
1784 if (c.button1 && !button1held)
\r
1789 ob->state = &s_keenthrow1;
\r
1790 button1held = true;
\r
1795 // give speed for slopes
\r
1797 move = tics*slopespeed[ob->hitnorth&7];
\r
1799 ob->xmove += move;
\r
1802 //===========================================================================
\r
1805 =======================
\r
1809 =======================
\r
1812 void KeenAirThink (objtype *ob)
\r
1816 if (jumptime<tics)
\r
1818 ob->ymove = ob->yspeed*jumptime;
\r
1823 ob->ymove = ob->yspeed*tics;
\r
1833 ob->state = ob->state->nextstate; // switch to second jump stage
\r
1840 if (ob->yspeed>0 && !ob->temp2)
\r
1842 ob->state = ob->state->nextstate; // switch to third jump stage
\r
1851 ob->xdir = c.xaxis;
\r
1852 AccelerateX(ob,c.xaxis*2,MAXXSPEED);
\r
1857 if (c.button1 && !button1held)
\r
1859 button1held = true;
\r
1866 ob->state = &s_keenairthrowup1;
\r
1869 ob->state = &s_keenairthrow1;
\r
1872 ob->state = &s_keenairthrowdown1;
\r
1877 if (ob->hitsouth==17) // going through a pole hole
\r
1879 ob->xspeed = ob->xmove = 0;
\r
1883 if (c.yaxis == -1)
\r
1884 CheckGrabPole (ob);
\r
1888 //===========================================================================
\r
1891 =======================
\r
1895 =======================
\r
1898 int polexspeed[3] = {-SPDPOLESIDEJUMP,0,SPDPOLESIDEJUMP};
\r
1900 void PoleActions (objtype *ob)
\r
1903 ob->xdir = c.xaxis;
\r
1905 if (c.button0 && !button0held) // jump off the pole
\r
1907 SD_PlaySound (JUMPSND);
\r
1908 ob->xspeed = polexspeed[c.xaxis+1];
\r
1909 ob->yspeed = -SPDPOLEJUMP;
\r
1910 ob->needtoclip = true;
\r
1911 jumptime = POLEJUMPTIME;
\r
1912 ob->state = &s_keenjump1;
\r
1914 button0held = true;
\r
1915 leavepoletime = TimeCount;
\r
1919 if (c.button1 && !button1held)
\r
1921 button1held = true;
\r
1926 ob->state = &s_keenpolethrowup1;
\r
1929 ob->state = &s_keenpolethrow1;
\r
1932 ob->state = &s_keenpolethrowdown1;
\r
1939 void KeenPoleThink (objtype *ob)
\r
1941 unsigned far *map, tile;
\r
1946 ob->state = &s_keenclimb1;
\r
1951 ob->state = &s_keenslide1;
\r
1953 KeenDropThink (ob);
\r
1960 // walk off pole if right next to ground
\r
1962 map = mapsegs[1] + (mapbwidthtable[ob->tilebottom+1]/2 + ob->tilemidx);
\r
1964 if (tinf[NORTHWALL+tile])
\r
1968 ob->needtoclip = true;
\r
1970 ob->state = &s_keenjump3;
\r
1972 SD_PlaySound (PLUMMETSND);
\r
1982 =======================
\r
1986 =======================
\r
1989 void KeenClimbThink (objtype *ob)
\r
1991 unsigned far *map;
\r
1993 map = (unsigned _seg *)mapsegs[1]+mapbwidthtable[ob->tiletop]/2+ob->temp4;
\r
1995 if ((tinf[INTILE+*map]&0x7f) != 1)
\r
1998 ob->state = &s_keenpole; // ran out of pole
\r
2005 ob->state = &s_keenpole;
\r
2010 ob->state = &s_keenslide1;
\r
2012 KeenDropThink (ob);
\r
2021 =======================
\r
2025 =======================
\r
2028 void KeenDropThink (objtype *ob)
\r
2030 unsigned far *map;
\r
2032 map = (unsigned _seg *)mapsegs[1]+mapbwidthtable[ob->tilebottom]/2+ob->temp4;
\r
2034 if ((tinf[INTILE+*map]&0x7f) != 1)
\r
2036 SD_PlaySound (PLUMMETSND);
\r
2037 ob->state = &s_keenjump3; // ran out of pole
\r
2040 ob->xspeed = polexspeed[c.xaxis+1];
\r
2042 ob->needtoclip = true;
\r
2050 ob->state = &s_keenclimb1;
\r
2055 ob->state = &s_keenpole;
\r
2063 //===========================================================================
\r
2066 =======================
\r
2070 =======================
\r
2073 void KeenThrow (objtype *ob)
\r
2075 // can't use &<var> in a switch statement...
\r
2077 if (ob->state == &s_keenthrow3)
\r
2080 ThrowPower (ob->midx-4*PIXGLOBAL,ob->y+8*PIXGLOBAL,dir_East);
\r
2082 ThrowPower (ob->midx-4*PIXGLOBAL,ob->y+8*PIXGLOBAL,dir_West);
\r
2086 if (ob->state == &s_keenpolethrow2)
\r
2089 ThrowPower (ob->x+24*PIXGLOBAL,ob->y,dir_East);
\r
2091 ThrowPower (ob->x-8*PIXGLOBAL,ob->y,dir_West);
\r
2095 if (ob->state == &s_keenthrowup2)
\r
2097 ThrowPower (ob->x+4*PIXGLOBAL,ob->y-8*PIXGLOBAL,dir_North);
\r
2101 if (ob->state == &s_keenpolethrowup2)
\r
2103 ThrowPower (ob->x+8*PIXGLOBAL,ob->y-8*PIXGLOBAL,dir_North);
\r
2107 if (ob->state == &s_keenpolethrowdown2)
\r
2109 ThrowPower (ob->x+8*PIXGLOBAL,ob->y+8*PIXGLOBAL,dir_South);
\r
2113 if (ob->state == &s_keenairthrow2)
\r
2116 ThrowPower (ob->midx-4*PIXGLOBAL,ob->y+8*PIXGLOBAL,dir_East);
\r
2118 ThrowPower (ob->midx-4*PIXGLOBAL,ob->y+8*PIXGLOBAL,dir_West);
\r
2121 ThrowPower (ob->x+32*PIXGLOBAL,ob->y+8*PIXGLOBAL,dir_East);
\r
2123 ThrowPower (ob->x-16*PIXGLOBAL,ob->y+8*PIXGLOBAL,dir_West);
\r
2126 new->xspeed += ob->xspeed/2;
\r
2127 new->yspeed += ob->yspeed/2;
\r
2131 if (ob->state == &s_keenairthrowup2)
\r
2134 ThrowPower (ob->x+16*PIXGLOBAL,ob->y,dir_North);
\r
2136 ThrowPower (ob->x+4*PIXGLOBAL,ob->y,dir_North);
\r
2137 new->xspeed += ob->xspeed/2;
\r
2138 new->yspeed += ob->yspeed/2;
\r
2142 if (ob->state == &s_keenairthrowdown2)
\r
2145 ThrowPower (ob->x+3*PIXGLOBAL,ob->y+16*PIXGLOBAL,dir_South);
\r
2147 ThrowPower (ob->x+12*PIXGLOBAL,ob->y+16*PIXGLOBAL,dir_South);
\r
2148 new->xspeed += ob->xspeed/2;
\r
2149 new->yspeed += ob->yspeed/2;
\r
2153 Quit ("KeenThrow: Bad state!");
\r
2158 =============================================================================
\r
2162 =============================================================================
\r
2166 ============================
\r
2170 ============================
\r
2173 void KillKeen (void)
\r
2177 SD_PlaySound (WAKEUPSND);
\r
2178 player->needtoclip = false;
\r
2179 ChangeState (player,&s_keendie1);
\r
2186 ============================
\r
2190 ============================
\r
2193 unsigned bonuspoints[6] = {100,200,500,1000,2000,5000};
\r
2195 void KeenContact (objtype *ob, objtype *hit)
\r
2197 switch (hit->obclass)
\r
2200 hit->obclass = inertobj;
\r
2201 switch (hit->temp1)
\r
2209 SD_PlaySound (GETPOINTSSND);
\r
2210 hit->shapenum = BONUS100SPR+hit->temp1;
\r
2211 GivePoints (bonuspoints[hit->temp1]);
\r
2212 ChangeState (hit,&s_bonusrise);
\r
2215 SD_PlaySound (EXTRAKEENSND);
\r
2216 hit->shapenum = BONUS1UPSPR;
\r
2217 gamestate.lives++;
\r
2218 ChangeState (hit,&s_bonusrise);
\r
2221 SD_PlaySound (EXTRAKEENSND);
\r
2222 hit->shapenum = BONUSSUPERSPR;
\r
2223 gamestate.lives+=3;
\r
2224 gamestate.flowerpowers+=8;
\r
2225 GivePoints (10000);
\r
2226 ChangeState (hit,&s_bonusrise);
\r
2229 SD_PlaySound (GETPOWERSND);
\r
2230 hit->shapenum = BONUSFLOWERSPR;
\r
2231 gamestate.flowerpowers++;
\r
2232 ChangeState (hit,&s_bonusrise);
\r
2235 SD_PlaySound (GETPOWERSND);
\r
2236 hit->shapenum = BONUSFLOWERUPSPR;
\r
2237 gamestate.flowerpowers+=5;
\r
2238 ChangeState (hit,&s_bonusrise);
\r
2241 SD_PlaySound (GETBOMBSND);
\r
2242 hit->shapenum = BONUSBOMBSPR;
\r
2243 gamestate.boobusbombs++;
\r
2244 gamestate.bombsthislevel++;
\r
2245 ChangeState (hit,&s_bonusrise);
\r
2248 SD_PlaySound (GETKEYSND);
\r
2249 hit->shapenum = BONUSKEYSPR;
\r
2251 ChangeState (hit,&s_bonusrise);
\r
2257 if (gamestate.keys)
\r
2259 if (hit->state != &s_doorraise)
\r
2261 SD_PlaySound (OPENDOORSND);
\r
2263 ChangeState (hit,&s_doorraise);
\r
2268 SD_PlaySound (NOWAYSND);
\r
2269 ClipToSpriteSide (ob,hit);
\r
2273 if (hit->state == &s_taterattack2)
\r
2277 ClipToSpriteSide (ob,hit);
\r
2278 if (!ob->needtoclip) // got pushed off a pole
\r
2280 SD_PlaySound (PLUMMETSND);
\r
2281 ob->needtoclip = true;
\r
2282 ob->xspeed = ob->yspeed = 0;
\r
2283 ChangeState(ob,&s_keenjump3);
\r
2289 ClipToSprite (ob,hit,true);
\r
2292 if (hit->state == &s_broccosmash3 || hit->state == &s_broccosmash4)
\r
2296 if (hit->state == &s_squasherjump2)
\r
2300 ClipToSpriteSide (ob,hit);
\r
2301 if (!ob->needtoclip) // got pushed off a pole
\r
2303 SD_PlaySound (PLUMMETSND);
\r
2304 ob->needtoclip = true;
\r
2305 ob->xspeed = ob->yspeed = 0;
\r
2306 ChangeState(ob,&s_keenjump3);
\r
2313 if (hit->state == &s_grapefall)
\r
2335 =============================================================================
\r
2339 =============================================================================
\r
2344 ============================
\r
2348 ============================
\r
2351 void KeenSimpleReact (objtype *ob)
\r
2358 ============================
\r
2362 ============================
\r
2365 void KeenStandReact (objtype *ob)
\r
2367 if (!ob->hitnorth)
\r
2370 // walked off an edge
\r
2372 SD_PlaySound (PLUMMETSND);
\r
2373 ob->xspeed = ob->xdir*WALKAIRSPEED;
\r
2374 ChangeState (ob,&s_keenjump3);
\r
2378 else if ( (ob->hitnorth & ~7) == 8) // deadly floor!
\r
2387 ============================
\r
2391 ============================
\r
2394 void KeenWalkReact (objtype *ob)
\r
2396 if (!ob->hitnorth)
\r
2399 // walked off an edge
\r
2401 ob->xspeed = ob->xdir*WALKAIRSPEED;
\r
2403 ChangeState (ob,&s_keenjump3);
\r
2407 else if ( (ob->hitnorth & ~7) == 8) // deadly floor!
\r
2413 if (ob->hiteast == 2) // doors
\r
2417 else if (ob->hitwest == 2) // doors
\r
2421 else if (ob->hiteast || ob->hitwest)
\r
2424 // ran into a wall
\r
2427 ob->state = &s_keenstand;
\r
2428 ob->shapenum = ob->xdir == 1 ? s_keenstand.rightshapenum :
\r
2429 s_keenstand.leftshapenum;
\r
2438 ============================
\r
2442 ============================
\r
2445 void KeenAirReact (objtype *ob)
\r
2448 unsigned far *map,mapextra;
\r
2450 if (ob->hiteast || ob->hitwest)
\r
2453 map = mapsegs[1] + (mapbwidthtable[ob->tiletop]/2) + ob->tileleft;
\r
2454 mapextra = mapwidth - (ob->tileright - ob->tileleft+1);
\r
2455 for (y=ob->tiletop;y<=ob->tilebottom;y++,map+=mapextra)
\r
2456 for (x=ob->tileleft;x<=ob->tileright;x++,map++)
\r
2457 if (tinf[SOUTHWALL+*map] == 17) // jumping up through a pole hole
\r
2460 ob->x = ob->tilemidx*TILEGLOBAL - 2*PIXGLOBAL;
\r
2466 if (ob->hitsouth == 17) // jumping up through a pole hole
\r
2471 ob->x = ob->tilemidx*TILEGLOBAL - 2*PIXGLOBAL;
\r
2475 SD_PlaySound (HITHEADSND);
\r
2477 if (ob->hitsouth > 1)
\r
2480 if (ob->yspeed<0) // push away from slopes
\r
2492 if (!(ob->hitnorth == 25 && jumptime)) // KLUDGE to allow jumping off
\r
2494 ob->temp1 = ob->temp2 = 0;
\r
2495 ChangeState (ob,&s_keenstand);
\r
2496 SD_PlaySound (LANDSND);
\r
2504 ============================
\r
2508 ============================
\r
2511 void KeenSlideReact (objtype *ob)
\r
2513 unsigned far *map;
\r
2515 if (ob->hitnorth) // friction slow down
\r
2517 map = mapsegs[2] + (mapbwidthtable[ob->tiletop]/2 + ob->tileleft);
\r
2518 if (!tinf[SOUTHWALL+*map] && !tinf[SOUTHWALL+*(map+1)])
\r
2523 if (ob->hitwest || ob->hiteast || !ob->xspeed)
\r
2524 ChangeState (ob,&s_keengetup);
\r