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
32 #define PLACESPRITE RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum, \
\r
36 void ProjectileReact (objtype *ob);
\r
39 =============================================================================
\r
43 temp1 = chasing player
\r
44 temp2 = nothink time
\r
46 =============================================================================
\r
49 void TaterThink (objtype *ob);
\r
50 void BackupReact (objtype *ob);
\r
52 extern statetype s_taterwalk1;
\r
53 extern statetype s_taterwalk2;
\r
54 extern statetype s_taterwalk3;
\r
55 extern statetype s_taterwalk4;
\r
58 extern statetype s_taterattack1;
\r
59 extern statetype s_taterattack2;
\r
60 extern statetype s_taterattack3;
\r
64 statetype s_taterwalk1 = {TATERTROOPWALKL1SPR,TATERTROOPWALKR1SPR,step,false,
\r
65 true,10, 128,0, TaterThink, NULL, WalkReact, &s_taterwalk2};
\r
66 statetype s_taterwalk2 = {TATERTROOPWALKL2SPR,TATERTROOPWALKR2SPR,step,false,
\r
67 true,10, 128,0, TaterThink, NULL, WalkReact, &s_taterwalk3};
\r
68 statetype s_taterwalk3 = {TATERTROOPWALKL3SPR,TATERTROOPWALKR3SPR,step,false,
\r
69 true,10, 128,0, TaterThink, NULL, WalkReact, &s_taterwalk4};
\r
70 statetype s_taterwalk4 = {TATERTROOPWALKL4SPR,TATERTROOPWALKR4SPR,step,false,
\r
71 true,10, 128,0, TaterThink, NULL, WalkReact, &s_taterwalk1};
\r
73 statetype s_taterattack1= {TATERTROOPLUNGEL1SPR,TATERTROOPLUNGER1SPR,step,false,
\r
74 false,12, 0,0, NULL, NULL, BackupReact, &s_taterattack2};
\r
75 statetype s_taterattack2= {TATERTROOPLUNGEL2SPR,TATERTROOPLUNGER2SPR,step,false,
\r
76 false,20, 0,0, NULL, NULL, DrawReact, &s_taterattack3};
\r
77 statetype s_taterattack3= {TATERTROOPLUNGEL1SPR,TATERTROOPLUNGER1SPR,step,false,
\r
78 false,8, 0,0, NULL, NULL, DrawReact, &s_taterwalk1};
\r
83 ====================
\r
87 ====================
\r
90 void SpawnTater (int tilex, int tiley)
\r
94 new->obclass = taterobj;
\r
95 new->x = tilex<<G_T_SHIFT;
\r
96 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE + 15;
\r
99 NewState (new,&s_taterwalk1);
\r
104 ====================
\r
108 ====================
\r
111 void TaterThink (objtype *ob)
\r
115 if (ob->top > player->bottom || ob->bottom < player->top)
\r
118 if ( ob->xdir == -1 )
\r
120 delta = ob->left - player->right;
\r
121 if (delta > TILEGLOBAL)
\r
123 if (delta < -8*PIXGLOBAL)
\r
128 SD_PlaySound (TATERSWINGSND);
\r
129 ob->state = &s_taterattack1;
\r
134 delta = player->left - ob->right;
\r
135 if (delta > TILEGLOBAL)
\r
137 if (delta < -8*PIXGLOBAL)
\r
142 SD_PlaySound (TATERSWINGSND);
\r
143 ob->state = &s_taterattack1;
\r
150 ====================
\r
154 ====================
\r
157 void BackupReact (objtype *ob)
\r
169 =============================================================================
\r
173 =============================================================================
\r
176 extern statetype s_cartroll1;
\r
177 extern statetype s_cartroll2;
\r
179 void CartReact (objtype *ob);
\r
183 statetype s_cartroll1 = {CANTCARTL1SPR,CANTCARTL1SPR,slide,true,
\r
184 false,5, 32,0, NULL, NULL, CartReact, &s_cartroll2};
\r
185 statetype s_cartroll2 = {CANTCARTL2SPR,CANTCARTL2SPR,slide,true,
\r
186 false,5, 32,0, NULL, NULL, CartReact, &s_cartroll1};
\r
191 ====================
\r
195 ====================
\r
198 void SpawnCart (int tilex, int tiley)
\r
202 new->obclass = cartobj;
\r
203 new->x = tilex<<G_T_SHIFT;
\r
204 new->y = (tiley<<G_T_SHIFT)-3*PIXGLOBAL;
\r
207 new->active = allways;
\r
208 NewState (new,&s_cartroll1);
\r
214 ====================
\r
218 ====================
\r
221 void CartReact (objtype *ob)
\r
225 if (ob->xdir == 1 && ob->hitwest)
\r
229 else if (ob->xdir == -1 && ob->hiteast)
\r
234 map = mapsegs[1] + mapbwidthtable[ob->tilebottom+1]/2;
\r
236 map += ob->tileright;
\r
238 map += ob->tileleft;
\r
240 if ( !tinf[NORTHWALL + *map] )
\r
241 ob->xdir = -ob->xdir;
\r
248 =============================================================================
\r
252 =============================================================================
\r
255 #define FRYXSPEED 40
\r
256 #define FRYYSPEED -20
\r
259 void FrenchyThink (objtype *ob);
\r
260 void FrenchyRunThink (objtype *ob);
\r
261 void FrenchyThrow (objtype *ob);
\r
263 extern statetype s_frenchywalk1;
\r
264 extern statetype s_frenchywalk2;
\r
265 extern statetype s_frenchywalk3;
\r
266 extern statetype s_frenchywalk4;
\r
268 extern statetype s_frenchyrun1;
\r
269 extern statetype s_frenchyrun2;
\r
270 extern statetype s_frenchyrun3;
\r
271 extern statetype s_frenchyrun4;
\r
273 extern statetype s_frenchythrow1;
\r
274 extern statetype s_frenchythrow2;
\r
275 extern statetype s_frenchythrow3;
\r
277 extern statetype s_fry1;
\r
278 extern statetype s_fry2;
\r
282 statetype s_frenchywalk1 = {FRENCHYRUNL1SPR,FRENCHYRUNR1SPR,step,false,
\r
283 true,10, 128,0, FrenchyThink, NULL, WalkReact, &s_frenchywalk2};
\r
284 statetype s_frenchywalk2 = {FRENCHYRUNL2SPR,FRENCHYRUNR2SPR,step,false,
\r
285 true,10, 128,0, FrenchyThink, NULL, WalkReact, &s_frenchywalk3};
\r
286 statetype s_frenchywalk3 = {FRENCHYRUNL3SPR,FRENCHYRUNR3SPR,step,false,
\r
287 true,10, 128,0, FrenchyThink, NULL, WalkReact, &s_frenchywalk4};
\r
288 statetype s_frenchywalk4 = {FRENCHYRUNL4SPR,FRENCHYRUNR4SPR,step,false,
\r
289 true,10, 128,0, FrenchyThink, NULL, WalkReact, &s_frenchywalk1};
\r
291 statetype s_frenchyrun1 = {FRENCHYRUNL1SPR,FRENCHYRUNR1SPR,step,true,
\r
292 true,5, 128,0, FrenchyRunThink, NULL, WalkReact, &s_frenchyrun2};
\r
293 statetype s_frenchyrun2 = {FRENCHYRUNL2SPR,FRENCHYRUNR2SPR,step,true,
\r
294 true,5, 128,0, FrenchyRunThink, NULL, WalkReact, &s_frenchyrun3};
\r
295 statetype s_frenchyrun3 = {FRENCHYRUNL3SPR,FRENCHYRUNR3SPR,step,true,
\r
296 true,5, 128,0, FrenchyRunThink, NULL, WalkReact, &s_frenchyrun4};
\r
297 statetype s_frenchyrun4 = {FRENCHYRUNL4SPR,FRENCHYRUNR4SPR,step,true,
\r
298 true,5, 128,0, FrenchyRunThink, NULL, WalkReact, &s_frenchyrun1};
\r
300 statetype s_frenchythrow1 = {FRENCHYTHROWL1SPR,FRENCHYTHROWR1SPR,step,false,
\r
301 false,10, 0,0, NULL, NULL, DrawReact, &s_frenchythrow2};
\r
302 statetype s_frenchythrow2 = {FRENCHYTHROWL2SPR,FRENCHYTHROWR2SPR,step,false,
\r
303 false,1, 0,0, FrenchyThrow, NULL, DrawReact, &s_frenchythrow3};
\r
304 statetype s_frenchythrow3 = {FRENCHYTHROWL2SPR,FRENCHYTHROWR2SPR,step,false,
\r
305 false,10, -128,0, NULL, NULL, DrawReact, &s_frenchywalk1};
\r
307 statetype s_fry1 = {FRENCHFRY1SPR,FRENCHFRY1SPR,stepthink,false,
\r
308 false,4, 0,0, ProjectileThink, NULL, ProjectileReact, &s_fry2};
\r
309 statetype s_fry2 = {FRENCHFRY2SPR,FRENCHFRY2SPR,stepthink,false,
\r
310 false,4, 0,0, ProjectileThink, NULL, ProjectileReact, &s_fry1};
\r
317 ====================
\r
321 ====================
\r
324 void SpawnFrenchy (int tilex, int tiley)
\r
328 new->obclass = frenchyobj;
\r
329 new->x = tilex<<G_T_SHIFT;
\r
330 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;
\r
333 NewState (new,&s_frenchywalk1);
\r
338 ====================
\r
342 ====================
\r
345 void FrenchyRunThink (objtype *ob)
\r
347 ob->state = &s_frenchywalk1;
\r
352 ====================
\r
356 ====================
\r
359 void FrenchyThrow (objtype *ob)
\r
362 new->obclass = shotobj;
\r
365 new->x = ob->x+24*16;
\r
366 new->y = ob->y+8*16;
\r
371 new->y = ob->y+8*16;
\r
373 new->xdir = ob->xdir;
\r
375 new->xspeed = ob->xdir * FRYXSPEED-(US_RndT()>>4);
\r
376 new->yspeed = FRYYSPEED;
\r
377 new->active = removable;
\r
378 NewState (new,&s_fry1);
\r
385 ====================
\r
389 ====================
\r
392 void FrenchyThink (objtype *ob)
\r
396 if ( abs(ob->y - player->y) > 3*TILEGLOBAL )
\r
399 ob->xdir = -ob->xdir; // turn randomly
\r
403 delta = player->x - ob->x;
\r
405 if (delta < -8*TILEGLOBAL)
\r
410 if (delta < -4*TILEGLOBAL)
\r
414 ob->state = &s_frenchythrow1;
\r
416 else if (delta < 0)
\r
420 ob->state = &s_frenchyrun1;
\r
423 else if (delta < 4*TILEGLOBAL)
\r
427 ob->state = &s_frenchyrun1;
\r
430 else if (delta < 8*TILEGLOBAL)
\r
432 // throw and walk closer
\r
434 ob->state = &s_frenchythrow1;
\r
445 =============================================================================
\r
449 ob->temp1 = direction : 0 = left, 1 = right, 2 = down
\r
451 =============================================================================
\r
454 #define SPITXSPEED 48
\r
455 #define SPITYSPEED -20
\r
457 void MelonSpitThink (objtype *ob);
\r
458 void ProjectileReact (objtype *ob);
\r
460 extern statetype s_melonside;
\r
461 extern statetype s_melonsidespit;
\r
462 extern statetype s_melonsidespit2;
\r
464 extern statetype s_melondown;
\r
465 extern statetype s_melondownspit;
\r
466 extern statetype s_melondownspit2;
\r
468 extern statetype s_melonseed1;
\r
469 extern statetype s_melonseed2;
\r
471 extern statetype s_melonseedd1;
\r
472 extern statetype s_melonseedd2;
\r
476 statetype s_melonside = {MELONLIPSL1SPR,MELONLIPSR1SPR,step,false,
\r
477 false,200, 0,0, NULL, NULL, DrawReact, &s_melonsidespit};
\r
478 statetype s_melonsidespit= {MELONLIPSL2SPR,MELONLIPSR2SPR,step,false,
\r
479 false,6, 0,0, MelonSpitThink, NULL, DrawReact, &s_melonsidespit2};
\r
480 statetype s_melonsidespit2= {MELONLIPSL2SPR,MELONLIPSR2SPR,step,false,
\r
481 false,6, 0,0, NULL, NULL, DrawReact, &s_melonside};
\r
483 statetype s_melondown = {MELONLIPSD1SPR,MELONLIPSD1SPR,step,false,
\r
484 false,200, 0,0, NULL, NULL, DrawReact, &s_melondownspit};
\r
485 statetype s_melondownspit = {MELONLIPSD2SPR,MELONLIPSD2SPR,step,false,
\r
486 false,6, 0,0, MelonSpitThink, NULL, DrawReact, &s_melondownspit2};
\r
487 statetype s_melondownspit2 = {MELONLIPSD2SPR,MELONLIPSD2SPR,step,false,
\r
488 false,6, 0,0, NULL, NULL, DrawReact, &s_melondown};
\r
490 statetype s_melonseed1 = {MELONSEEDL1SPR,MELONSEEDR1SPR,think,false,
\r
491 false,4, 0,0, ProjectileThink, NULL, ProjectileReact, &s_melonseed2};
\r
492 statetype s_melonseed2 = {MELONSEEDL2SPR,MELONSEEDR2SPR,think,false,
\r
493 false,4, 0,0, ProjectileThink, NULL, ProjectileReact, &s_melonseed1};
\r
495 statetype s_melonseedd1 = {MELONSEEDD1SPR,MELONSEEDD1SPR,stepthink,false,
\r
496 false,4, 0,0, ProjectileThink, NULL, ProjectileReact, &s_melonseedd2};
\r
497 statetype s_melonseedd2 = {MELONSEEDD2SPR,MELONSEEDD2SPR,stepthink,false,
\r
498 false,4, 0,0, ProjectileThink, NULL, ProjectileReact, &s_melonseedd1};
\r
503 ====================
\r
507 ====================
\r
510 void SpawnMelon (int tilex, int tiley,int dir)
\r
514 new->obclass = melonobj;
\r
515 new->x = tilex<<G_T_SHIFT;
\r
516 new->y = tiley<<G_T_SHIFT;
\r
522 NewState (new,&s_melonside);
\r
524 NewState (new,&s_melondown);
\r
526 new->ticcount = US_RndT()>>1;
\r
532 ====================
\r
536 ====================
\r
539 void MelonSpitThink (objtype *ob)
\r
542 new->obclass = shotobj;
\r
546 new->x = ob->x+24*16;
\r
547 new->y = ob->y+8*16;
\r
548 new->xdir = ob->xdir;
\r
550 new->xspeed = -SPITXSPEED-(US_RndT()>>4);
\r
551 new->yspeed = SPITYSPEED;
\r
552 NewState (new,&s_melonseed1);
\r
556 new->y = ob->y+8*16;
\r
557 new->xdir = ob->xdir;
\r
559 new->xspeed = SPITXSPEED+(US_RndT()>>4);
\r
560 new->yspeed = SPITYSPEED;
\r
561 NewState (new,&s_melonseed1);
\r
564 new->x = ob->x+8*16;
\r
565 new->y = ob->y+24*16;
\r
567 new->yspeed = -SPITYSPEED;
\r
568 NewState (new,&s_melonseedd1);
\r
572 new->active = removable;
\r
576 ============================
\r
580 ============================
\r
583 void ProjectileReact (objtype *ob)
\r
585 unsigned wall,absx,absy,angle,newangle;
\r
586 unsigned long speed;
\r
589 if (ob->hiteast || ob->hitwest)
\r
590 ob->xspeed= -ob->xspeed/2;
\r
593 ob->yspeed= -ob->yspeed/2;
\r
595 wall = ob->hitnorth;
\r
598 if (ob->yspeed < 0)
\r
601 absx = abs(ob->xspeed);
\r
605 if (absx>absy*2) // 22 degrees
\r
608 speed = absx*286; // x*sqrt(5)/2
\r
613 speed = absx*362; // x*sqrt(2)
\r
618 if (absy>absx*2) // 90 degrees
\r
625 angle = 2; // 67 degrees
\r
626 speed = absy*286; // y*sqrt(5)/2
\r
629 if (ob->xspeed > 0)
\r
633 newangle = bounceangle[ob->hitnorth][angle];
\r
637 ob->xspeed = speed / 286;
\r
638 ob->yspeed = -ob->xspeed / 2;
\r
641 ob->xspeed = speed / 362;
\r
642 ob->yspeed = -ob->xspeed;
\r
645 ob->yspeed = -(speed / 286);
\r
646 ob->xspeed = -ob->yspeed / 2;
\r
652 ob->yspeed = -(speed / 256);
\r
655 ob->yspeed = -(speed / 286);
\r
656 ob->xspeed = ob->yspeed / 2;
\r
659 ob->xspeed = ob->yspeed = -(speed / 362);
\r
662 ob->xspeed = -(speed / 286);
\r
663 ob->yspeed = ob->xspeed / 2;
\r
667 ob->xspeed = -(speed / 286);
\r
668 ob->yspeed = -ob->xspeed / 2;
\r
671 ob->xspeed = -(speed / 362);
\r
672 ob->yspeed = -ob->xspeed;
\r
675 ob->yspeed = speed / 286;
\r
676 ob->xspeed = -ob->yspeed / 2;
\r
682 ob->yspeed = -(speed / 256);
\r
685 ob->yspeed = speed / 286;
\r
686 ob->xspeed = ob->yspeed / 2;
\r
689 ob->xspeed = speed / 362;
\r
690 ob->yspeed = speed / 362;
\r
693 ob->xspeed = speed / 286;
\r
694 ob->yspeed = ob->xspeed / 2;
\r
698 if (speed < 256*16)
\r
704 =============================================================================
\r
708 =============================================================================
\r
711 #define SPDSQUASHLEAPY 50
\r
714 void SquasherThink (objtype *ob);
\r
715 void SquasherJumpReact (objtype *ob);
\r
717 extern statetype s_squasherwalk1;
\r
718 extern statetype s_squasherwalk2;
\r
720 extern statetype s_squasherjump1;
\r
721 extern statetype s_squasherjump2;
\r
723 extern statetype s_squasherwait;
\r
727 statetype s_squasherwalk1 = {SQUASHERWALKL1SPR,SQUASHERWALKR1SPR,step,false,
\r
728 true,10, 128,0, SquasherThink, NULL, WalkReact, &s_squasherwalk2};
\r
729 statetype s_squasherwalk2 = {SQUASHERWALKL2SPR,SQUASHERWALKR2SPR,step,false,
\r
730 true,10, 128,0, SquasherThink, NULL, WalkReact, &s_squasherwalk1};
\r
732 statetype s_squasherjump1 = {SQUASHERJUMPL1SPR,SQUASHERJUMPR1SPR,stepthink,false,
\r
733 false,20, 0,0, ProjectileThink, NULL, SquasherJumpReact, &s_squasherjump2};
\r
734 statetype s_squasherjump2 = {SQUASHERJUMPL2SPR,SQUASHERJUMPR2SPR,think,false,
\r
735 false,0, 0,0, ProjectileThink, NULL, SquasherJumpReact, NULL};
\r
737 statetype s_squasherwait = {SQUASHERJUMPL2SPR,SQUASHERJUMPR2SPR,step,false,
\r
738 false,10, 0,0, ProjectileThink, NULL, DrawReact, &s_squasherwalk1};
\r
743 ====================
\r
747 ====================
\r
750 void SpawnSquasher (int tilex, int tiley)
\r
754 new->obclass = squashobj;
\r
755 new->x = tilex<<G_T_SHIFT;
\r
756 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;
\r
759 NewState (new,&s_squasherwalk1);
\r
763 ====================
\r
767 ====================
\r
770 void SquasherThink (objtype *ob)
\r
774 if ( abs(ob->y - player->y) > 3*TILEGLOBAL )
\r
777 ob->xdir = -ob->xdir; // turn randomly
\r
782 delta = player->x - ob->x;
\r
784 if ( ob->xdir == -1 )
\r
786 if (delta < -6*TILEGLOBAL)
\r
788 if (delta > 8*PIXGLOBAL)
\r
796 if (delta > 6*TILEGLOBAL)
\r
798 if (delta < -8*PIXGLOBAL)
\r
805 ob->yspeed = -SPDSQUASHLEAPY;
\r
806 ob->xspeed = delta/60;
\r
807 ob->state = &s_squasherjump1;
\r
811 ====================
\r
813 = SquasherJumpReact
\r
815 ====================
\r
818 void SquasherJumpReact (objtype *ob)
\r
824 ChangeState (ob,&s_squasherwait);
\r
831 =============================================================================
\r
835 temp4 = pole x coordinate
\r
837 =============================================================================
\r
840 void ApelThink (objtype *ob);
\r
841 void ApelClimbThink (objtype *ob);
\r
842 void ApelSlideThink (objtype *ob);
\r
843 void ApelFallThink (objtype *ob);
\r
845 void ApelClimbReact (objtype *ob);
\r
846 void ApelSlideReact (objtype *ob);
\r
847 void ApelFallReact (objtype *ob);
\r
849 extern statetype s_apelwalk1;
\r
850 extern statetype s_apelwalk2;
\r
851 extern statetype s_apelwalk3;
\r
853 extern statetype s_apelclimb1;
\r
854 extern statetype s_apelclimb2;
\r
856 extern statetype s_apelslide1;
\r
857 extern statetype s_apelslide2;
\r
858 extern statetype s_apelslide3;
\r
859 extern statetype s_apelslide4;
\r
861 extern statetype s_apelfall;
\r
865 statetype s_apelwalk1 = {APELWALKL1SPR,APELWALKR1SPR,step,false,
\r
866 true,10, 128,0, ApelThink, NULL, WalkReact, &s_apelwalk2};
\r
867 statetype s_apelwalk2 = {APELWALKL2SPR,APELWALKR2SPR,step,false,
\r
868 true,10, 128,0, ApelThink, NULL, WalkReact, &s_apelwalk3};
\r
869 statetype s_apelwalk3 = {APELWALKL3SPR,APELWALKR3SPR,step,false,
\r
870 true,10, 128,0, ApelThink, NULL, WalkReact, &s_apelwalk1};
\r
872 statetype s_apelclimb1 = {APELSHINNY1SPR,APELSHINNY1SPR,slide,false,
\r
873 false,6, 0,-16, ApelClimbThink, NULL, ApelClimbReact, &s_apelclimb2};
\r
874 statetype s_apelclimb2 = {APELSHINNY2SPR,APELSHINNY2SPR,slide,false,
\r
875 false,6, 0,-16, ApelClimbThink, NULL, ApelClimbReact, &s_apelclimb1};
\r
877 statetype s_apelslide1 = {APELSLIDE1SPR,APELSLIDE1SPR,slide,false,
\r
878 false,6, 0,16, ApelSlideThink, NULL, ApelFallReact, &s_apelslide2};
\r
879 statetype s_apelslide2 = {APELSLIDE2SPR,APELSLIDE2SPR,slide,false,
\r
880 false,6, 0,16, ApelSlideThink, NULL, ApelFallReact, &s_apelslide3};
\r
881 statetype s_apelslide3 = {APELSLIDE3SPR,APELSLIDE3SPR,slide,false,
\r
882 false,6, 0,16, ApelSlideThink, NULL, ApelFallReact, &s_apelslide4};
\r
883 statetype s_apelslide4 = {APELSLIDE4SPR,APELSLIDE4SPR,slide,false,
\r
884 false,6, 0,16, ApelSlideThink, NULL, ApelFallReact, &s_apelslide1};
\r
886 statetype s_apelfall = {APELWALKL1SPR,APELWALKR1SPR,think,false,
\r
887 false,0, 0,0, ProjectileThink, NULL, ApelFallReact, NULL};
\r
893 ====================
\r
897 ====================
\r
900 void SpawnApel (int tilex, int tiley)
\r
904 new->obclass = apelobj;
\r
905 new->x = tilex<<G_T_SHIFT;
\r
906 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;
\r
909 NewState (new,&s_apelwalk1);
\r
914 ====================
\r
918 ====================
\r
921 void ApelThink (objtype *ob)
\r
926 if (ob->top > player->bottom || ob->bottom < player->top)
\r
929 // try to climb a pole to reach player
\r
931 if (ob->y < player->y)
\r
932 y = ob->tilebottom;
\r
936 map = (unsigned _seg *)mapsegs[1]+
\r
937 mapbwidthtable[y]/2 + ob->tilemidx;
\r
939 if ((tinf[INTILE+*map]&0x7f) == 1)
\r
941 ob->xmove = (ob->tilemidx<<G_T_SHIFT) - ob->x;
\r
943 ob->temp4 = ob->tilemidx; // for future reference
\r
944 ob->needtoclip = false; // can climb through pole holes
\r
945 if (ob->y < player->y)
\r
946 ob->state = &s_apelslide1;
\r
948 ob->state = &s_apelclimb1;
\r
953 if (US_RndT()>32) // don't turn around all the time
\r
956 if (ob->x < player->x)
\r
965 ====================
\r
969 ====================
\r
972 void ApelClimbThink (objtype *ob)
\r
976 map = (unsigned _seg *)mapsegs[1]+
\r
977 mapbwidthtable[ob->tiletop]/2 + ob->temp4;
\r
979 if ((tinf[INTILE+*map]&0x7f) != 1)
\r
981 ob->needtoclip = true;
\r
982 ob->state = &s_apelfall;
\r
988 ====================
\r
992 ====================
\r
995 void ApelSlideThink (objtype *ob)
\r
999 map = (unsigned _seg *)mapsegs[1]+
\r
1000 mapbwidthtable[ob->tilebottom]/2 + ob->temp4;
\r
1002 if ((tinf[INTILE+*map]&0x7f) != 1)
\r
1004 ob->needtoclip = true;
\r
1005 ob->state = &s_apelfall;
\r
1011 ====================
\r
1015 ====================
\r
1018 void ApelClimbReact (objtype *ob)
\r
1021 ChangeState (ob,&s_apelfall);
\r
1027 ====================
\r
1031 ====================
\r
1034 void ApelFallReact (objtype *ob)
\r
1037 ChangeState (ob,&s_apelwalk1);
\r
1043 =============================================================================
\r
1047 =============================================================================
\r
1050 void PeaBrainThink (objtype *ob);
\r
1051 void PeaFlyReact (objtype *ob);
\r
1053 extern statetype s_peabrainfly;
\r
1055 extern statetype s_peabrainwalk1;
\r
1056 extern statetype s_peabrainwalk2;
\r
1057 extern statetype s_peabrainwalk3;
\r
1058 extern statetype s_peabrainwalk4;
\r
1062 statetype s_peabrainfly = {PEABRAINWALKL1SPR,PEABRAINWALKR1SPR,think,false,
\r
1063 false,0, 0,0, ProjectileThink, NULL, PeaFlyReact, NULL};
\r
1065 statetype s_peabrainwalk1 = {PEABRAINWALKL1SPR,PEABRAINWALKR1SPR,step,false,
\r
1066 true,10, 128,0, PeaBrainThink, NULL, WalkReact, &s_peabrainwalk2};
\r
1067 statetype s_peabrainwalk2 = {PEABRAINWALKL2SPR,PEABRAINWALKR2SPR,step,false,
\r
1068 true,10, 128,0, PeaBrainThink, NULL, WalkReact, &s_peabrainwalk3};
\r
1069 statetype s_peabrainwalk3 = {PEABRAINWALKL3SPR,PEABRAINWALKR3SPR,step,false,
\r
1070 true,10, 128,0, PeaBrainThink, NULL, WalkReact, &s_peabrainwalk4};
\r
1071 statetype s_peabrainwalk4 = {PEABRAINWALKL4SPR,PEABRAINWALKR4SPR,step,false,
\r
1072 true,10, 128,0, PeaBrainThink, NULL, WalkReact, &s_peabrainwalk1};
\r
1077 ====================
\r
1081 ====================
\r
1084 void SpawnPeaBrain (int tilex, int tiley)
\r
1086 GetNewObj (false);
\r
1088 new->obclass = peabrainobj;
\r
1089 new->x = tilex<<G_T_SHIFT;
\r
1090 new->y = tiley<<G_T_SHIFT;
\r
1091 NewState (new,&s_peabrainwalk1);
\r
1095 ====================
\r
1099 ====================
\r
1102 void PeaBrainThink (objtype *ob)
\r
1109 ====================
\r
1113 ====================
\r
1116 void PeaFlyReact (objtype *ob)
\r
1119 ChangeState (ob,&s_peabrainwalk1);
\r
1126 =============================================================================
\r
1130 temp1 = number of peas spit
\r
1132 =============================================================================
\r
1135 #define MAXPEASPIT 4
\r
1137 #define PEAXSPEED 48
\r
1138 #define PEAYSPEED -20
\r
1141 void PeaPodThink (objtype *ob);
\r
1142 void SpitPeaBrain (objtype *ob);
\r
1144 extern statetype s_peapodwalk1;
\r
1145 extern statetype s_peapodwalk2;
\r
1146 extern statetype s_peapodwalk3;
\r
1147 extern statetype s_peapodwalk4;
\r
1149 extern statetype s_peapodspit1;
\r
1150 extern statetype s_peapodspit2;
\r
1154 statetype s_peapodwalk1 = {PEAPODRUNL1SPR,PEAPODRUNR1SPR,step,false,
\r
1155 true,10, 128,0, PeaPodThink, NULL, WalkReact, &s_peapodwalk2};
\r
1156 statetype s_peapodwalk2 = {PEAPODRUNL2SPR,PEAPODRUNR2SPR,step,false,
\r
1157 true,10, 128,0, PeaPodThink, NULL, WalkReact, &s_peapodwalk3};
\r
1158 statetype s_peapodwalk3 = {PEAPODRUNL3SPR,PEAPODRUNR3SPR,step,false,
\r
1159 true,10, 128,0, PeaPodThink, NULL, WalkReact, &s_peapodwalk4};
\r
1160 statetype s_peapodwalk4 = {PEAPODRUNL4SPR,PEAPODRUNR4SPR,step,false,
\r
1161 true,10, 128,0, PeaPodThink, NULL, WalkReact, &s_peapodwalk1};
\r
1163 statetype s_peapodspit1 = {PEAPODSPITLSPR,PEAPODSPITRSPR,step,false,
\r
1164 true,30, 0,0, SpitPeaBrain, NULL, DrawReact, &s_peapodspit2};
\r
1165 statetype s_peapodspit2 = {PEAPODSPITLSPR,PEAPODSPITRSPR,step,false,
\r
1166 true,30, 0,0, NULL, NULL, DrawReact, &s_peapodwalk1};
\r
1171 ====================
\r
1175 ====================
\r
1178 void SpawnPeaPod (int tilex, int tiley)
\r
1180 GetNewObj (false);
\r
1182 new->obclass = peapodobj;
\r
1183 new->x = tilex<<G_T_SHIFT;
\r
1184 new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;
\r
1187 NewState (new,&s_peapodwalk1);
\r
1191 ====================
\r
1195 ====================
\r
1198 void SpitPeaBrain (objtype *ob)
\r
1201 new->obclass = peabrainobj;
\r
1202 if (ob->xdir == 1)
\r
1204 new->x = ob->x+8*16;
\r
1205 new->y = ob->y+8*16;
\r
1210 new->y = ob->y+8*16;
\r
1212 new->xdir = ob->xdir;
\r
1214 new->xspeed = ob->xdir * PEAXSPEED-(US_RndT()>>4);
\r
1215 new->yspeed = PEAYSPEED;
\r
1216 NewState (new,&s_peabrainfly);
\r
1222 ====================
\r
1226 ====================
\r
1229 void PeaPodThink (objtype *ob)
\r
1233 if ( abs(ob->y - player->y) > 3*TILEGLOBAL )
\r
1236 if (player->x < ob->x && ob->xdir == 1)
\r
1239 if (player->x > ob->x && ob->xdir == -1)
\r
1242 if (US_RndT()<8 && ob->temp1 < MAXPEASPIT)
\r
1245 ob->state = &s_peapodspit1;
\r
1252 =============================================================================
\r
1256 temp4 = hit points
\r
1258 =============================================================================
\r
1261 #define PREFRAGTHINK 60
\r
1262 #define POSTFRAGTHINK 60
\r
1264 #define SPDBOOBUSJUMP 60
\r
1265 #define SPDBOOBUSRUNJUMP 24
\r
1267 void BoobusThink (objtype *ob);
\r
1268 void FinishThink (objtype *ob);
\r
1269 void FragThink (objtype *ob);
\r
1270 void BoobusGroundReact (objtype *ob);
\r
1271 void BoobusAirReact (objtype *ob);
\r
1273 extern statetype s_boobuswalk1;
\r
1274 extern statetype s_boobuswalk2;
\r
1275 extern statetype s_boobuswalk3;
\r
1276 extern statetype s_boobuswalk4;
\r
1278 extern statetype s_boobusjump;
\r
1280 extern statetype s_deathwait1;
\r
1281 extern statetype s_deathwait2;
\r
1282 extern statetype s_deathwait3;
\r
1283 extern statetype s_deathboom1;
\r
1284 extern statetype s_deathboom2;
\r
1285 extern statetype s_deathboom3;
\r
1286 extern statetype s_deathboom4;
\r
1287 extern statetype s_deathboom5;
\r
1288 extern statetype s_deathboom6;
\r
1292 statetype s_boobuswalk1 = {BOOBUSWALKL1SPR,BOOBUSWALKR1SPR,step,false,
\r
1293 true,10, 128,0, BoobusThink, NULL, BoobusGroundReact, &s_boobuswalk2};
\r
1294 statetype s_boobuswalk2 = {BOOBUSWALKL2SPR,BOOBUSWALKR2SPR,step,false,
\r
1295 true,10, 128,0, BoobusThink, NULL, BoobusGroundReact, &s_boobuswalk3};
\r
1296 statetype s_boobuswalk3 = {BOOBUSWALKL3SPR,BOOBUSWALKR3SPR,step,false,
\r
1297 true,10, 128,0, BoobusThink, NULL, BoobusGroundReact, &s_boobuswalk4};
\r
1298 statetype s_boobuswalk4 = {BOOBUSWALKL4SPR,BOOBUSWALKR4SPR,step,false,
\r
1299 true,10, 128,0, BoobusThink, NULL, BoobusGroundReact, &s_boobuswalk1};
\r
1301 statetype s_boobusjump = {BOOBUSJUMPSPR,BOOBUSJUMPSPR,think,false,
\r
1302 false,0, 0,0, ProjectileThink, NULL, BoobusAirReact, NULL};
\r
1304 statetype s_boobusdie = {BOOBUSJUMPSPR,BOOBUSJUMPSPR,step,false,
\r
1305 false,4, 0,0, FragThink, NULL, DrawReact, &s_boobusdie};
\r
1306 statetype s_boobusdie2 = {NULL,NULL,step,false,
\r
1307 false,4, 0,0, FragThink, NULL, NULL, &s_boobusdie2};
\r
1308 statetype s_boobusdie3 = {NULL,NULL,step,false,
\r
1309 false,250, 0,0, FinishThink, NULL, NULL, NULL};
\r
1311 statetype s_deathboom1 = {BOOBUSBOOM1SPR,BOOBUSBOOM1SPR,step,false,
\r
1312 false,20, 0,0, ProjectileThink, NULL, DrawReact3, &s_deathboom2};
\r
1313 statetype s_deathboom2 = {BOOBUSBOOM2SPR,BOOBUSBOOM2SPR,step,false,
\r
1314 false,20, 0,0, ProjectileThink, NULL, DrawReact3, &s_deathboom3};
\r
1315 statetype s_deathboom3 = {POOF1SPR,POOF1SPR,step,false,
\r
1316 false,40, 0,0, ProjectileThink, NULL, DrawReact3, &s_deathboom4};
\r
1317 statetype s_deathboom4 = {POOF2SPR,POOF2SPR,step,false,
\r
1318 false,30, 0,0, ProjectileThink, NULL, DrawReact3, &s_deathboom5};
\r
1319 statetype s_deathboom5 = {POOF3SPR,POOF3SPR,step,false,
\r
1320 false,30, 0,0, ProjectileThink, NULL, DrawReact3, &s_deathboom6};
\r
1321 statetype s_deathboom6 = {POOF4SPR,POOF4SPR,step,false,
\r
1322 false,30, 0,0, ProjectileThink, NULL, DrawReact3, NULL};
\r
1328 ====================
\r
1332 ====================
\r
1335 void SpawnBoobus (int tilex, int tiley)
\r
1337 GetNewObj (false);
\r
1339 new->obclass = boobusobj;
\r
1340 new->x = tilex<<G_T_SHIFT;
\r
1341 new->y = (tiley<<G_T_SHIFT)-11*BLOCKSIZE;
\r
1343 NewState (new,&s_boobuswalk1);
\r
1344 new->temp4 = 12; // hit points
\r
1349 ===================
\r
1353 ===================
\r
1356 void FragThink (objtype *ob)
\r
1358 if (++ob->temp1 == PREFRAGTHINK)
\r
1359 ob->state = &s_boobusdie2;
\r
1360 if (++ob->temp1 == POSTFRAGTHINK)
\r
1362 RF_RemoveSprite (&ob->sprite);
\r
1363 ob->state = &s_boobusdie3;
\r
1366 SD_PlaySound (BOMBBOOMSND);
\r
1368 new->x = ob->x-BLOCKSIZE + 5*US_RndT();
\r
1369 new->y = ob->y-BLOCKSIZE + 5*US_RndT();
\r
1370 new->xspeed = 0; //US_RndT()/4-32;
\r
1371 new->yspeed = 0; //US_RndT()/4-32;
\r
1372 US_RndT(); // keep rnd from even wrapping
\r
1373 ChangeState (new,&s_deathboom1);
\r
1378 ===================
\r
1382 ===================
\r
1385 void FinishThink (objtype *ob)
\r
1387 playstate = victorious;
\r
1389 SD_PlaySound (BOOBUSGONESND);
\r
1394 ====================
\r
1398 ====================
\r
1401 void BoobusThink (objtype *ob)
\r
1404 boolean inline = false;
\r
1406 if (ob->left > player->right)
\r
1408 else if (ob->right < player->left)
\r
1413 if (player->top < ob->bottom && player->bottom > ob->top)
\r
1415 // on same level as player, so charge!
\r
1420 // above or below player, so get directly in line and jump
\r
1423 if (ob->y < player->y)
\r
1426 move = PIXGLOBAL*8;
\r
1428 ob->bottom += move;
\r
1430 ob->state = &s_boobusjump;
\r
1431 ob->yspeed = ob->xmove = ob->xspeed = ob->ymove = 0;
\r
1436 ob->state = &s_boobusjump;
\r
1437 ob->yspeed = -SPDBOOBUSJUMP;
\r
1446 ====================
\r
1448 = BoobusGroundReact
\r
1450 ====================
\r
1453 void BoobusGroundReact (objtype *ob)
\r
1455 if (ob->xdir == 1 && ob->hitwest)
\r
1457 ob->x -= ob->xmove;
\r
1459 ob->nothink = US_RndT()>>5;
\r
1460 ChangeState (ob,ob->state);
\r
1462 else if (ob->xdir == -1 && ob->hiteast)
\r
1464 ob->x -= ob->xmove;
\r
1466 ob->nothink = US_RndT()>>5;
\r
1467 ChangeState (ob,ob->state);
\r
1469 else if (!ob->hitnorth)
\r
1471 if (ob->bottom >= player->bottom)
\r
1474 ob->x -= ob->xmove;
\r
1475 ob->y -= ob->ymove;
\r
1476 ob->yspeed = -SPDBOOBUSJUMP;
\r
1477 ob->xspeed = ob->xdir * SPDBOOBUSRUNJUMP;
\r
1482 ob->xspeed = ob->yspeed = 0;
\r
1484 ChangeState (ob,&s_boobusjump);
\r
1493 ====================
\r
1497 ====================
\r
1500 void BoobusAirReact (objtype *ob)
\r
1506 ChangeState (ob,&s_boobuswalk1);
\r