OSDN Git Service

374028950a76c85b4dfb45b6f49a7d94790c8963
[proj16/16.git] / src / lib / hb / c6_act3.c
1 /* Catacomb Apocalypse Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\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
8  *\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
13  *\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
17  */\r
18 \r
19 // C3_PLAY.C\r
20 \r
21 #include "DEF.H"\r
22 #pragma hdrstop\r
23 \r
24 /*\r
25 =============================================================================\r
26 \r
27                                                  LOCAL CONSTANTS\r
28 \r
29 =============================================================================\r
30 */\r
31 \r
32 /*\r
33 =============================================================================\r
34 \r
35                                                  GLOBAL VARIABLES\r
36 \r
37 =============================================================================\r
38 */\r
39 \r
40 boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);\r
41 void T_ShootPlayer(objtype *ob);\r
42 \r
43 /*\r
44 =============================================================================\r
45 \r
46                                                  LOCAL VARIABLES\r
47 \r
48 =============================================================================\r
49 */\r
50 \r
51 \r
52 \r
53 \r
54 \r
55 /*\r
56 =============================================================================\r
57 \r
58                                                         DEMON\r
59 \r
60 =============================================================================\r
61 */\r
62 \r
63 void T_TrollDemon (objtype *ob);\r
64 \r
65 statetype s_demonpause = {DEMON1PIC,40,NULL,&s_demon2};\r
66 \r
67 statetype s_demon1 = {DEMON1PIC,20,&T_TrollDemon,&s_demon2};\r
68 statetype s_demon2 = {DEMON2PIC,20,&T_TrollDemon,&s_demon3};\r
69 statetype s_demon3 = {DEMON3PIC,20,&T_TrollDemon,&s_demon4};\r
70 statetype s_demon4 = {DEMON4PIC,20,&T_TrollDemon,&s_demon1};\r
71 \r
72 statetype s_demonattack1 = {DEMONATTACK1PIC,20,NULL,&s_demonattack2};\r
73 statetype s_demonattack2 = {DEMONATTACK2PIC,20,NULL,&s_demonattack3};\r
74 statetype s_demonattack3 = {DEMONATTACK3PIC,30,&T_DoDamage,&s_demonpause};\r
75 \r
76 statetype s_demonouch = {DEMONOUCHPIC,15,&T_TrollDemon,&s_demon1};\r
77 \r
78 statetype s_demondie1 = {DEMONDIE1PIC,40,NULL,&s_demondie2};\r
79 statetype s_demondie2 = {DEMONDIE2PIC,30,&LargeSound,&s_demondie3};\r
80 statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};\r
81 \r
82 \r
83 \r
84 /*\r
85 ===============\r
86 =\r
87 = SpawnDemon\r
88 =\r
89 ===============\r
90 */\r
91 \r
92 void SpawnDemon (int tilex, int tiley)\r
93 {\r
94         SpawnNewObj(tilex,tiley,&s_demon1,PIXRADIUS*35);\r
95         new->obclass = demonobj;\r
96         new->speed = 2048;\r
97         new->flags |= of_shootable;\r
98         new->hitpoints = EasyHitPoints(30);\r
99 }\r
100 \r
101 \r
102 /*\r
103 =============================================================================\r
104 \r
105                                                                                 TROLL\r
106 \r
107 =============================================================================\r
108 */\r
109 \r
110 statetype s_trollpause = {TROLL1PIC, 30, &T_DoDamage, &s_troll2};\r
111 \r
112 statetype s_troll1 = {TROLL1PIC, 13, &T_TrollDemon, &s_troll2};\r
113 statetype s_troll2 = {TROLL2PIC, 13, &T_TrollDemon, &s_troll3};\r
114 statetype s_troll3 = {TROLL3PIC, 13, &T_TrollDemon, &s_troll4};\r
115 statetype s_troll4 = {TROLL4PIC, 13, &T_TrollDemon, &s_troll1};\r
116 \r
117 statetype s_trollattack1 = {TROLLATTACK1PIC, 15, NULL, &s_trollattack2};\r
118 statetype s_trollattack2 = {TROLLATTACK2PIC, 20, NULL, &s_trollpause};\r
119 \r
120 statetype s_trollouch = {TROLLOUCHPIC, 14, &T_TrollDemon, &s_troll1};\r
121 \r
122 statetype s_trolldie1 = {TROLLDIE1PIC, 18, NULL, &s_trolldie2};\r
123 statetype s_trolldie2 = {TROLLDIE2PIC, 15, &LargeSound, &s_trolldie3};\r
124 statetype s_trolldie3 = {TROLLDIE3PIC, 0, NULL, &s_trolldie3};\r
125 \r
126 \r
127 /*\r
128 ===============\r
129 =\r
130 = SpawnTroll\r
131 =\r
132 ===============\r
133 */\r
134 \r
135 void SpawnTroll (int tilex, int tiley)\r
136 {\r
137         SpawnNewObj(tilex,tiley,&s_troll1,35*PIXRADIUS);\r
138         new->speed = 2500;\r
139         new->obclass = trollobj;\r
140         new->flags |= of_shootable;\r
141         new->hitpoints = EasyHitPoints(15);\r
142 }\r
143 \r
144 \r
145 /*\r
146 =============================================================================\r
147 \r
148                                                                                 CYBORG DEMON\r
149 \r
150 =============================================================================\r
151 */\r
152 \r
153 void T_Demon (objtype *ob);\r
154 \r
155 statetype s_cyborg_demon1 = {CYBORG1PIC, 20, T_TrollDemon, &s_cyborg_demon2};\r
156 statetype s_cyborg_demon2 = {CYBORG2PIC, 20, T_TrollDemon, &s_cyborg_demon3};\r
157 statetype s_cyborg_demon3 = {CYBORG3PIC, 20, T_TrollDemon, &s_cyborg_demon4};\r
158 statetype s_cyborg_demon4 = {CYBORG4PIC, 20, T_TrollDemon, &s_cyborg_demon1};\r
159 \r
160 statetype s_cyborg_demonattack1 = {CYBORGATTACK1PIC, 20, NULL, &s_cyborg_demonattack2};\r
161 statetype s_cyborg_demonattack2 = {CYBORGATTACK2PIC, 20, NULL, &s_cyborg_demonattack3};\r
162 statetype s_cyborg_demonattack3 = {CYBORGATTACK3PIC, 30, T_DoDamage, &s_cyborg_demon2};\r
163 \r
164 statetype s_cyborg_demonouch = {CYBORGOUCHPIC, 30, NULL, &s_cyborg_demon1};\r
165 \r
166 statetype s_cyborg_demondie1 = {CYBORGOUCHPIC, 40, NULL, &s_cyborg_demondie2};\r
167 statetype s_cyborg_demondie2 = {CYBORGDIE1PIC, 30, &LargeSound, &s_cyborg_demondie3};\r
168 statetype s_cyborg_demondie3 = {CYBORGDIE2PIC, 20, NULL, &s_cyborg_demondie3};\r
169 \r
170 /*\r
171 ===============\r
172 =\r
173 = SpawnCyborgDemon\r
174 =\r
175 ===============\r
176 */\r
177 \r
178 void SpawnCyborgDemon (int tilex, int tiley)\r
179 {\r
180         SpawnNewObj(tilex, tiley, &s_cyborg_demon1, PIXRADIUS*35);\r
181         new->obclass    = cyborgdemonobj;\r
182         new->speed = 2048;\r
183         new->flags |= of_shootable;\r
184         new->hitpoints = EasyHitPoints(30);\r
185 }\r
186 \r
187 \r
188 /*\r
189 ===============\r
190 =\r
191 = T_TrollDemon\r
192 =\r
193 ===============\r
194 */\r
195 \r
196 void T_TrollDemon (objtype *ob)\r
197 {\r
198         if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
199         {\r
200                 if (ob->obclass == cyborgdemonobj)\r
201                         ob->state = &s_cyborg_demonattack1;\r
202                 else\r
203                         if (ob->obclass == trollobj)\r
204                                 ob->state = &s_trollattack1;\r
205                         else\r
206                                 ob->state = &s_demonattack1;\r
207                 ob->ticcount = ob->state->tictime;\r
208         }\r
209 }\r
210 \r
211 \r
212 \r
213 \r
214 \r
215 /*\r
216 =============================================================================\r
217 \r
218                                                                                 INVISIBLE DUDE!\r
219 \r
220 =============================================================================\r
221 */\r
222 \r
223 void T_InvisibleDude (objtype *ob);\r
224 \r
225 statetype s_invis_fizz1 = {INVIS_FIZZ1PIC, 8, &T_InvisibleDude, &s_invis_fizz2};\r
226 statetype s_invis_fizz2 = {INVIS_FIZZ2PIC, 8, &T_InvisibleDude, &s_invis_fizz3};\r
227 statetype s_invis_fizz3 = {INVIS_FIZZ3PIC, 8, &T_InvisibleDude, &s_invis_walk};\r
228 \r
229 statetype s_invis_walk = {0, 25, &T_InvisibleDude, &s_invis_walk};\r
230 statetype s_invis_attack = {0, -1, &T_DoDamage, &s_invis_pause};\r
231 statetype s_invis_pause = {0, 40, NULL, &s_invis_walk};\r
232 \r
233 statetype s_invis_flash1 = {INVIS_FIZZ1PIC, 8, &T_InvisibleDude, &s_invis_walk};\r
234 statetype s_invis_flash2 = {INVIS_FIZZ2PIC, 8, &T_InvisibleDude, &s_invis_walk};\r
235 statetype s_invis_flash3 = {INVIS_FIZZ3PIC, 8, &T_InvisibleDude, &s_invis_walk};\r
236 \r
237 statetype s_invis_death1 = {INVIS_DEATH1PIC, 40, NULL, &s_invis_death2};\r
238 statetype s_invis_death2 = {INVIS_DEATH2PIC, 30, &LargeSound, &s_invis_death3};\r
239 statetype s_invis_death3 = {INVIS_DEATH3PIC, 20, NULL, &s_invis_death3};\r
240 \r
241 /*\r
242 ===============\r
243 =\r
244 = SpawnInvisDude\r
245 =\r
246 ===============\r
247 */\r
248 void SpawnInvisDude(int tilex, int tiley)\r
249 {\r
250         SpawnNewObj(tilex, tiley, &s_invis_walk, PIXRADIUS*20);\r
251         new->obclass    = invisdudeobj;\r
252         new->speed              = 2048;\r
253         new->flags              |= of_shootable;\r
254         new->hitpoints  = EasyHitPoints(20);\r
255         new->temp1              = 0;            // for random flashing of pictures\r
256 }\r
257 \r
258 \r
259 /*\r
260 ===============\r
261 =\r
262 = T_InvisibleDude\r
263 =\r
264 ===============\r
265 */\r
266 void T_InvisibleDude (objtype *ob)\r
267 {\r
268         if (!random(100))\r
269         {\r
270                 switch (ob->temp1++)\r
271                 {\r
272                         case 0:\r
273                                 ob->state = &s_invis_flash1;\r
274                         break;\r
275 \r
276                         case 1:\r
277                                 ob->state = &s_invis_flash2;\r
278                         break;\r
279 \r
280                         case 2:\r
281                                 ob->state = &s_invis_flash3;\r
282                                 ob->temp1 = 0;\r
283                         break;\r
284                 }\r
285                 ob->ticcount = ob->state->tictime;\r
286         }\r
287 \r
288 \r
289         if (Chase (ob,true))\r
290         {\r
291                 ob->state = &s_invis_attack;\r
292                 ob->ticcount = ob->state->tictime;\r
293         }\r
294 \r
295 }\r
296 \r
297 \r
298 \r
299 /*\r
300 =============================================================================\r
301 \r
302                                                                                         BOUNCE\r
303 \r
304 temp2 = set when hit player, reset when hit wall\r
305 \r
306 =============================================================================\r
307 */\r
308 \r
309 #define SPDBOUNCE       4096\r
310 #define DMGBOUNCE       10\r
311 \r
312 void T_Bounce (objtype *ob);\r
313 void T_Bounce_Death (objtype *ob);\r
314 \r
315 statetype s_bounce1 = {PSHOT1PIC, 8, &T_Bounce, &s_bounce2};\r
316 statetype s_bounce2 = {PSHOT2PIC, 8, &T_Bounce, &s_bounce1};\r
317 \r
318 /*\r
319 ===============\r
320 =\r
321 = SpawnBounce\r
322 =\r
323 ===============\r
324 */\r
325 \r
326 void SpawnBounce (int tilex, int tiley, boolean towest)\r
327 {\r
328         SpawnNewObj(tilex, tiley, &s_bounce1, 24*PIXRADIUS);\r
329         new->obclass = bounceobj;\r
330         new->hitpoints = EasyHitPoints(10);\r
331         new->flags |= of_shootable;\r
332         if (towest)\r
333                 new->dir = west;\r
334         else\r
335                 new->dir = north;\r
336 }\r
337 \r
338 \r
339 /*\r
340 ===============\r
341 =\r
342 = T_Bounce\r
343 =\r
344 ===============\r
345 */\r
346 \r
347 void T_Bounce (objtype *ob)\r
348 {\r
349         long move;\r
350         long deltax,deltay,size;\r
351 \r
352         move = SPDBOUNCE*tics;\r
353         size = (long)ob->size + player->size + move;\r
354 \r
355         while (move)\r
356         {\r
357                 deltax = ob->x - player->x;\r
358                 deltay = ob->y - player->y;\r
359 \r
360                 if (deltax <= size && deltax >= -size\r
361                 && deltay <= size && deltay >= -size && !ob->temp2)\r
362                 {\r
363                         ob->temp2 = 1;\r
364                         TakeDamage (DMGBOUNCE);\r
365                 }\r
366 \r
367                 if (move < ob->distance)\r
368                 {\r
369                         MoveObj (ob,move);\r
370                         break;\r
371                 }\r
372                 actorat[ob->tilex][ob->tiley] = 0;      // pick up marker from goal\r
373 \r
374                 ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;\r
375                 ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;\r
376                 move -= ob->distance;\r
377 \r
378                 //\r
379                 // bounce if hit wall\r
380                 //\r
381                 switch (ob->dir)\r
382                 {\r
383                 case north:\r
384                         if (tilemap[ob->tilex][--ob->tiley])\r
385                         {\r
386                                 ob->dir = south;\r
387                                 ob->tiley+=2;\r
388                                 ob->temp2 = 0;\r
389                         }\r
390                         break;\r
391                 case east:\r
392                         if (tilemap[++ob->tilex][ob->tiley])\r
393                         {\r
394                                 ob->dir = west;\r
395                                 ob->tilex-=2;\r
396                                 ob->temp2 = 0;\r
397                         }\r
398                         break;\r
399                 case south:\r
400                         if (tilemap[ob->tilex][++ob->tiley])\r
401                         {\r
402                                 ob->dir = north;\r
403                                 ob->tiley-=2;\r
404                                 ob->temp2 = 0;\r
405                         }\r
406                         break;\r
407                 case west:\r
408                         if (tilemap[--ob->tilex][ob->tiley])\r
409                         {\r
410                                 ob->dir = east;\r
411                                 ob->tilex+=2;\r
412                                 ob->temp2 = 0;\r
413                         }\r
414                         break;\r
415                 }\r
416 \r
417                 ob->distance = TILEGLOBAL;\r
418 \r
419                 actorat[ob->tilex][ob->tiley] = ob;     // set down a new goal marker\r
420         }\r
421         CalcBounds (ob);\r
422 }\r
423 \r
424 \r
425 /*\r
426 =============================================================================\r
427 \r
428                                                         GRELMINAR\r
429 \r
430 =============================================================================\r
431 */\r
432 \r
433 \r
434 void T_Grelminar (objtype *ob);\r
435 void T_GrelminarShoot (objtype *ob);\r
436 void T_Grelm_DropKey(objtype *ob);\r
437 \r
438 statetype s_grelpause = {GREL1PIC,50,NULL,&s_grel2};\r
439 \r
440 statetype s_grel1 = {GREL1PIC,20,T_Grelminar,&s_grel2};\r
441 statetype s_grel2 = {GREL2PIC,20,T_Grelminar,&s_grel1};\r
442 \r
443 statetype s_grelattack3 = {GRELATTACKPIC,30,NULL,&s_grelpause};\r
444 \r
445 statetype s_grelouch = {GRELHITPIC,6,NULL,&s_grel1};\r
446 \r
447 statetype s_greldie1 = {GRELDIE1PIC,22,NULL,&s_greldie2};\r
448 statetype s_greldie2 = {GRELDIE2PIC,22,NULL,&s_greldie3};\r
449 statetype s_greldie3 = {GRELDIE3PIC,22,NULL,&s_greldie4};\r
450 statetype s_greldie4 = {GRELDIE4PIC,22,NULL,&s_greldie5};\r
451 statetype s_greldie5 = {GRELDIE5PIC,22,NULL,&s_greldie5a};\r
452 statetype s_greldie5a = {GRELDIE5PIC,-1,T_Grelm_DropKey,&s_greldie6};\r
453 statetype s_greldie6 = {GRELDIE6PIC,0,NULL,&s_greldie6};\r
454 \r
455 statetype s_gshot1 = {SKULL_SHOTPIC,8,T_ShootPlayer,&s_gshot1};\r
456 \r
457 /*\r
458 ===============\r
459 =\r
460 = SpawnGrelminar\r
461 =\r
462 ===============\r
463 */\r
464 \r
465 void SpawnGrelminar (int tilex, int tiley)\r
466 {\r
467         unsigned Grel_Hard;\r
468         unsigned DropKey;\r
469 \r
470         SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*25);\r
471         new->obclass = grelmobj;\r
472         new->speed = 2048;\r
473         new->flags |= of_shootable;\r
474 \r
475         //\r
476         // if Grelminar is to drop a key the info-plane byte to the right\r
477         //              should have a 1 in the highbyte, else he will not drop the key.\r
478         //\r
479         DropKey = *(mapsegs[2]+farmapylookup[tiley]+tilex+1);\r
480         if (DropKey)\r
481                 new->temp1 = DropKey>>8;\r
482         else\r
483                 new->temp1 = 0;\r
484 \r
485         //\r
486         // The info-plane byte below Grelminar will determine how powerful\r
487         //              Grelminar is.  If nothing is there, he is the most powerful.\r
488         //                      -- affected are the hit points and the shot damage.\r
489         //      The hit points are controlled here, the shot damage is controlled\r
490         //      within the spawning of the shot.  See ShootPlayer for more info.\r
491         //\r
492         Grel_Hard = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);\r
493         if (Grel_Hard)\r
494         {\r
495                 new->temp2 = Grel_Hard>>8;\r
496                 new->hitpoints = EasyHitPoints((new->temp2 * 10));\r
497         }\r
498         else\r
499         {\r
500                 new->hitpoints = EasyHitPoints(100);\r
501                 new->temp2 = 10;\r
502         }\r
503 }\r
504 \r
505 \r
506 /*\r
507 ===============\r
508 =\r
509 = T_Grelminar\r
510 =\r
511 ===============\r
512 */\r
513 \r
514 void T_Grelminar (objtype *ob)\r
515 {\r
516         Chase (ob,false);\r
517 \r
518         if (!random(10))\r
519                 if (ShootPlayer(ob,gshotobj,ob->temp2,&s_gshot1))\r
520                 {\r
521                         ob->state = &s_grelattack3;\r
522                         ob->ticcount = ob->state->tictime;\r
523                 }\r
524         if (CheckHandAttack(ob))\r
525                 TakeDamage (ob->temp2*3);\r
526 \r
527 }\r
528 \r
529 \r
530 //=================================\r
531 //\r
532 // T_Grelm_DropKey\r
533 //\r
534 //=================================\r
535 void T_Grelm_DropKey(objtype *ob)\r
536 {\r
537         if (!(ob->temp1))\r
538         {\r
539                 ob->state = NULL;\r
540                 return;\r
541         }\r
542 \r
543         SpawnBonus(ob->tilex,ob->tiley,B_RKEY);\r
544         SD_PlaySound(GRELM_DEADSND);\r
545         ob->temp1 = false;\r
546 }\r
547 \r
548 \r
549 \r
550 //--------------------------------------------------------------------------\r
551 // ShootPlayer()\r
552 //--------------------------------------------------------------------------\r
553 boolean ShootPlayer(objtype *ob, short obclass, short speed, statetype *state)\r
554 {\r
555         int angle = AngleNearPlayer(ob);\r
556 \r
557         if (angle == -1)\r
558                 return(false);\r
559 \r
560         DSpawnNewObjFrac (ob->x,ob->y,state,PIXRADIUS*14);\r
561         new->obclass = obclass;\r
562         new->active = always;\r
563         new->angle = angle;\r
564 \r
565         //\r
566         //      If the shot is Grelminar's, then determine the power of the shot.\r
567         //      The shot speed is hard-wired as 10000.  But the shot power is\r
568         //              determined by speed.  Speed now contains "Grelminar's level of\r
569         //              hardness" and this is multiplied by 3 to get the shot power.\r
570         //\r
571         if (obclass == gshotobj)\r
572         {\r
573                 new->speed = 10000;\r
574                 new->temp1 = speed*3;\r
575         }\r
576         else\r
577                 new->speed = speed;\r
578 \r
579 \r
580         return(true);\r
581 }\r
582 \r
583 //--------------------------------------------------------------------------\r
584 // T_ShootPlayer()\r
585 //--------------------------------------------------------------------------\r
586 void T_ShootPlayer(objtype *ob)\r
587 {\r
588         objtype *check;\r
589         long xmove,ymove,speed;\r
590 \r
591         speed = ob->speed*tics;\r
592 \r
593         xmove = FixedByFrac(speed,costable[ob->angle]);\r
594         ymove = -FixedByFrac(speed,sintable[ob->angle]);\r
595 \r
596         if (ShotClipMove(ob,xmove,ymove))\r
597         {\r
598                 ob->state = &s_pshot_exp1;\r
599                 ob->ticcount = ob->state->tictime;\r
600                 return;\r
601         }\r
602 \r
603         ob->tilex = ob->x >> TILESHIFT;\r
604         ob->tiley = ob->y >> TILESHIFT;\r
605 \r
606 \r
607 // check for collision with wall\r
608 //\r
609         if (tilemap[ob->tilex][ob->tiley])\r
610         {\r
611 //              SD_PlaySound (SHOOTWALLSND);\r
612                 ob->state = &s_pshot_exp1;\r
613                 ob->ticcount = s_pshot_exp1.tictime;\r
614                 return;\r
615         }\r
616 \r
617 \r
618 \r
619 // check for collision with player\r
620 //\r
621         if ( ob->xl <= player->xh\r
622         && ob->xh >= player->xl\r
623         && ob->yl <= player->yh\r
624         && ob->yh >= player->yl)\r
625         {\r
626                 switch (ob->obclass)\r
627                 {\r
628                         case wshotobj:                                          // Wizard's shot\r
629                                 TakeDamage (7);\r
630                         break;\r
631 \r
632                         case hshotobj:                                          // Egyptian Head's shot\r
633                                 TakeDamage (5);\r
634                         break;\r
635 \r
636                         case bshotobj:                                          // Blob's shot\r
637                                 TakeDamage (5);\r
638                         break;\r
639 \r
640                         case rshotobj:                                          // Ray's shot\r
641                                 TakeDamage (5);\r
642                         break;\r
643 \r
644                         case rbshotobj:                                 // RamBone's shot\r
645                                 TakeDamage(7);\r
646                         break;\r
647 \r
648                         case fmshotobj:                                 // Future Mage's shot\r
649                                 TakeDamage(7);\r
650                         break;\r
651 \r
652                         case rtshotobj:                                 // RoboTank's shot\r
653                                 TakeDamage(15);\r
654                         break;\r
655 \r
656                         case syshotobj:                                 // Stompy's shot\r
657                                 TakeDamage(7);\r
658                         break;\r
659 \r
660                         case bgshotobj:                                 // Bug's shot\r
661                                 TakeDamage(7);\r
662                         break;\r
663 \r
664                         case eshotobj:                                          // Eye's shot\r
665                                 TakeDamage(5);\r
666                         break;\r
667 \r
668                         case gshotobj:\r
669                                 TakeDamage (ob->temp1);         // the damage of Grelminar's shot -\r
670                         break;                                                          //   see Grelminar's spawning\r
671 \r
672                 }\r
673                 ob->state = NULL;\r
674                 return;\r
675         }\r
676 \r
677 // check for collision with other solid and realsolid objects.\r
678 //  Great terminology!! -- solid objects really aren't solid\r
679 //                      -- realsolid objects ARE solid\r
680 //      if ((actorat[ob->tilex][ob->tiley]) && (actorat[ob->tilex][ob->tiley]->obclass != ob->obclass))\r
681         if (((actorat[ob->tilex][ob->tiley]->obclass == realsolidobj) ||\r
682                  (actorat[ob->tilex][ob->tiley]->obclass == solidobj)) &&\r
683                  (actorat[ob->tilex][ob->tiley]->flags & of_shootable))\r
684         {\r
685                         ob->state = &s_pshot_exp1;\r
686                         ob->ticcount = s_pshot_exp1.tictime;\r
687                         return;\r
688         }\r
689 \r
690 \r
691 // check for collision with player\r
692 //\r
693         for (check = player->next; check; check=check->next)\r
694                 if ((ob->flags & of_shootable)\r
695                 && ob->xl <= check->xh\r
696                 && ob->xh >= check->xl\r
697                 && ob->yl <= check->yh\r
698                 && ob->yh >= check->yl)\r
699                 {\r
700                         switch (ob->obclass)\r
701                         {\r
702 // APOCALYPSE\r
703                                 case wshotobj:                                          // Wizard's shot\r
704                                         ShootActor (check, 3);\r
705                                 break;\r
706 \r
707                                 case hshotobj:                                          // Egyptian Head's shot\r
708                                         ShootActor (check, 5);\r
709                                 break;\r
710 \r
711                                 case bshotobj:                                          // Blob's shot\r
712                                         ShootActor (check, 2);\r
713                                 break;\r
714 \r
715                                 case rshotobj:                                          // Ray's shot\r
716                                         ShootActor (check, 5);\r
717                                 break;\r
718 \r
719                                 case rbshotobj:                                 // RamBone's shot\r
720                                         ShootActor (check, 5);\r
721                                 break;\r
722 \r
723                                 case fmshotobj:                                 // Future Mage's shot\r
724                                         ShootActor (check, 5);\r
725                                 break;\r
726 \r
727                                 case rtshotobj:                                 // RoboTank's shot\r
728                                         ShootActor (check, 15);\r
729                                 break;\r
730 \r
731                                 case syshotobj:                                 // Stompy's shot\r
732                                         ShootActor (check, 5);\r
733                                 break;\r
734 \r
735                                 case bgshotobj:                                 // Bug's shot\r
736                                         ShootActor (check, 3);\r
737                                 break;\r
738 \r
739                                 case eshotobj:                                          // Eye's shot\r
740                                         ShootActor (check, 2);\r
741                                 break;\r
742 \r
743                                 case gshotobj:\r
744                                         ShootActor (check,25);          //NOLAN--check on me!!!!!!!\r
745                                 break;\r
746 \r
747                                 case pshotobj:\r
748                                         ShootActor (check,25);\r
749                                 break;\r
750 \r
751                         }\r
752                         ob->state = &s_pshot_exp1;\r
753                         ob->ticcount = s_pshot_exp1.tictime;\r
754                         return;\r
755                 }\r
756 }\r
757 \r
758 //-------------------------------------------------------------------------\r
759 // AngleNearPlayer()\r
760 //-------------------------------------------------------------------------\r
761 int AngleNearPlayer(objtype *ob)\r
762 {\r
763         int angle=-1;\r
764         int xdiff = ob->tilex-player->tilex;\r
765         int ydiff = ob->tiley-player->tiley;\r
766 \r
767         if (ob->tiley == player->tiley)\r
768         {\r
769                 if (ob->tilex < player->tilex)\r
770                         angle = 0;\r
771                 else\r
772                         angle = 180;\r
773         }\r
774         else\r
775         if (ob->tilex == player->tilex)\r
776         {\r
777                 if (ob->tiley < player->tiley)\r
778                         angle = 270;\r
779                 else\r
780                         angle = 90;\r
781         }\r
782         else\r
783         if (xdiff == ydiff)\r
784                 if (ob->tilex < player->tilex)\r
785                 {\r
786                         if (ob->tiley < player->tiley)\r
787                                 angle = 315;\r
788                         else\r
789                                 angle = 45;\r
790                 }\r
791                 else\r
792                 {\r
793                         if (ob->tiley < player->tiley)\r
794                                 angle = 225;\r
795                         else\r
796                                 angle = 135;\r
797                 }\r
798 \r
799         return(angle);\r
800 }\r
801 \r
802 \r