1 /* Catacomb 3-D Source Code
\r
2 * Copyright (C) 1993-2014 Flat Rock Software
\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
34 =============================================================================
\r
38 =============================================================================
\r
44 =============================================================================
\r
48 =============================================================================
\r
52 dirtype dirtable[9] = {northwest,north,northeast,west,nodir,east,
\r
53 southwest,south,southeast};
\r
58 =============================================================================
\r
62 =============================================================================
\r
65 extern statetype s_boltbonus2;
\r
66 extern statetype s_nukebonus2;
\r
68 statetype s_boltbonus = {BOLTOBJPIC,8,NULL,&s_boltbonus2};
\r
69 statetype s_boltbonus2 = {BOLTOBJ2PIC,8,NULL,&s_boltbonus};
\r
71 statetype s_nukebonus = {NUKEOBJPIC,8,NULL,&s_nukebonus2};
\r
72 statetype s_nukebonus2 = {NUKEOBJ2PIC,8,NULL,&s_nukebonus};
\r
74 statetype s_potionbonus = {POTIONOBJPIC,0,NULL,&s_potionbonus};
\r
75 statetype s_rkeybonus = {RKEYOBJPIC,0,NULL,&s_rkeybonus};
\r
76 statetype s_ykeybonus = {YKEYOBJPIC,0,NULL,&s_ykeybonus};
\r
77 statetype s_gkeybonus = {GKEYOBJPIC,0,NULL,&s_gkeybonus};
\r
78 statetype s_bkeybonus = {BKEYOBJPIC,0,NULL,&s_bkeybonus};
\r
79 statetype s_scrollbonus = {SCROLLOBJPIC,0,NULL,&s_scrollbonus};
\r
80 statetype s_chestbonus = {CHESTOBJPIC,0,NULL,&s_chestbonus};
\r
81 statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};
\r
91 void SpawnBonus (int tilex, int tiley, int number)
\r
95 if (number == B_BOLT)
\r
96 state = &s_boltbonus;
\r
97 else if (number == B_NUKE)
\r
98 state = &s_nukebonus;
\r
99 else if (number == B_POTION)
\r
100 state = &s_potionbonus;
\r
101 else if (number == B_RKEY)
\r
102 state = &s_rkeybonus;
\r
103 else if (number == B_YKEY)
\r
104 state = &s_ykeybonus;
\r
105 else if (number == B_GKEY)
\r
106 state = &s_gkeybonus;
\r
107 else if (number == B_BKEY)
\r
108 state = &s_bkeybonus;
\r
109 else if (number >= B_SCROLL1 && number <= B_SCROLL8)
\r
110 state = &s_scrollbonus;
\r
111 else if (number == B_CHEST)
\r
112 state = &s_chestbonus;
\r
113 else if (number == B_GOAL)
\r
114 state = &s_goalbonus;
\r
116 SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);
\r
117 new->tileobject = true;
\r
118 new->temp1 = number;
\r
119 new->obclass = bonusobj;
\r
120 new->shootable = false;
\r
125 =============================================================================
\r
129 =============================================================================
\r
133 void T_WallDie (objtype *ob);
\r
135 extern statetype s_walldie1;
\r
136 extern statetype s_walldie2;
\r
137 extern statetype s_walldie3;
\r
138 extern statetype s_walldie4;
\r
139 extern statetype s_walldie5;
\r
140 extern statetype s_walldie6;
\r
142 statetype s_walldie1 = {0,20,NULL,&s_walldie2};
\r
143 statetype s_walldie2 = {0,-1,T_WallDie,&s_walldie3};
\r
144 statetype s_walldie3 = {0,20,NULL,&s_walldie4};
\r
145 statetype s_walldie4 = {0,-1,T_WallDie,&s_walldie5};
\r
146 statetype s_walldie5 = {0,20,NULL,&s_walldie6};
\r
147 statetype s_walldie6 = {0,-1,T_WallDie,NULL};
\r
157 void ExplodeWall (int tilex, int tiley)
\r
159 SpawnNewObj (tilex,tiley,&s_walldie1,0);
\r
160 new->obclass = inertobj;
\r
161 new->active = true;
\r
162 (unsigned)actorat[new->tilex][new->tiley] = tilemap[new->tilex][new->tiley] =
\r
163 *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = WALLEXP;
\r
175 void T_WallDie (objtype *ob)
\r
177 unsigned tile,other;
\r
179 if (++ob->temp1 == 3)
\r
182 tile = WALLEXP-1 + ob->temp1;
\r
184 (unsigned)actorat[ob->tilex][ob->tiley] = tilemap[ob->tilex][ob->tiley] =
\r
185 *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex) = tile;
\r
187 if (ob->temp1 == 1)
\r
190 // blow up nearby walls
\r
192 other = tilemap[ob->tilex-1][ob->tiley];
\r
193 if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
\r
194 ExplodeWall (ob->tilex-1,ob->tiley);
\r
195 other = tilemap[ob->tilex+1][ob->tiley];
\r
196 if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
\r
197 ExplodeWall (ob->tilex+1,ob->tiley);
\r
198 other = tilemap[ob->tilex][ob->tiley-1];
\r
199 if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
\r
200 ExplodeWall (ob->tilex,ob->tiley-1);
\r
201 other = tilemap[ob->tilex][ob->tiley+1];
\r
202 if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
\r
203 ExplodeWall (ob->tilex,ob->tiley+1);
\r
209 =============================================================================
\r
213 =============================================================================
\r
216 void T_Gate (objtype *ob);
\r
218 extern statetype s_gate1;
\r
219 extern statetype s_gate2;
\r
220 extern statetype s_gate3;
\r
221 extern statetype s_gate4;
\r
223 extern statetype s_fgate1;
\r
224 extern statetype s_fgate2;
\r
225 extern statetype s_fgate3;
\r
226 extern statetype s_fgate4;
\r
228 statetype s_gate1 = {WARP1PIC,12,T_Gate,&s_gate2};
\r
229 statetype s_gate2 = {WARP2PIC,12,T_Gate,&s_gate3};
\r
230 statetype s_gate3 = {WARP3PIC,12,T_Gate,&s_gate4};
\r
231 statetype s_gate4 = {WARP4PIC,12,T_Gate,&s_gate1};
\r
233 statetype s_fgate1 = {WARP1PIC,6,T_Gate,&s_fgate2};
\r
234 statetype s_fgate2 = {WARP2PIC,6,T_Gate,&s_fgate3};
\r
235 statetype s_fgate3 = {WARP3PIC,6,T_Gate,&s_fgate4};
\r
236 statetype s_fgate4 = {WARP4PIC,6,T_Gate,&s_fgate1};
\r
246 void SpawnWarp (int tilex, int tiley, int type)
\r
249 SpawnNewObj (tilex,tiley,&s_fgate1,TILEGLOBAL/3);
\r
251 SpawnNewObj (tilex,tiley,&s_gate1,TILEGLOBAL/3);
\r
252 new->obclass = gateobj;
\r
265 #define STATUSCOLOR 4
\r
267 void T_Gate (objtype *ob)
\r
273 if (CheckHandAttack (ob) && !playstate)
\r
280 VW_Bar (26,4,232,9,STATUSCOLOR); // clear text description
\r
282 IN_ClearKeysDown ();
\r
286 // teleport inside level
\r
288 for (check=player->next;check;check=check->next)
\r
289 if (check->obclass==gateobj && check->temp1==ob->temp1 &&
\r
292 player->x = check->x;
\r
293 player->y = check->y;
\r
294 Thrust (player->angle,TILEGLOBAL/2); // move forwards
\r
295 Thrust (player->angle,TILEGLOBAL/2); // move forwards
\r
296 Thrust (player->angle,TILEGLOBAL/2); // move forwards
\r
303 // teleport out of level
\r
305 playstate = ex_warped;
\r
306 spot = *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex)-NAMESTART;
\r
310 gamestate.mapon=spot-1;
\r
311 SD_PlaySound(WARPUPSND);
\r
318 =============================================================================
\r
322 =============================================================================
\r
325 void T_Troll (objtype *ob);
\r
327 extern statetype s_trollpause;
\r
329 extern statetype s_troll1;
\r
330 extern statetype s_troll2;
\r
331 extern statetype s_troll3;
\r
332 extern statetype s_troll4;
\r
334 extern statetype s_trollattack1;
\r
335 extern statetype s_trollattack2;
\r
336 extern statetype s_trollattack3;
\r
338 extern statetype s_trollouch;
\r
340 extern statetype s_trolldie1;
\r
341 extern statetype s_trolldie2;
\r
342 extern statetype s_trolldie3;
\r
345 statetype s_trollpause = {TROLL1PIC,40,NULL,&s_troll2};
\r
347 statetype s_troll1 = {TROLL1PIC,13,T_Troll,&s_troll2};
\r
348 statetype s_troll2 = {TROLL2PIC,13,T_Troll,&s_troll3};
\r
349 statetype s_troll3 = {TROLL3PIC,13,T_Troll,&s_troll4};
\r
350 statetype s_troll4 = {TROLL4PIC,13,T_Troll,&s_troll1};
\r
352 statetype s_trollattack1 = {TROLLATTACK1PIC,20,NULL,&s_trollattack2};
\r
353 statetype s_trollattack2 = {TROLLATTACK2PIC,10,T_DoDamage,&s_trollattack3};
\r
354 statetype s_trollattack3 = {TROLLATTACK2PIC,40,NULL,&s_trollpause};
\r
356 statetype s_trollouch = {TROLLOUCHPIC,8,NULL,&s_troll1};
\r
358 statetype s_trolldie1 = {TROLLDIE1PIC,8,NULL,&s_trolldie2};
\r
359 statetype s_trolldie2 = {TROLLDIE2PIC,8,NULL,&s_trolldie3};
\r
360 statetype s_trolldie3 = {TROLLDIE3PIC,0,NULL,&s_trolldie3};
\r
371 void SpawnTroll (int tilex, int tiley)
\r
373 SpawnNewObj(tilex,tiley,&s_troll1,40*PIXRADIUS);
\r
375 new->obclass = trollobj;
\r
376 new->shootable = true;
\r
377 new->hitpoints = 10;
\r
389 void T_Troll (objtype *ob)
\r
391 if (Chase (ob,true))
\r
393 ob->state = &s_trollattack1;
\r
394 ob->ticcount = ob->state->tictime;
\r
402 =============================================================================
\r
406 =============================================================================
\r
409 void T_Orc (objtype *ob);
\r
411 extern statetype s_orcpause;
\r
413 extern statetype s_orc1;
\r
414 extern statetype s_orc2;
\r
415 extern statetype s_orc3;
\r
416 extern statetype s_orc4;
\r
418 extern statetype s_orcattack1;
\r
419 extern statetype s_orcattack2;
\r
420 extern statetype s_orcattack3;
\r
422 extern statetype s_orcouch;
\r
424 extern statetype s_orcdie1;
\r
425 extern statetype s_orcdie2;
\r
426 extern statetype s_orcdie3;
\r
430 statetype s_orcpause = {ORC1PIC,40,NULL,&s_orc2};
\r
432 statetype s_orc1 = {ORC1PIC,20,T_Orc,&s_orc2};
\r
433 statetype s_orc2 = {ORC2PIC,20,T_Orc,&s_orc3};
\r
434 statetype s_orc3 = {ORC3PIC,20,T_Orc,&s_orc4};
\r
435 statetype s_orc4 = {ORC4PIC,20,T_Orc,&s_orc1};
\r
437 statetype s_orcattack1 = {ORCATTACK1PIC,20,NULL,&s_orcattack2};
\r
438 statetype s_orcattack2 = {ORCATTACK2PIC,10,T_DoDamage,&s_orcattack3};
\r
439 statetype s_orcattack3 = {ORCATTACK2PIC,40,NULL,&s_orcpause};
\r
441 statetype s_orcouch = {ORCOUCHPIC,10,NULL,&s_orc1};
\r
443 statetype s_orcdie1 = {ORCDIE1PIC,8,NULL,&s_orcdie2};
\r
444 statetype s_orcdie2 = {ORCDIE2PIC,8,NULL,&s_orcdie3};
\r
445 statetype s_orcdie3 = {ORCDIE3PIC,0,NULL,&s_orcdie3};
\r
456 void SpawnOrc (int tilex, int tiley)
\r
458 SpawnNewObj(tilex,tiley,&s_orc1,PIXRADIUS*32);
\r
459 new->obclass = orcobj;
\r
461 new->shootable = true;
\r
462 new->hitpoints = 3;
\r
474 void T_Orc (objtype *ob)
\r
476 if (Chase (ob,true))
\r
478 ob->state = &s_orcattack1;
\r
479 ob->ticcount = ob->state->tictime;
\r
486 =============================================================================
\r
490 =============================================================================
\r
493 void T_Demon (objtype *ob);
\r
496 extern statetype s_demonpause;
\r
498 extern statetype s_demon1;
\r
499 extern statetype s_demon2;
\r
500 extern statetype s_demon3;
\r
501 extern statetype s_demon4;
\r
503 extern statetype s_demonattack1;
\r
504 extern statetype s_demonattack2;
\r
505 extern statetype s_demonattack3;
\r
507 extern statetype s_demonouch;
\r
509 extern statetype s_demondie1;
\r
510 extern statetype s_demondie2;
\r
511 extern statetype s_demondie3;
\r
514 statetype s_demonpause = {DEMON1PIC,40,NULL,&s_demon2};
\r
516 statetype s_demon1 = {DEMON1PIC,20,T_Demon,&s_demon2};
\r
517 statetype s_demon2 = {DEMON2PIC,20,T_Demon,&s_demon3};
\r
518 statetype s_demon3 = {DEMON3PIC,20,T_Demon,&s_demon4};
\r
519 statetype s_demon4 = {DEMON4PIC,20,T_Demon,&s_demon1};
\r
521 statetype s_demonattack1 = {DEMONATTACK1PIC,20,NULL,&s_demonattack2};
\r
522 statetype s_demonattack2 = {DEMONATTACK2PIC,20,T_DoDamage,&s_demonattack3};
\r
523 statetype s_demonattack3 = {DEMONATTACK3PIC,30,NULL,&s_demonpause};
\r
525 statetype s_demonouch = {DEMONOUCHPIC,10,NULL,&s_demon1};
\r
527 statetype s_demondie1 = {DEMONDIE1PIC,20,NULL,&s_demondie2};
\r
528 statetype s_demondie2 = {DEMONDIE2PIC,20,NULL,&s_demondie3};
\r
529 statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};
\r
541 void SpawnDemon (int tilex, int tiley)
\r
543 SpawnNewObj(tilex,tiley,&s_demon1,TILEGLOBAL/2);
\r
544 new->obclass = demonobj;
\r
546 new->shootable = true;
\r
547 new->hitpoints = 50;
\r
559 void T_Demon (objtype *ob)
\r
561 if (Chase (ob,true))
\r
563 ob->state = &s_demonattack1;
\r
564 ob->ticcount = ob->state->tictime;
\r
570 =============================================================================
\r
576 =============================================================================
\r
579 #define MSHOTDAMAGE 2
\r
580 #define MSHOTSPEED 10000
\r
582 void T_Mshot (objtype *ob);
\r
585 extern statetype s_mshot1;
\r
586 extern statetype s_mshot2;
\r
588 statetype s_mshot1 = {PSHOT1PIC,8,&T_Mshot,&s_mshot2};
\r
589 statetype s_mshot2 = {PSHOT2PIC,8,&T_Mshot,&s_mshot1};
\r
600 void T_Mshot (objtype *ob)
\r
603 long xmove,ymove,speed;
\r
610 ymove = -ob->speed*tics;
\r
613 xmove = ob->speed*tics;
\r
616 ymove = ob->speed*tics;
\r
619 xmove = -ob->speed*tics;
\r
628 ob->tilex = ob->x>>TILESHIFT;
\r
629 ob->tiley = ob->y>>TILESHIFT;
\r
631 if (tilemap[ob->tilex][ob->tiley])
\r
633 SD_PlaySound (SHOOTWALLSND);
\r
639 // check final position for monsters hit
\r
641 if ( ob->xl <= player->xh
\r
642 && ob->xh >= player->xl
\r
643 && ob->yl <= player->yh
\r
644 && ob->yh >= player->yl)
\r
646 TakeDamage (MSHOTDAMAGE*2);
\r
651 for (check = player->next; check; check=check->next)
\r
652 if (ob->shootable && ob->obclass != mageobj
\r
653 && ob->xl <= check->xh
\r
654 && ob->xh >= check->xl
\r
655 && ob->yl <= check->yh
\r
656 && ob->yh >= check->yl)
\r
658 ShootActor (check,MSHOTDAMAGE);
\r
668 =============================================================================
\r
672 =============================================================================
\r
676 void T_Mage (objtype *ob);
\r
677 void T_MageShoot (objtype *ob);
\r
679 extern statetype s_magepause;
\r
681 extern statetype s_mage1;
\r
682 extern statetype s_mage2;
\r
684 extern statetype s_mageattack1;
\r
685 extern statetype s_mageattack2;
\r
686 extern statetype s_mageattack3;
\r
688 extern statetype s_mageouch;
\r
690 extern statetype s_magedie1;
\r
691 extern statetype s_magedie2;
\r
694 statetype s_magepause = {MAGE1PIC,100,NULL,&s_mage2};
\r
696 statetype s_mage1 = {MAGE1PIC,20,T_Mage,&s_mage2};
\r
697 statetype s_mage2 = {MAGE2PIC,20,T_Mage,&s_mage1};
\r
699 statetype s_mageattack1 = {MAGEATTACKPIC,20,NULL,&s_mageattack2};
\r
700 statetype s_mageattack2 = {MAGEATTACKPIC,-1,T_MageShoot,&s_mageattack3};
\r
701 statetype s_mageattack3 = {MAGEATTACKPIC,30,NULL,&s_magepause};
\r
703 statetype s_mageouch = {MAGEOUCHPIC,10,NULL,&s_mage1};
\r
705 statetype s_magedie1 = {MAGEDIE1PIC,20,NULL,&s_magedie2};
\r
706 statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};
\r
717 void SpawnMage (int tilex, int tiley)
\r
719 SpawnNewObj(tilex,tiley,&s_mage1,TILEGLOBAL/2);
\r
720 new->obclass = mageobj;
\r
722 new->shootable = true;
\r
723 new->hitpoints = 5;
\r
735 void T_Mage (objtype *ob)
\r
739 // check for line up with player
\r
742 if (ob->x-PIXRADIUS*14 < player->xh
\r
743 && ob->x+PIXRADIUS > player->xl)
\r
746 ob->state = &s_mageattack1;
\r
748 else if (ob->y-PIXRADIUS*14 < player->yh
\r
749 && ob->y+PIXRADIUS > player->yl)
\r
752 ob->state = &s_mageattack1;
\r
765 void T_MageShoot (objtype *ob)
\r
767 SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);
\r
768 new->obclass = mshotobj;
\r
769 new->speed = MSHOTSPEED;
\r
772 if (ob->tiley < player->tiley)
\r
779 if (ob->tilex < player->tilex)
\r
788 =============================================================================
\r
792 =============================================================================
\r
796 void T_Nemesis (objtype *ob);
\r
797 void T_NemesisShoot (objtype *ob);
\r
799 extern statetype s_grelpause;
\r
801 extern statetype s_grel1;
\r
802 extern statetype s_grel2;
\r
804 extern statetype s_grelattack1;
\r
805 extern statetype s_grelattack2;
\r
806 extern statetype s_grelattack3;
\r
808 extern statetype s_grelouch;
\r
810 extern statetype s_greldie1;
\r
811 extern statetype s_greldie2;
\r
812 extern statetype s_greldie3;
\r
813 extern statetype s_greldie4;
\r
814 extern statetype s_greldie5;
\r
815 extern statetype s_greldie6;
\r
818 statetype s_grelpause = {GREL1PIC,50,NULL,&s_grel2};
\r
820 statetype s_grel1 = {GREL1PIC,20,T_Nemesis,&s_grel2};
\r
821 statetype s_grel2 = {GREL2PIC,20,T_Nemesis,&s_grel1};
\r
823 statetype s_grelattack1 = {GRELATTACKPIC,20,NULL,&s_grelattack2};
\r
824 statetype s_grelattack2 = {GRELATTACKPIC,-1,T_NemesisShoot,&s_grelattack3};
\r
825 statetype s_grelattack3 = {GRELATTACKPIC,30,NULL,&s_grelpause};
\r
827 statetype s_grelouch = {GRELHITPIC,6,NULL,&s_grel1};
\r
829 statetype s_greldie1 = {GRELDIE1PIC,20,NULL,&s_greldie2};
\r
830 statetype s_greldie2 = {GRELDIE2PIC,20,NULL,&s_greldie3};
\r
831 statetype s_greldie3 = {GRELDIE3PIC,20,NULL,&s_greldie4};
\r
832 statetype s_greldie4 = {GRELDIE4PIC,20,NULL,&s_greldie5};
\r
833 statetype s_greldie5 = {GRELDIE5PIC,20,NULL,&s_greldie6};
\r
834 statetype s_greldie6 = {GRELDIE6PIC,0,NULL,&s_greldie6};
\r
845 void SpawnNemesis (int tilex, int tiley)
\r
847 SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*56);
\r
848 new->obclass = grelmobj;
\r
850 new->shootable = true;
\r
851 new->hitpoints = 100;
\r
863 void T_Nemesis (objtype *ob)
\r
867 // check for line up with player
\r
869 if (ob->tilex == player->tilex)
\r
872 ob->state = &s_grelattack1;
\r
874 else if (ob->tiley == player->tiley)
\r
877 ob->state = &s_grelattack1;
\r
890 void T_NemesisShoot (objtype *ob)
\r
892 SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);
\r
893 new->obclass = mshotobj;
\r
894 new->speed = MSHOTSPEED;
\r
897 if (ob->tiley < player->tiley)
\r
904 if (ob->tilex < player->tilex)
\r
913 =============================================================================
\r
917 =============================================================================
\r
920 void T_Bat (objtype *ob);
\r
921 void T_BatPast (objtype *ob);
\r
923 extern statetype s_bat1;
\r
924 extern statetype s_bat2;
\r
925 extern statetype s_bat3;
\r
926 extern statetype s_bat4;
\r
928 extern statetype s_batdie1;
\r
929 extern statetype s_batdie2;
\r
932 statetype s_bat1 = {BAT1PIC,6,T_Bat,&s_bat2};
\r
933 statetype s_bat2 = {BAT2PIC,6,T_Bat,&s_bat3};
\r
934 statetype s_bat3 = {BAT3PIC,6,T_Bat,&s_bat4};
\r
935 statetype s_bat4 = {BAT4PIC,6,T_Bat,&s_bat1};
\r
937 statetype s_batpast = {BAT4PIC,80,T_BatPast,&s_bat1};
\r
939 statetype s_batdie1 = {BATDIE1PIC,8,NULL,&s_batdie2};
\r
940 statetype s_batdie2 = {BATDIE2PIC,8,NULL,NULL};
\r
951 void SpawnBat (int tilex, int tiley)
\r
953 SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*24);
\r
954 new->obclass =batobj;
\r
955 new->shootable = true;
\r
957 new->hitpoints = 1;
\r
963 ==================================
\r
967 ==================================
\r
970 void BatChaseThink (objtype *obj)
\r
974 deltax=player->tilex - obj->tilex;
\r
975 deltay=player->tiley - obj->tiley;
\r
989 obj->dir = dirtable[deltay*3+deltax];
\r
993 obj->dir = dirtable[3+deltax];
\r
997 obj->dir = dirtable[deltay*3+1];
\r
1005 void BatRunThink (objtype *obj)
\r
1007 int deltax,deltay;
\r
1009 deltax=player->tilex - obj->tilex;
\r
1010 deltay=player->tiley - obj->tiley;
\r
1022 obj->dir = dirtable[deltay*3+deltax];
\r
1026 obj->dir = dirtable[3+deltax];
\r
1030 obj->dir = dirtable[deltay*3+1];
\r
1044 void T_Bat (objtype *ob)
\r
1047 long deltax,deltay,size;
\r
1049 move = ob->speed*tics;
\r
1050 size = (long)ob->size + player->size + move;
\r
1055 deltax = ob->x - player->x;
\r
1056 deltay = ob->y - player->y;
\r
1058 if (deltax <= size && deltax >= -size
\r
1059 && deltay <= size && deltay >= -size && !ob->temp1)
\r
1065 if (move < ob->distance)
\r
1067 MoveObj (ob,move);
\r
1071 actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
\r
1072 if (ob->dir == nodir)
\r
1075 ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
\r
1076 ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
\r
1077 move -= ob->distance;
\r
1081 Walk (ob); // go straight
\r
1084 ob->state = &s_batpast;
\r
1085 ob->ticcount = ob->state->tictime;
\r
1089 BatChaseThink (ob); // head towards player
\r
1091 actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
\r
1092 } while (0); // just once
\r
1105 void T_BatPast (objtype *ob)
\r
1108 long deltax,deltay,size;
\r
1110 move = ob->speed*tics;
\r
1114 if (move < ob->distance)
\r
1116 MoveObj (ob,move);
\r
1119 actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
\r
1121 ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
\r
1122 ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
\r
1123 move -= ob->distance;
\r
1127 actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
\r
1128 } while (0); //(move)
\r
1135 =============================================================================
\r
1139 temp2 = set when hit player, reset when hit wall
\r
1141 =============================================================================
\r
1144 #define SPDBOUNCE 4096
\r
1145 #define DMGBOUNCE 10
\r
1147 void T_Bounce (objtype *ob);
\r
1149 extern statetype s_bounce1;
\r
1150 extern statetype s_bounce2;
\r
1153 statetype s_bounce1 = {BIGPSHOT1PIC,8,T_Bounce,&s_bounce2};
\r
1154 statetype s_bounce2 = {BIGPSHOT2PIC,8,T_Bounce,&s_bounce1};
\r
1164 void SpawnBounce (int tilex, int tiley, boolean towest)
\r
1166 SpawnNewObj(tilex,tiley,&s_bounce1,24*PIXRADIUS);
\r
1167 new->obclass = bounceobj;
\r
1183 void T_Bounce (objtype *ob)
\r
1186 long deltax,deltay,size;
\r
1188 move = SPDBOUNCE*tics;
\r
1189 size = (long)ob->size + player->size + move;
\r
1193 deltax = ob->x - player->x;
\r
1194 deltay = ob->y - player->y;
\r
1196 if (deltax <= size && deltax >= -size
\r
1197 && deltay <= size && deltay >= -size && !ob->temp2)
\r
1200 TakeDamage (DMGBOUNCE);
\r
1203 if (move < ob->distance)
\r
1205 MoveObj (ob,move);
\r
1208 actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
\r
1210 ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
\r
1211 ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
\r
1212 move -= ob->distance;
\r
1215 // bounce if hit wall
\r
1220 if (tilemap[ob->tilex][--ob->tiley])
\r
1228 if (tilemap[++ob->tilex][ob->tiley])
\r
1236 if (tilemap[ob->tilex][++ob->tiley])
\r
1244 if (tilemap[--ob->tilex][ob->tiley])
\r
1253 ob->distance = TILEGLOBAL;
\r
1255 actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
\r