1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 1996, 2003 - 3D Realms Entertainment
4 Copyright (C) 2017-2019 Nuke.YKT
5
6 This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
7
8 Duke Nukem 3D is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17 See the GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 Original Source: 1996 - Todd Replogle
24 Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
25 */
26 //-------------------------------------------------------------------------
27
28 #include "types.h"
29 #include "develop.h"
30 #include "scriplib.h"
31 #include "file_lib.h"
32 #include "gamedefs.h"
33 #include "keyboard.h"
34 #include "util_lib.h"
35 #include "function.h"
36 #include "control.h"
37 #include "fx_man.h"
38 #include "sounds.h"
39 #include "config.h"
40 #include "sndcards.h"
41
42 #include "duke3d.h"
43
44
45 long tempwallptr;
spawn(short j,short pn)46 short spawn( short j, short pn )
47 {
48 short i, s, startwall, endwall, sect, clostest;
49 long x, y, d;
50 spritetype *sp;
51
52 if(j >= 0)
53 {
54 i = EGS(sprite[j].sectnum,sprite[j].x,sprite[j].y,sprite[j].z
55 ,pn,0,0,0,0,0,0,j,0);
56 hittype[i].picnum = sprite[j].picnum;
57 }
58 else
59 {
60 i = pn;
61
62 hittype[i].picnum = PN;
63 hittype[i].timetosleep = 0;
64 hittype[i].extra = -1;
65
66 hittype[i].bposx = SX;
67 hittype[i].bposy = SY;
68 hittype[i].bposz = SZ;
69
70 OW = hittype[i].owner = i;
71 hittype[i].cgg = 0;
72 hittype[i].movflag = 0;
73 hittype[i].tempang = 0;
74 hittype[i].dispicnum = 0;
75 hittype[i].floorz = sector[SECT].floorz;
76 hittype[i].ceilingz = sector[SECT].ceilingz;
77
78 hittype[i].lastvx = 0;
79 hittype[i].lastvy = 0;
80 hittype[i].actorstayput = -1;
81
82 T1 = T2 = T3 = T4 = T5 = T6 = 0;
83
84 if(CS&48)
85 if( !(PN >= CRACK1 && PN <= CRACK4) )
86 {
87 if(SS == 127) return i;
88 if( wallswitchcheck(i) == 1 && (CS&16) )
89 {
90 if( PN != ACCESSSWITCH && PN != ACCESSSWITCH2 && sprite[i].pal)
91 {
92 if( (ud.multimode < 2) || (ud.multimode > 1 && ud.coop==1) )
93 {
94 sprite[i].xrepeat = sprite[i].yrepeat = 0;
95 sprite[i].cstat = SLT = SHT = 0;
96 return i;
97 }
98 }
99 CS |= 257;
100 if( sprite[i].pal && PN != ACCESSSWITCH && PN != ACCESSSWITCH2)
101 sprite[i].pal = 0;
102 return i;
103 }
104
105 if( SHT )
106 {
107 changespritestat(i,12);
108 CS |= 257;
109 SH = impact_damage;
110 return i;
111 }
112 }
113
114 s = PN;
115
116 if( CS&1 ) CS |= 256;
117
118 if( actorscrptr[s] )
119 {
120 SH = *(actorscrptr[s]);
121 T5 = *(actorscrptr[s]+1);
122 T2 = *(actorscrptr[s]+2);
123 if( *(actorscrptr[s]+3) && SHT == 0 )
124 SHT = *(actorscrptr[s]+3);
125 }
126 else T2 = T5 = 0;
127 }
128
129 sp = &sprite[i];
130 sect = sp->sectnum;
131
132 switch(sp->picnum)
133 {
134 default:
135
136 if( actorscrptr[sp->picnum] )
137 {
138 if( j == -1 && sp->lotag > ud.player_skill )
139 {
140 sp->xrepeat=sp->yrepeat=0;
141 changespritestat(i,5);
142 break;
143 }
144
145 // Init the size
146 if(sp->xrepeat == 0 || sp->yrepeat == 0)
147 sp->xrepeat = sp->yrepeat = 1;
148
149 if( actortype[sp->picnum] & 3)
150 {
151 if( ud.monsters_off == 1 )
152 {
153 sp->xrepeat=sp->yrepeat=0;
154 changespritestat(i,5);
155 break;
156 }
157
158 makeitfall(i);
159
160 if( actortype[sp->picnum] & 2)
161 hittype[i].actorstayput = sp->sectnum;
162
163 if (actorfella(sp))
164 ps[myconnectindex].max_actors_killed++;
165 sp->clipdist = 80;
166 if(j >= 0)
167 {
168 if(sprite[j].picnum == RESPAWN)
169 hittype[i].tempang = sprite[i].pal = sprite[j].pal;
170 changespritestat(i,1);
171 }
172 else changespritestat(i,2);
173 }
174 else
175 {
176 sp->clipdist = 40;
177 sp->owner = i;
178 changespritestat(i,1);
179 }
180
181 hittype[i].timetosleep = 0;
182
183 if(j >= 0)
184 sp->ang = sprite[j].ang;
185 }
186 break;
187 case RRTILE280:
188 case RRTILE281:
189 case RRTILE282:
190 case RRTILE283:
191 case RRTILE2025:
192 case RRTILE2026:
193 case RRTILE2027:
194 case RRTILE2028:
195 sp->cstat = 0;
196 sp->cstat |= 32768;
197 sp->xrepeat = 0;
198 sp->yrepeat = 0;
199 sp->clipdist = 0;
200 sp->extra = 0;
201 changespritestat(i,105);
202 break;
203 case RRTILE3410:
204 sp->extra = 0;
205 changespritestat(i,107);
206 break;
207 #ifdef RRRA
208 case RRTILE8450:
209 sp->xrepeat = 64;
210 sp->yrepeat = 64;
211 sp->extra = sp->lotag;
212 sp->cstat |= 257;
213 changespritestat(i,116);
214 break;
215 case PIG+11:
216 sp->xrepeat = 16;
217 sp->yrepeat = 16;
218 sp->clipdist = 0;
219 sp->extra = 0;
220 sp->cstat = 0;
221 changespritestat(i,121);
222 break;
223 case RRTILE8487:
224 case RRTILE8489:
225 sp->xrepeat = 32;
226 sp->yrepeat = 32;
227 sp->extra = 0;
228 sp->cstat |= 257;
229 sp->hitag = 0;
230 changespritestat(i,117);
231 break;
232 case RRTILE7424:
233 sp->extra = 0;
234 sp->xrepeat = 0;
235 sp->yrepeat = 0;
236 changespritestat(i,11);
237 break;
238 case RRTILE7936:
239 sp->xrepeat = 0;
240 sp->yrepeat = 0;
241 sub_86730(2);
242 ps[screenpeek].fogtype = 1;
243 break;
244 case RRTILE6144:
245 sp->xrepeat = 0;
246 sp->yrepeat = 0;
247 ps[screenpeek].raat5dd = 1;
248 break;
249 case RRTILE8448:
250 sp->lotag = 1;
251 sp->clipdist = 0;
252 break;
253 case RRTILE8099:
254 sp->lotag = 5;
255 sp->clipdist = 0;
256 changespritestat(i,123);
257 break;
258 case RRTILE8704:
259 sp->lotag = 1;
260 sp->clipdist = 0;
261 break;
262 case RRTILE8192:
263 sp->xrepeat = 0;
264 sp->yrepeat = 0;
265 ps[screenpeek].raat5fd = 1;
266 break;
267 case RRTILE8193:
268 sp->xrepeat = 0;
269 sp->yrepeat = 0;
270 ps[screenpeek].raat601 = 1;
271 break;
272 case RRTILE8165:
273 sp->lotag = 1;
274 sp->clipdist = 0;
275 sp->owner = i;
276 sp->extra = 0;
277 changespritestat(i,115);
278 break;
279 case RRTILE8593:
280 sp->lotag = 1;
281 sp->clipdist = 0;
282 sp->owner = i;
283 sp->extra = 0;
284 changespritestat(i,122);
285 break;
286 #endif
287 case RRTILE285:
288 case RRTILE286:
289 case RRTILE287:
290 case RRTILE288:
291 case RRTILE289:
292 case RRTILE290:
293 case RRTILE291:
294 case RRTILE292:
295 case RRTILE293:
296 sp->cstat = 0;
297 sp->cstat |= 32768;
298 sp->xrepeat = 0;
299 sp->yrepeat = 0;
300 sp->clipdist = 0;
301 sp->lotag = 0;
302 changespritestat(i,106);
303 break;
304 case WATERSPLASH2:
305 case MUD:
306 if (j >= 0)
307 {
308 setsprite(i,sprite[j].x,sprite[j].y,sprite[j].z);
309 sp->xrepeat = sp->yrepeat = 8+(TRAND&7);
310 }
311 else sp->xrepeat = sp->yrepeat = 16+(TRAND&15);
312
313 sp->shade = -16;
314 sp->cstat |= 128;
315 if(j >= 0)
316 {
317 if(sector[sprite[j].sectnum].lotag == 2)
318 {
319 sp->z = getceilzofslope(SECT,SX,SY)+(16<<8);
320 sp->cstat |= 8;
321 }
322 else if( sector[sprite[j].sectnum].lotag == 1)
323 sp->z = getflorzofslope(SECT,SX,SY);
324 }
325
326 if(sector[sect].floorpicnum == FLOORSLIME ||
327 sector[sect].ceilingpicnum == FLOORSLIME)
328 sp->pal = 7;
329 case NEON1:
330 case NEON2:
331 case NEON3:
332 case NEON4:
333 case NEON5:
334 case NEON6:
335 case DOMELITE:
336 if(sp->picnum != WATERSPLASH2)
337 sp->cstat |= 257;
338 if(sp->picnum == DOMELITE)
339 sp->cstat |= 257;
340 case JIBS1:
341 case JIBS2:
342 case JIBS3:
343 case JIBS4:
344 case JIBS5:
345 case JIBS6:
346 case DUKETORSO:
347 case DUKEGUN:
348 case DUKELEG:
349 case BILLYJIBA:
350 case BILLYJIBB:
351 case HULKJIBA:
352 case HULKJIBB:
353 case HULKJIBC:
354 case MINJIBA:
355 case MINJIBB:
356 case MINJIBC:
357 case COOTJIBA:
358 case COOTJIBB:
359 case COOTJIBC:
360 #ifdef RRRA
361 case RRTILE2460:
362 case RRTILE2465:
363 case BIKEJIBA:
364 case BIKEJIBB:
365 case BIKEJIBC:
366 case BIKERJIBA:
367 case BIKERJIBB:
368 case BIKERJIBC:
369 case BIKERJIBD:
370 case CHEERJIBA:
371 case CHEERJIBB:
372 case CHEERJIBC:
373 case CHEERJIBD:
374 case FBOATJIBA:
375 case FBOATJIBB:
376 case RABBITJIBA:
377 case RABBITJIBB:
378 case RABBITJIBC:
379 case MAMAJIBA:
380 case MAMAJIBB:
381 #endif
382 if (sp->picnum == JIBS6)
383 {
384 sp->xrepeat >>= 1;
385 sp->yrepeat >>= 1;
386 }
387 #ifdef RRRA
388 else if (sp->picnum == RABBITJIBA)
389 {
390 sp->xrepeat = 18;
391 sp->yrepeat = 18;
392 }
393 else if (sp->picnum == RABBITJIBB)
394 {
395 sp->xrepeat = 36;
396 sp->yrepeat = 36;
397 }
398 else if (sp->picnum == RABBITJIBC)
399 {
400 sp->xrepeat = 54;
401 sp->yrepeat = 54;
402 }
403 #endif
404 changespritestat(i,5);
405 break;
406 case TONGUE:
407 if(j >= 0)
408 sp->ang = sprite[j].ang;
409 sp->z -= 38<<8;
410 sp->zvel = 256-(TRAND&511);
411 sp->xvel = 64-(TRAND&127);
412 changespritestat(i,4);
413 break;
414 case TRANSPORTERSTAR:
415 case TRANSPORTERBEAM:
416 if(j == -1) break;
417 if(sp->picnum == TRANSPORTERBEAM)
418 {
419 sp->xrepeat = 31;
420 sp->yrepeat = 1;
421 sp->z = sector[sprite[j].sectnum].floorz-(40<<8);
422 }
423 else
424 {
425 if(sprite[j].statnum == 4)
426 {
427 sp->xrepeat = 8;
428 sp->yrepeat = 8;
429 }
430 else
431 {
432 sp->xrepeat = 48;
433 sp->yrepeat = 64;
434 if(sprite[j].statnum == 10 || badguy(&sprite[j]) )
435 sp->z -= (32<<8);
436 }
437 }
438
439 sp->shade = -127;
440 sp->cstat = 128|2;
441 sp->ang = sprite[j].ang;
442
443 sp->xvel = 128;
444 changespritestat(i,5);
445 ssp(i,CLIPMASK0);
446 setsprite(i,sp->x,sp->y,sp->z);
447 break;
448
449 case FRAMEEFFECT1:
450 if (j >= 0)
451 {
452 sp->xrepeat = sprite[j].xrepeat;
453 sp->yrepeat = sprite[j].yrepeat;
454 if (sprite[j].picnum == APLAYER)
455 T2 = SMALLSMOKE;
456 else
457 T2 = sprite[j].picnum;
458 }
459 else sp->xrepeat = sp->yrepeat = 0;
460
461 changespritestat(i,5);
462 break;
463
464 case FORCESPHERE:
465 if (j == -1)
466 {
467 sp->cstat = (short)32768;
468 changespritestat(i,2);
469 }
470 else
471 {
472 sp->xrepeat = sp->yrepeat = 1;
473 changespritestat(i,5);
474 }
475 break;
476
477 case BLOOD:
478 sp->xrepeat = sp->yrepeat = 4;
479 sp->z -= (26<<8);
480 changespritestat(i,5);
481 break;
482 case BLOODPOOL:
483 {
484 short s1;
485 s1 = sp->sectnum;
486
487 updatesector(sp->x+108,sp->y+108,&s1);
488 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
489 {
490 updatesector(sp->x-108,sp->y-108,&s1);
491 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
492 {
493 updatesector(sp->x+108,sp->y-108,&s1);
494 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
495 {
496 updatesector(sp->x-108,sp->y+108,&s1);
497 if(s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz)
498 { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
499 }
500 else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
501 }
502 else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
503 }
504 else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
505 }
506
507 if( sector[SECT].lotag == 1 )
508 {
509 changespritestat(i,5);
510 break;
511 }
512
513 if(j >= 0)
514 {
515 if( sprite[j].pal == 1)
516 sp->pal = 1;
517 else if( sprite[j].pal != 6 && sprite[j].picnum != NUKEBARREL && sprite[j].picnum != TIRE )
518 {
519 sp->pal = 2; // Red
520 }
521 else sp->pal = 0; // green
522
523 if(sprite[j].picnum == TIRE)
524 sp->shade = 127;
525 }
526 sp->cstat |= 32;
527
528 case BLOODSPLAT1:
529 case BLOODSPLAT2:
530 case BLOODSPLAT3:
531 case BLOODSPLAT4:
532 sp->cstat |= 16;
533 sp->xrepeat = 7+(TRAND&7);
534 sp->yrepeat = 7+(TRAND&7);
535 sp->z -= (16<<8);
536 if(j >= 0 && sprite[j].pal == 6)
537 sp->pal = 6;
538 insertspriteq(i);
539 changespritestat(i,5);
540 break;
541
542 case HYDRENT:
543 case SATELITE:
544 case FUELPOD:
545 case SOLARPANNEL:
546 case ANTENNA:
547 case GRATE1:
548 case CHAIR1:
549 case CHAIR2:
550 case CHAIR3:
551 case BOTTLE1:
552 case BOTTLE2:
553 case BOTTLE3:
554 case BOTTLE4:
555 case BOTTLE5:
556 case BOTTLE6:
557 case BOTTLE7:
558 case BOTTLE8:
559 case BOTTLE10:
560 case BOTTLE11:
561 case BOTTLE12:
562 case BOTTLE13:
563 case BOTTLE14:
564 case BOTTLE15:
565 case BOTTLE16:
566 case BOTTLE17:
567 case BOTTLE18:
568 case BOTTLE19:
569 case SCALE:
570 case VACUUM:
571 case FANSPRITE:
572 case CACTUS:
573 case CACTUSBROKE:
574 case CAMERALIGHT:
575 case MOVIECAMERA:
576 case IVUNIT:
577 case POT1:
578 case POT2:
579 case POT3:
580 case SUSHIPLATE1:
581 case SUSHIPLATE2:
582 case SUSHIPLATE3:
583 case SUSHIPLATE4:
584 case SUSHIPLATE5:
585 case WAITTOBESEATED:
586 case VASE:
587 case PIPE1:
588 case PIPE2:
589 case PIPE3:
590 case PIPE4:
591 case PIPE5:
592 case PIPE6:
593 sp->clipdist = 32;
594 sp->cstat |= 257;
595 changespritestat(i,0);
596 break;
597 case FEMMAG1:
598 case FEMMAG2:
599 sp->cstat &= ~257;
600 changespritestat(i,0);
601 break;
602
603 case MASKWALL7:
604 j = sp->cstat&60;
605 sp->cstat = j|1;
606 changespritestat(i,0);
607 break;
608 case FOOTPRINTS:
609 case FOOTPRINTS2:
610 case FOOTPRINTS3:
611 case FOOTPRINTS4:
612 if(j >= 0)
613 {
614 short s1;
615 s1 = sp->sectnum;
616
617 updatesector(sp->x+84,sp->y+84,&s1);
618 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
619 {
620 updatesector(sp->x-84,sp->y-84,&s1);
621 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
622 {
623 updatesector(sp->x+84,sp->y-84,&s1);
624 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
625 {
626 updatesector(sp->x-84,sp->y+84,&s1);
627 if(s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz)
628 { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
629 }
630 else { sp->xrepeat = sp->yrepeat = 0;break;}
631 }
632 else { sp->xrepeat = sp->yrepeat = 0;break;}
633 }
634 else { sp->xrepeat = sp->yrepeat = 0;break;}
635
636 sp->cstat = 32+((ps[sprite[j].yvel].footprintcount&1)<<2);
637 sp->ang = sprite[j].ang;
638 }
639
640 sp->z = sector[sect].floorz;
641 if(sector[sect].lotag != 1 && sector[sect].lotag != 2)
642 sp->xrepeat = sp->yrepeat = 32;
643
644 insertspriteq(i);
645 changespritestat(i,5);
646 break;
647 case FEM10:
648 case NAKED1:
649 case STATUE:
650 case TOUGHGAL:
651 sp->yvel = sp->hitag;
652 sp->hitag = -1;
653 case QUEBALL:
654 case STRIPEBALL:
655 if (sp->picnum == QUEBALL || sp->picnum == STRIPEBALL)
656 {
657 sp->cstat = 256;
658 sp->clipdist = 8;
659 }
660 else
661 {
662 sp->cstat |= 257;
663 sp->clipdist = 32;
664 }
665 changespritestat(i,2);
666 break;
667 case BOWLINGBALL:
668 sp->cstat = 256;
669 sp->clipdist = 64;
670 sp->xrepeat = 11;
671 sp->yrepeat = 9;
672 changespritestat(i,2);
673 break;
674 case HENSTAND:
675 sp->cstat = 257;
676 sp->clipdist = 48;
677 sp->xrepeat = 21;
678 sp->yrepeat = 15;
679 changespritestat(i,2);
680 break;
681 case RRTILE295:
682 sp->cstat |= 32768;
683 changespritestat(i,107);
684 break;
685 case RRTILE296:
686 case RRTILE297:
687 sp->xrepeat = 64;
688 sp->yrepeat = 64;
689 sp->clipdist = 64;
690 changespritestat(i,108);
691 break;
692 case RRTILE3190:
693 case RRTILE3191:
694 case RRTILE3192:
695 sp->cstat = 257;
696 sp->clipdist = 8;
697 sp->xrepeat = 32;
698 sp->yrepeat = 26;
699 sp->xvel = 32;
700 changespritestat(i,1);
701 break;
702 case RRTILE3120:
703 sp->cstat = 257;
704 sp->clipdist = 8;
705 sp->xrepeat = 12;
706 sp->yrepeat = 10;
707 sp->xvel = 32;
708 changespritestat(i,1);
709 break;
710 case RRTILE3122:
711 sp->cstat = 257;
712 sp->clipdist = 2;
713 sp->xrepeat = 8;
714 sp->yrepeat = 6;
715 sp->xvel = 16;
716 changespritestat(i,1);
717 break;
718 case RRTILE3123:
719 sp->cstat = 257;
720 sp->clipdist = 8;
721 sp->xrepeat = 13;
722 sp->yrepeat = 13;
723 sp->xvel = 16;
724 changespritestat(i,1);
725 break;
726 case RRTILE3124:
727 sp->cstat = 257;
728 sp->clipdist = 8;
729 sp->xrepeat = 17;
730 sp->yrepeat = 12;
731 sp->xvel = 32;
732 changespritestat(i,1);
733 break;
734 case RRTILE3132:
735 sp->cstat = 257;
736 sp->clipdist = 8;
737 sp->xrepeat = 13;
738 sp->yrepeat = 10;
739 sp->xvel = 0;
740 changespritestat(i,1);
741 break;
742 case RRTILE3440:
743 sp->cstat = 257;
744 sp->clipdist = 48;
745 sp->xrepeat = 23;
746 sp->yrepeat = 23;
747 changespritestat(i,2);
748 break;
749 case DUKELYINGDEAD:
750 if(j >= 0 && sprite[j].picnum == APLAYER)
751 {
752 sp->xrepeat = sprite[j].xrepeat;
753 sp->yrepeat = sprite[j].yrepeat;
754 sp->shade = sprite[j].shade;
755 sp->pal = ps[sprite[j].yvel].palookup;
756 }
757 sp->cstat = 0;
758 sp->extra = 1;
759 sp->xvel = 292;
760 sp->zvel = 360;
761 case RESPAWNMARKERRED:
762 if(sp->picnum == RESPAWNMARKERRED)
763 {
764 sp->xrepeat = sp->yrepeat = 8;
765 if(j >= 0) sp->z = hittype[j].floorz;
766 }
767 else
768 {
769 sp->cstat |= 257;
770 sp->clipdist = 128;
771 }
772 case MIKE:
773 if(sp->picnum == MIKE)
774 sp->yvel = sp->hitag;
775 changespritestat(i,1);
776 break;
777
778 case SPOTLITE:
779 T1 = sp->x;
780 T2 = sp->y;
781 break;
782 case BULLETHOLE:
783 sp->xrepeat = sp->yrepeat = 3;
784 sp->cstat = 16+(krand()&12);
785 insertspriteq(i);
786 case MONEY:
787 if(sp->picnum == MONEY)
788 {
789 hittype[i].temp_data[0] = TRAND&2047;
790 sp->cstat = TRAND&12;
791 sp->xrepeat = sp->yrepeat = 8;
792 sp->ang = TRAND&2047;
793 }
794 changespritestat(i,5);
795 break;
796
797 case SHELL: //From the player
798 case SHOTGUNSHELL:
799 if( j >= 0 )
800 {
801 short snum,a;
802
803 if(sprite[j].picnum == APLAYER)
804 {
805 snum = sprite[j].yvel;
806 a = ps[snum].ang-(TRAND&63)+8; //Fine tune
807
808 T1 = TRAND&1;
809 if(sp->picnum == SHOTGUNSHELL)
810 sp->z = (6<<8)+ps[snum].pyoff+ps[snum].posz-((ps[snum].horizoff+ps[snum].horiz-100)<<4);
811 else sp->z = (3<<8)+ps[snum].pyoff+ps[snum].posz-((ps[snum].horizoff+ps[snum].horiz-100)<<4);
812 sp->zvel = -(TRAND&255);
813 }
814 else
815 {
816 a = sp->ang;
817 sp->z = sprite[j].z-PHEIGHT+(7<<8);
818 }
819
820 sp->x = sprite[j].x+(sintable[(a+512)&2047]>>7);
821 sp->y = sprite[j].y+(sintable[a&2047]>>7);
822
823 sp->shade = -8;
824
825 sp->ang = a-512;
826 sp->xvel = 20;
827
828 if (sp->picnum == SHELL)
829 sp->xrepeat=sp->yrepeat=2;
830 else
831 sp->xrepeat=sp->yrepeat=4;
832
833 changespritestat(i,5);
834 }
835 break;
836 case RESPAWN:
837 sp->extra = 66-13;
838 case MUSICANDSFX:
839 if (ud.multimode < 2 && sp->pal == 1)
840 {
841 sp->xrepeat = sp->yrepeat = 0;
842 changespritestat(i,5);
843 break;
844 }
845 sp->cstat = (short)32768;
846 changespritestat(i,11);
847 break;
848 case SOUNDFX:
849 {
850 short tg;
851 sp->cstat |= 32768;
852 changespritestat(i,2);
853 tg = sp->hitag;
854 tg = sp->lotag;
855 }
856 break;
857 case EXPLOSION2:
858 case EXPLOSION3:
859 case BURNING:
860 case SMALLSMOKE:
861 if(j >= 0)
862 {
863 sp->ang = sprite[j].ang;
864 sp->shade = -64;
865 sp->cstat = 128|(TRAND&4);
866 }
867
868 if(sp->picnum == EXPLOSION2)
869 {
870 sp->xrepeat = 48;
871 sp->yrepeat = 48;
872 sp->shade = -127;
873 sp->cstat |= 128;
874 }
875 else if(sp->picnum == EXPLOSION3)
876 {
877 sp->xrepeat = 128;
878 sp->yrepeat = 128;
879 sp->shade = -127;
880 sp->cstat |= 128;
881 }
882 else if(sp->picnum == SMALLSMOKE)
883 {
884 sp->xrepeat = 12;
885 sp->yrepeat = 12;
886 }
887 else if(sp->picnum == BURNING)
888 {
889 sp->xrepeat = 4;
890 sp->yrepeat = 4;
891 }
892
893 if(j >= 0)
894 {
895 x = getflorzofslope(sp->sectnum,sp->x,sp->y);
896 if(sp->z > x-(12<<8) )
897 sp->z = x-(12<<8);
898 }
899
900 changespritestat(i,5);
901
902 break;
903
904 case PLAYERONWATER:
905 if(j >= 0)
906 {
907 sp->xrepeat = sprite[j].xrepeat;
908 sp->yrepeat = sprite[j].yrepeat;
909 sp->zvel = 128;
910 if(sector[sp->sectnum].lotag != 2)
911 sp->cstat |= 32768;
912 }
913 changespritestat(i,13);
914 break;
915
916 case APLAYER:
917 sp->xrepeat = sp->yrepeat = 0;
918 j = ud.coop;
919 if(j == 2) j = 0;
920
921 if( ud.multimode < 2 || (ud.multimode > 1 && j != sp->lotag) )
922 changespritestat(i,5);
923 else
924 changespritestat(i,10);
925 break;
926
927 case WATERBUBBLE:
928 if(j >= 0 && sprite[j].picnum == APLAYER)
929 sp->z-= (16<<8);
930 if(sp->picnum == WATERBUBBLE)
931 {
932 if(j >= 0)
933 sp->ang = sprite[j].ang;
934 sp->xrepeat = sp->yrepeat = 1+(TRAND&7);
935 }
936 else
937 sp->xrepeat = sp->yrepeat = 32;
938 changespritestat(i,5);
939 break;
940 case CRANE:
941
942 sp->cstat |= 64|257;
943
944 sp->picnum += 2;
945 sp->z = sector[sect].ceilingz+(48<<8);
946 T5 = tempwallptr;
947
948 msx[tempwallptr] = sp->x;
949 msy[tempwallptr] = sp->y;
950 msx[tempwallptr+2] = sp->z;
951
952 s = headspritestat[0];
953 while(s >= 0)
954 {
955 if( sprite[s].picnum == CRANEPOLE && SHT == (sprite[s].hitag) )
956 {
957 msy[tempwallptr+2] = s;
958
959 T2 = sprite[s].sectnum;
960
961 sprite[s].xrepeat = 48;
962 sprite[s].yrepeat = 128;
963
964 msx[tempwallptr+1] = sprite[s].x;
965 msy[tempwallptr+1] = sprite[s].y;
966
967 sprite[s].x = sp->x;
968 sprite[s].y = sp->y;
969 sprite[s].z = sp->z;
970 sprite[s].shade = sp->shade;
971
972 setsprite(s,sprite[s].x,sprite[s].y,sprite[s].z);
973 break;
974 }
975 s = nextspritestat[s];
976 }
977
978 tempwallptr += 3;
979 sp->owner = -1;
980 sp->extra = 8;
981 changespritestat(i,6);
982 break;
983 case WATERDRIP:
984 // TODO: array underflow
985 if(j >= 0 && sprite[j].statnum == 10 || sprite[j].statnum == 1)
986 {
987 sp->shade = 32;
988 if(sprite[j].pal != 1)
989 {
990 sp->pal = 2;
991 sp->z -= (18<<8);
992 }
993 else sp->z -= (13<<8);
994 sp->ang = getangle(ps[connecthead].posx-sp->x,ps[connecthead].posy-sp->y);
995 sp->xvel = 48-(TRAND&31);
996 ssp(i,CLIPMASK0);
997 }
998 else if(j == -1)
999 {
1000 sp->z += (4<<8);
1001 T1 = sp->z;
1002 }
1003 case TRASH:
1004
1005 if(sp->picnum != WATERDRIP) sp->ang = TRAND&2047;
1006
1007 sp->xrepeat = 24;
1008 sp->yrepeat = 24;
1009 changespritestat(i,6);
1010 break;
1011
1012 case PLUG:
1013 sp->lotag = 9999;
1014 changespritestat(i,6);
1015 break;
1016 case TOUCHPLATE:
1017 T3 = sector[sect].floorz;
1018 if(sector[sect].lotag != 1 && sector[sect].lotag != 2)
1019 sector[sect].floorz = sp->z;
1020 if(sp->pal && ud.multimode > 1)
1021 {
1022 sp->xrepeat=sp->yrepeat=0;
1023 changespritestat(i,5);
1024 break;
1025 }
1026 case WATERBUBBLEMAKER:
1027 sp->cstat |= 32768;
1028 changespritestat(i,6);
1029 break;
1030 case BOLT1:
1031 case BOLT1+1:
1032 case BOLT1+2:
1033 case BOLT1+3:
1034 T1 = sp->xrepeat;
1035 T2 = sp->yrepeat;
1036 case MASTERSWITCH:
1037 if(sp->picnum == 8)
1038 sp->cstat |= 32768;
1039 sp->yvel = 0;
1040 changespritestat(i,6);
1041 break;
1042 case BILLYRAYSTAYPUT:
1043 case BRAYSNIPER:
1044 case BUBBASTAND:
1045 case HULKSTAYPUT:
1046 case HENSTAYPUT:
1047 case PIGSTAYPUT:
1048 case MINIONSTAYPUT:
1049 case COOTSTAYPUT:
1050 #ifdef RRRA
1051 case SBSWIPE:
1052 case CHEERSTAYPUT:
1053 #else
1054 case SBMOVE:
1055 #endif
1056 hittype[i].actorstayput = sp->sectnum;
1057 case BOULDER:
1058 case BOULDER1:
1059 case RAT:
1060 case TORNADO:
1061 case BILLYCOCK:
1062 case BILLYRAY:
1063 case DOGRUN:
1064 case LTH:
1065 case HULK:
1066 case HEN:
1067 case DRONE:
1068 case PIG:
1069 case MINION:
1070 case UFO1:
1071 case UFO2:
1072 case UFO3:
1073 case UFO4:
1074 case UFO5:
1075 case COW:
1076 case COOT:
1077 case SHARK:
1078 case VIXEN:
1079 #ifdef RRRA
1080 case BIKERB:
1081 case BIKERBV2:
1082 case BIKER:
1083 case MAKEOUT:
1084 case CHEERB:
1085 case CHEER:
1086 case COOTPLAY:
1087 case BILLYPLAY:
1088 case MINIONBOAT:
1089 case HULKBOAT:
1090 case CHEERBOAT:
1091 case RABBIT:
1092 case ROCK:
1093 case ROCK2:
1094 case MAMACLOUD:
1095 case MAMA:
1096 #endif
1097 sp->xrepeat = 40;
1098 sp->yrepeat = 40;
1099 switch (sp->picnum)
1100 {
1101 case VIXEN:
1102 if (sp->pal == 34)
1103 {
1104 sp->xrepeat = 22;
1105 sp->yrepeat = 21;
1106 }
1107 else
1108 {
1109 sp->xrepeat = 22;
1110 sp->yrepeat = 20;
1111 }
1112 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1113 break;
1114 case HULKHANG:
1115 case HULKHANGDEAD:
1116 case HULKJUMP:
1117 case HULK:
1118 case HULKSTAYPUT:
1119 sp->xrepeat = 32;
1120 sp->yrepeat = 32;
1121 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1122 break;
1123 case COOT:
1124 case COOTSTAYPUT:
1125 #ifdef RRRA
1126 case COOTPLAY:
1127 #endif
1128 sp->xrepeat = 24;
1129 sp->yrepeat = 18;
1130 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1131 sp->clipdist <<= 2;
1132 break;
1133 case DRONE:
1134 sp->xrepeat = 14;
1135 sp->yrepeat = 7;
1136 sp->clipdist = 128;
1137 break;
1138 case BILLYCOCK:
1139 case BILLYRAY:
1140 case BILLYRAYSTAYPUT:
1141 case BRAYSNIPER:
1142 case BUBBASTAND:
1143 #ifdef RRRA
1144 case SBSWIPE:
1145 case BILLYPLAY:
1146 #endif
1147 sp->xrepeat = 25;
1148 sp->yrepeat = 21;
1149 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1150 break;
1151 case COW:
1152 sp->xrepeat = 32;
1153 sp->yrepeat = 32;
1154 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1155 break;
1156 case HEN:
1157 case HENSTAYPUT:
1158 case HENSTAND:
1159 if(sp->pal == 35)
1160 {
1161 sp->xrepeat = 42;
1162 sp->yrepeat = 30;
1163 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1164 }
1165 else
1166 {
1167 sp->xrepeat = 21;
1168 sp->yrepeat = 15;
1169 sp->clipdist = 64;
1170 }
1171 break;
1172 case MINION:
1173 case MINIONSTAYPUT:
1174 sp->xrepeat = 16;
1175 sp->yrepeat = 16;
1176 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1177 #ifdef RRRA
1178 if (ps[screenpeek].raat5fd)
1179 sp->pal = 8;
1180 #endif
1181 break;
1182 case DOGRUN:
1183 case PIG:
1184 sp->xrepeat = 16;
1185 sp->yrepeat = 16;
1186 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1187 break;
1188 #ifdef RRRA
1189 case RABBIT:
1190 sp->xrepeat = 18;
1191 sp->yrepeat = 18;
1192 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1193 break;
1194 case MAMACLOUD:
1195 sp->xrepeat = 64;
1196 sp->yrepeat = 64;
1197 sp->cstat = 2;
1198 sp->cstat |= 512;
1199 sp->x += (TRAND&2047)-1024;
1200 sp->y += (TRAND&2047)-1024;
1201 sp->z += (TRAND&2047)-1024;
1202 break;
1203 case MAMA:
1204 if (sp->pal == 30)
1205 {
1206 sp->xrepeat = 26;
1207 sp->yrepeat = 26;
1208 sp->clipdist = 75;
1209 }
1210 else if (sp->pal == 31)
1211 {
1212 sp->xrepeat = 36;
1213 sp->yrepeat = 36;
1214 sp->clipdist = 100;
1215 }
1216 else if (sp->pal == 32)
1217 {
1218 sp->xrepeat = 50;
1219 sp->yrepeat = 50;
1220 sp->clipdist = 100;
1221 }
1222 else
1223 {
1224 sp->xrepeat = 50;
1225 sp->yrepeat = 50;
1226 sp->clipdist = 100;
1227 }
1228 break;
1229 case BIKERB:
1230 sp->xrepeat = 28;
1231 sp->yrepeat = 22;
1232 sp->clipdist = 72;
1233 break;
1234 case BIKERBV2:
1235 sp->xrepeat = 28;
1236 sp->yrepeat = 22;
1237 sp->clipdist = 72;
1238 break;
1239 case BIKER:
1240 sp->xrepeat = 28;
1241 sp->yrepeat = 22;
1242 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1243 break;
1244 case CHEERB:
1245 sp->xrepeat = 28;
1246 sp->yrepeat = 22;
1247 sp->clipdist = 72;
1248 break;
1249 case CHEER:
1250 case CHEERSTAYPUT:
1251 sp->xrepeat = 20;
1252 sp->yrepeat = 20;
1253 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1254 break;
1255 case MAKEOUT:
1256 sp->xrepeat = 26;
1257 sp->yrepeat = 26;
1258 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1259 break;
1260 case MINIONBOAT:
1261 sp->xrepeat = 16;
1262 sp->yrepeat = 16;
1263 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1264 break;
1265 case HULKBOAT:
1266 sp->xrepeat = 48;
1267 sp->yrepeat = 48;
1268 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1269 break;
1270 case CHEERBOAT:
1271 sp->xrepeat = 32;
1272 sp->yrepeat = 32;
1273 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1274 break;
1275 #endif
1276 case TORNADO:
1277 sp->xrepeat = 64;
1278 sp->yrepeat = 128;
1279 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1280 sp->clipdist >>= 2;
1281 sp->cstat = 2;
1282 break;
1283 case LTH:
1284 sp->xrepeat = 24;
1285 sp->yrepeat = 22;
1286 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1287 break;
1288 #ifdef RRRA
1289 case ROCK:
1290 case ROCK2:
1291 sp->xrepeat = 64;
1292 sp->yrepeat = 64;
1293 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1294 break;
1295 #endif
1296 case UFO1:
1297 case UFO2:
1298 case UFO3:
1299 case UFO4:
1300 case UFO5:
1301 sp->xrepeat = 32;
1302 sp->yrepeat = 32;
1303 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1304 sp->extra = 50;
1305 break;
1306 #ifndef RRRA
1307 case SBMOVE:
1308 sp->xrepeat = 48;
1309 sp->yrepeat = 48;
1310 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
1311 break;
1312 #endif
1313
1314 default:
1315 break;
1316 }
1317
1318 if(j >= 0) sp->lotag = 0;
1319
1320 if( ( sp->lotag > ud.player_skill ) || ud.monsters_off == 1 )
1321 {
1322 sp->xrepeat=sp->yrepeat=0;
1323 changespritestat(i,5);
1324 break;
1325 }
1326 else
1327 {
1328 makeitfall(i);
1329
1330 if(sp->picnum == RAT)
1331 {
1332 sp->ang = TRAND&2047;
1333 sp->xrepeat = sp->yrepeat = 48;
1334 sp->cstat = 0;
1335 }
1336 else
1337 {
1338 sp->cstat |= 257;
1339
1340 if(sp->picnum != 5501)
1341 if (actorfella(sp))
1342 ps[myconnectindex].max_actors_killed++;
1343 }
1344
1345 if(j >= 0)
1346 {
1347 hittype[i].timetosleep = 0;
1348 check_fta_sounds(i);
1349 changespritestat(i,1);
1350 }
1351 else changespritestat(i,2);
1352
1353 sp->shade = sprite[j].shade;
1354 }
1355
1356 break;
1357 case LOCATORS:
1358 // sp->xrepeat=sp->yrepeat=0;
1359 sp->cstat |= 32768;
1360 changespritestat(i,7);
1361 break;
1362
1363 case ACTIVATORLOCKED:
1364 case ACTIVATOR:
1365 // sp->xrepeat=sp->yrepeat=0;
1366 sp->cstat |= 32768;
1367 if (sp->picnum == ACTIVATORLOCKED)
1368 sector[sect].lotag ^= 16384;
1369 changespritestat(i,8);
1370 break;
1371 case DOORSHOCK:
1372 sp->cstat |= 1+256;
1373 sp->shade = -12;
1374
1375 changespritestat(i,6);
1376 break;
1377
1378 case OOZ:
1379 sp->shade = -12;
1380
1381 if(j >= 0)
1382 if( sprite[j].picnum == NUKEBARREL )
1383 sp->pal = 8;
1384
1385 changespritestat(i,1);
1386
1387 getglobalz(i);
1388
1389 j = (hittype[i].floorz-hittype[i].ceilingz)>>9;
1390
1391 sp->yrepeat = j;
1392 sp->xrepeat = 25-(j>>1);
1393 sp->cstat |= (TRAND&4);
1394 break;
1395
1396 case HEAVYHBOMB:
1397 sp->owner = i;
1398 sp->xrepeat = sp->yrepeat = 9;
1399 sp->yvel = 4;
1400 case REACTOR2:
1401 case REACTOR:
1402 case RECON:
1403
1404 if (sp->picnum == RECON)
1405 {
1406 if( sp->lotag > ud.player_skill )
1407 {
1408 sp->xrepeat = sp->yrepeat = 0;
1409 changespritestat(i,5);
1410 return i;
1411 }
1412 if (actorfella(sp))
1413 ps[myconnectindex].max_actors_killed++;
1414 hittype[i].temp_data[5] = 0;
1415 if(ud.monsters_off == 1)
1416 {
1417 sp->xrepeat = sp->yrepeat = 0;
1418 changespritestat(i,5);
1419 break;
1420 }
1421 sp->extra = 130;
1422 }
1423
1424 if(sp->picnum == REACTOR || sp->picnum == REACTOR2)
1425 sp->extra = impact_damage;
1426
1427 CS |= 257; // Make it hitable
1428
1429 if( ud.multimode < 2 && sp->pal != 0)
1430 {
1431 sp->xrepeat = sp->yrepeat = 0;
1432 changespritestat(i,5);
1433 break;
1434 }
1435 sp->pal = 0;
1436 SS = -17;
1437
1438 changespritestat(i,2);
1439 break;
1440
1441 case ATOMICHEALTH:
1442 case STEROIDS:
1443 case HEATSENSOR:
1444 case SHIELD:
1445 case AIRTANK:
1446 case TRIPBOMBSPRITE:
1447 case JETPACK:
1448 case HOLODUKE:
1449
1450 case FIRSTGUNSPRITE:
1451 case CHAINGUNSPRITE:
1452 case SHOTGUNSPRITE:
1453 case RPGSPRITE:
1454 case SHRINKERSPRITE:
1455 case FREEZESPRITE:
1456 case DEVISTATORSPRITE:
1457
1458 case SHOTGUNAMMO:
1459 case FREEZEAMMO:
1460 case HBOMBAMMO:
1461 case CRYSTALAMMO:
1462 case GROWAMMO:
1463 case BATTERYAMMO:
1464 case DEVISTATORAMMO:
1465 case RPGAMMO:
1466 case BOOTS:
1467 case AMMO:
1468 case AMMOLOTS:
1469 case COLA:
1470 case FIRSTAID:
1471 case SIXPAK:
1472
1473 case RRTILE43:
1474 case BOWLINGBALLSPRITE:
1475 #ifdef RRRA
1476 case RPG2SPRITE:
1477 case MOTOAMMO:
1478 case BOATAMMO:
1479 #endif
1480 if (j >= 0)
1481 {
1482 sp->lotag = 0;
1483 if (sp->picnum != BOWLINGBALLSPRITE)
1484 {
1485 sp->z -= (32 << 8);
1486 sp->zvel = -(4 << 8);
1487 }
1488 else
1489 {
1490 sp->zvel = 0;
1491 }
1492 ssp(i,CLIPMASK0);
1493 sp->cstat = TRAND&4;
1494 }
1495 else
1496 {
1497 sp->owner = i;
1498 sp->cstat = 0;
1499 }
1500
1501 if( ( ud.multimode < 2 && sp->pal != 0) || (sp->lotag > ud.player_skill) )
1502 {
1503 sp->xrepeat = sp->yrepeat = 0;
1504 changespritestat(i,5);
1505 break;
1506 }
1507
1508 sp->pal = 0;
1509
1510 case ACCESSCARD:
1511
1512 if (sp->picnum == ATOMICHEALTH)
1513 sp->cstat |= 128;
1514
1515 if(ud.multimode > 1 && ud.coop != 1 && sp->picnum == ACCESSCARD)
1516 {
1517 sp->xrepeat = sp->yrepeat = 0;
1518 changespritestat(i,5);
1519 break;
1520 }
1521 else
1522 {
1523 if(sp->picnum == AMMO)
1524 sp->xrepeat = sp->yrepeat = 16;
1525 else sp->xrepeat = sp->yrepeat = 32;
1526 }
1527
1528 sp->shade = -17;
1529
1530 if(j >= 0) changespritestat(i,1);
1531 else
1532 {
1533 changespritestat(i,2);
1534 makeitfall(i);
1535 }
1536 switch (sp->picnum)
1537 {
1538 case FIRSTGUNSPRITE:
1539 sp->xrepeat = 16;
1540 sp->yrepeat = 16;
1541 break;
1542 case SHOTGUNAMMO:
1543 sp->xrepeat = 18;
1544 sp->yrepeat = 17;
1545 #ifdef RRRA
1546 sp->cstat = 256;
1547 #endif
1548 break;
1549 case SIXPAK:
1550 sp->xrepeat = 13;
1551 sp->yrepeat = 9;
1552 #ifdef RRRA
1553 sp->cstat = 256;
1554 #endif
1555 break;
1556 case FIRSTAID:
1557 sp->xrepeat = 8;
1558 sp->yrepeat = 8;
1559 break;
1560 case COLA:
1561 sp->xrepeat = 5;
1562 sp->yrepeat = 4;
1563 break;
1564 case AMMO:
1565 sp->xrepeat = 9;
1566 sp->yrepeat = 9;
1567 break;
1568 #ifdef RRRA
1569 case MOTOAMMO:
1570 sp->xrepeat = 23;
1571 sp->yrepeat = 23;
1572 break;
1573 case BOATAMMO:
1574 sp->xrepeat = 16;
1575 sp->yrepeat = 16;
1576 break;
1577 #endif
1578 case JETPACK:
1579 sp->xrepeat = 8;
1580 sp->yrepeat = 6;
1581 break;
1582 case STEROIDS:
1583 sp->xrepeat = 13;
1584 sp->yrepeat = 9;
1585 break;
1586 case ACCESSCARD:
1587 sp->xrepeat = 11;
1588 sp->yrepeat = 12;
1589 break;
1590 case HEATSENSOR:
1591 sp->xrepeat = 6;
1592 sp->yrepeat = 4;
1593 break;
1594 case AIRTANK:
1595 sp->xrepeat = 19;
1596 sp->yrepeat = 16;
1597 break;
1598 case BATTERYAMMO:
1599 sp->xrepeat = 15;
1600 sp->yrepeat = 15;
1601 break;
1602 case BOWLINGBALLSPRITE:
1603 sp->xrepeat = 11;
1604 sp->yrepeat = 11;
1605 break;
1606 case TRIPBOMBSPRITE:
1607 sp->xrepeat = 11;
1608 sp->yrepeat = 11;
1609 sp->yvel = 4;
1610 sp->xvel = 32;
1611 break;
1612 case RPGSPRITE:
1613 sp->xrepeat = 16;
1614 sp->yrepeat = 14;
1615 break;
1616 #ifdef RRRA
1617 case RPG2SPRITE:
1618 sp->xrepeat = 20;
1619 sp->yrepeat = 20;
1620 break;
1621 #endif
1622 case SHRINKERSPRITE:
1623 sp->xrepeat = 22;
1624 sp->yrepeat = 13;
1625 break;
1626 case DEVISTATORSPRITE:
1627 sp->xrepeat = 18;
1628 sp->yrepeat = 17;
1629 break;
1630 case RRTILE43:
1631 sp->xrepeat = 12;
1632 sp->yrepeat = 7;
1633 break;
1634 case GROWSPRITEICON:
1635 sp->xrepeat = 10;
1636 sp->yrepeat = 9;
1637 break;
1638 case DEVISTATORAMMO:
1639 sp->xrepeat = 10;
1640 sp->yrepeat = 9;
1641 break;
1642 case ATOMICHEALTH:
1643 sp->xrepeat = 8;
1644 sp->yrepeat = 8;
1645 break;
1646 case FREEZESPRITE:
1647 sp->xrepeat = 17;
1648 sp->yrepeat = 16;
1649 break;
1650 }
1651 sp->shade = sector[sp->sectnum].floorshade;
1652 break;
1653 case WATERFOUNTAIN:
1654 SLT = 1;
1655 case TREE1:
1656 case TREE2:
1657 case TIRE:
1658 CS = 257; // Make it hitable
1659 sprite[i].extra = 1;
1660 changespritestat(i,6);
1661 break;
1662
1663 case CAMERA1:
1664 case CAMERA1+1:
1665 case CAMERA1+2:
1666 case CAMERA1+3:
1667 case CAMERA1+4:
1668 case CAMERAPOLE:
1669 sp->extra = 1;
1670
1671 if(camerashitable) sp->cstat = 257;
1672 else sp->cstat = 0;
1673
1674 if( ud.multimode < 2 && sp->pal != 0 )
1675 {
1676 sp->xrepeat = sp->yrepeat = 0;
1677 changespritestat(i,5);
1678 break;
1679 }
1680 else sp->pal = 0;
1681 if(sp->picnum == CAMERAPOLE) break;
1682 sp->picnum = CAMERA1;
1683 changespritestat(i,1);
1684 break;
1685 case STEAM:
1686 if(j >= 0)
1687 {
1688 sp->ang = sprite[j].ang;
1689 sp->cstat = 16+128+2;
1690 sp->xrepeat=sp->yrepeat=1;
1691 sp->xvel = -8;
1692 ssp(i,CLIPMASK0);
1693 }
1694 case CEILINGSTEAM:
1695 changespritestat(i,6);
1696 break;
1697 case SECTOREFFECTOR:
1698 sp->yvel = sector[sect].extra;
1699 sp->cstat |= 32768;
1700 sp->xrepeat = sp->yrepeat = 0;
1701
1702 switch(sp->lotag)
1703 {
1704 case 7: // Transporters!!!!
1705 case 23:// XPTR END
1706 if(sp->lotag != 23)
1707 {
1708 for(j=0;j<MAXSPRITES;j++)
1709 if(sprite[j].statnum < MAXSTATUS && sprite[j].picnum == SECTOREFFECTOR && ( sprite[j].lotag == 7 || sprite[j].lotag == 23 ) && i != j && sprite[j].hitag == SHT)
1710 {
1711 OW = j;
1712 break;
1713 }
1714 }
1715 else OW = i;
1716
1717 T5 = sector[sect].floorz == SZ;
1718 sp->cstat = 0;
1719 changespritestat(i,9);
1720 return i;
1721 case 1:
1722 sp->owner = -1;
1723 T1 = 1;
1724 break;
1725 case 18:
1726
1727 if(sp->ang == 512)
1728 {
1729 T2 = sector[sect].ceilingz;
1730 if(sp->pal)
1731 sector[sect].ceilingz = sp->z;
1732 }
1733 else
1734 {
1735 T2 = sector[sect].floorz;
1736 if(sp->pal)
1737 sector[sect].floorz = sp->z;
1738 }
1739
1740 sp->hitag <<= 2;
1741 break;
1742
1743 case 19:
1744 sp->owner = -1;
1745 break;
1746 case 25: // Pistons
1747 T5 = sector[sect].ceilingz;
1748 sector[sect].ceilingz = sp->z;
1749 setinterpolation(§or[sect].ceilingz);
1750 break;
1751 case 35:
1752 sector[sect].ceilingz = sp->z;
1753 break;
1754 case 27:
1755 if(ud.recstat == 1)
1756 {
1757 sp->xrepeat=sp->yrepeat=64;
1758 sp->cstat &= 32767;
1759 }
1760 break;
1761 #ifdef RRRA
1762 case 47:
1763 case 48:
1764 #endif
1765 case 12:
1766
1767 T2 = sector[sect].floorshade;
1768 T3 = sector[sect].ceilingshade;
1769 break;
1770
1771 case 13:
1772
1773 T1 = sector[sect].ceilingz;
1774 T2 = sector[sect].floorz;
1775
1776 if( klabs(T1-sp->z) < klabs(T2-sp->z) )
1777 sp->owner = 1;
1778 else sp->owner = 0;
1779
1780 if(sp->ang == 512)
1781 {
1782 if(sp->owner)
1783 sector[sect].ceilingz = sp->z;
1784 else
1785 sector[sect].floorz = sp->z;
1786 }
1787 else
1788 sector[sect].ceilingz = sector[sect].floorz = sp->z;
1789
1790 if( sector[sect].ceilingstat&1 )
1791 {
1792 sector[sect].ceilingstat ^= 1;
1793 T4 = 1;
1794
1795 if(!sp->owner && sp->ang==512)
1796 {
1797 sector[sect].ceilingstat ^= 1;
1798 T4 = 0;
1799 }
1800
1801 sector[sect].ceilingshade =
1802 sector[sect].floorshade;
1803
1804 if(sp->ang==512)
1805 {
1806 startwall = sector[sect].wallptr;
1807 endwall = startwall+sector[sect].wallnum;
1808 for(j=startwall;j<endwall;j++)
1809 {
1810 x = wall[j].nextsector;
1811 if(x >= 0)
1812 if( !(sector[x].ceilingstat&1) )
1813 {
1814 sector[sect].ceilingpicnum =
1815 sector[x].ceilingpicnum;
1816 sector[sect].ceilingshade =
1817 sector[x].ceilingshade;
1818 break; //Leave earily
1819 }
1820 }
1821 }
1822 }
1823
1824 break;
1825
1826 case 17:
1827
1828 T3 = sector[sect].floorz; //Stopping loc
1829
1830 j = nextsectorneighborz(sect,sector[sect].floorz,-1,-1);
1831 T4 = sector[j].ceilingz;
1832
1833 j = nextsectorneighborz(sect,sector[sect].ceilingz,1,1);
1834 T5 = sector[j].floorz;
1835
1836 if(numplayers < 2)
1837 {
1838 setinterpolation(§or[sect].floorz);
1839 setinterpolation(§or[sect].ceilingz);
1840 }
1841
1842 break;
1843
1844 case 24:
1845 sp->yvel <<= 1;
1846 case 36:
1847 break;
1848
1849 case 20:
1850 {
1851 long q;
1852
1853 startwall = sector[sect].wallptr;
1854 endwall = startwall+sector[sect].wallnum;
1855
1856 //find the two most clostest wall x's and y's
1857 q = 0x7fffffff;
1858
1859 for(s=startwall;s<endwall;s++)
1860 {
1861 x = wall[s].x;
1862 y = wall[s].y;
1863
1864 d = FindDistance2D(sp->x-x,sp->y-y);
1865 if( d < q )
1866 {
1867 q = d;
1868 clostest = s;
1869 }
1870 }
1871
1872 T2 = clostest;
1873
1874 q = 0x7fffffff;
1875
1876 for(s=startwall;s<endwall;s++)
1877 {
1878 x = wall[s].x;
1879 y = wall[s].y;
1880
1881 d = FindDistance2D(sp->x-x,sp->y-y);
1882 if(d < q && s != T2)
1883 {
1884 q = d;
1885 clostest = s;
1886 }
1887 }
1888
1889 T3 = clostest;
1890 }
1891
1892 break;
1893
1894 case 3:
1895
1896 T4=sector[sect].floorshade;
1897
1898 sector[sect].floorshade = sp->shade;
1899 sector[sect].ceilingshade = sp->shade;
1900
1901 sp->owner = sector[sect].ceilingpal<<8;
1902 sp->owner |= sector[sect].floorpal;
1903
1904 //fix all the walls;
1905
1906 startwall = sector[sect].wallptr;
1907 endwall = startwall+sector[sect].wallnum;
1908
1909 for(s=startwall;s<endwall;s++)
1910 {
1911 if(!(wall[s].hitag&1))
1912 wall[s].shade=sp->shade;
1913 if( (wall[s].cstat&2) && wall[s].nextwall >= 0)
1914 wall[wall[s].nextwall].shade = sp->shade;
1915 }
1916 break;
1917
1918 case 31:
1919 T2 = sector[sect].floorz;
1920 // T3 = sp->hitag;
1921 if(sp->ang != 1536) sector[sect].floorz = sp->z;
1922
1923 startwall = sector[sect].wallptr;
1924 endwall = startwall+sector[sect].wallnum;
1925
1926 for(s=startwall;s<endwall;s++)
1927 if(wall[s].hitag == 0) wall[s].hitag = 9999;
1928
1929 setinterpolation(§or[sect].floorz);
1930
1931 break;
1932 case 32:
1933 T2 = sector[sect].ceilingz;
1934 T3 = sp->hitag;
1935 if(sp->ang != 1536) sector[sect].ceilingz = sp->z;
1936
1937 startwall = sector[sect].wallptr;
1938 endwall = startwall+sector[sect].wallnum;
1939
1940 for(s=startwall;s<endwall;s++)
1941 if(wall[s].hitag == 0) wall[s].hitag = 9999;
1942
1943 setinterpolation(§or[sect].ceilingz);
1944
1945 break;
1946
1947 case 4: //Flashing lights
1948
1949 T3 = sector[sect].floorshade;
1950
1951 startwall = sector[sect].wallptr;
1952 endwall = startwall+sector[sect].wallnum;
1953
1954 sp->owner = sector[sect].ceilingpal<<8;
1955 sp->owner |= sector[sect].floorpal;
1956
1957 for(s=startwall;s<endwall;s++)
1958 if(wall[s].shade > T4)
1959 T4 = wall[s].shade;
1960
1961 break;
1962
1963 case 9:
1964 if( sector[sect].lotag &&
1965 labs(sector[sect].ceilingz-sp->z) > 1024)
1966 sector[sect].lotag |= 32768; //If its open
1967 case 8:
1968 //First, get the ceiling-floor shade
1969
1970 T1 = sector[sect].floorshade;
1971 T2 = sector[sect].ceilingshade;
1972
1973 startwall = sector[sect].wallptr;
1974 endwall = startwall+sector[sect].wallnum;
1975
1976 for(s=startwall;s<endwall;s++)
1977 if(wall[s].shade > T3)
1978 T3 = wall[s].shade;
1979
1980 T4 = 1; //Take Out;
1981
1982 break;
1983
1984 case 88:
1985 //First, get the ceiling-floor shade
1986
1987 T1 = sector[sect].floorshade;
1988 T2 = sector[sect].ceilingshade;
1989
1990 startwall = sector[sect].wallptr;
1991 endwall = startwall+sector[sect].wallnum;
1992
1993 for(s=startwall;s<endwall;s++)
1994 if(wall[s].shade > T3)
1995 T3 = wall[s].shade;
1996
1997 T4 = 1; //Take Out;
1998 break;
1999
2000 case 11://Pivitor rotater
2001 if(sp->ang>1024) T4 = 2;
2002 else T4 = -2;
2003 case 0:
2004 case 2://Earthquakemakers
2005 case 5://Boss Creature
2006 case 6://Subway
2007 case 14://Caboos
2008 case 15://Subwaytype sliding door
2009 case 16://That rotating blocker reactor thing
2010 case 26://ESCELATOR
2011 case 30://No rotational subways
2012
2013 if(sp->lotag == 0)
2014 {
2015 if( sector[sect].lotag == 30 )
2016 {
2017 if(sp->pal) sprite[i].clipdist = 1;
2018 else sprite[i].clipdist = 0;
2019 T4 = sector[sect].floorz;
2020 sector[sect].hitag = i;
2021 }
2022
2023 for(j = 0;j < MAXSPRITES;j++)
2024 {
2025 if( sprite[j].statnum < MAXSTATUS )
2026 if( sprite[j].picnum == SECTOREFFECTOR &&
2027 sprite[j].lotag == 1 &&
2028 sprite[j].hitag == sp->hitag)
2029 {
2030 if( sp->ang == 512 )
2031 {
2032 sp->x = sprite[j].x;
2033 sp->y = sprite[j].y;
2034 }
2035 break;
2036 }
2037 }
2038 if(j == MAXSPRITES)
2039 {
2040 sprintf(tempbuf,"Found lonely Sector Effector (lotag 0) at (%ld,%ld)\n",sp->x,sp->y);
2041 gameexit(tempbuf);
2042 }
2043 sp->owner = j;
2044 }
2045
2046 startwall = sector[sect].wallptr;
2047 endwall = startwall+sector[sect].wallnum;
2048
2049 T2 = tempwallptr;
2050 for(s=startwall;s<endwall;s++)
2051 {
2052 msx[tempwallptr] = wall[s].x-sp->x;
2053 msy[tempwallptr] = wall[s].y-sp->y;
2054 tempwallptr++;
2055 if(tempwallptr > 2047)
2056 {
2057 sprintf(tempbuf,"Too many moving sectors at (%ld,%ld).\n",wall[s].x,wall[s].y);
2058 gameexit(tempbuf);
2059 }
2060 }
2061 if( sp->lotag == 30 || sp->lotag == 6 || sp->lotag == 14 || sp->lotag == 5 )
2062 {
2063
2064 startwall = sector[sect].wallptr;
2065 endwall = startwall+sector[sect].wallnum;
2066
2067 if(sector[sect].hitag == -1)
2068 sp->extra = 0;
2069 else sp->extra = 1;
2070
2071 sector[sect].hitag = i;
2072
2073 j = 0;
2074
2075 for(s=startwall;s<endwall;s++)
2076 {
2077 if( wall[ s ].nextsector >= 0 &&
2078 sector[ wall[ s ].nextsector].hitag == 0 &&
2079 #ifdef RRRA
2080 (sector[ wall[ s ].nextsector].lotag < 3 || sector[ wall[ s ].nextsector].lotag == 160) )
2081 #else
2082 sector[ wall[ s ].nextsector].lotag < 3 )
2083 #endif
2084 {
2085 s = wall[s].nextsector;
2086 j = 1;
2087 break;
2088 }
2089 }
2090
2091 if(j == 0)
2092 {
2093 sprintf(tempbuf,"Subway found no zero'd sectors with locators\nat (%ld,%ld).\n",sp->x,sp->y);
2094 gameexit(tempbuf);
2095 }
2096
2097 sp->owner = -1;
2098 T1 = s;
2099
2100 if(sp->lotag != 30)
2101 T4 = sp->hitag;
2102 }
2103
2104 else if(sp->lotag == 16)
2105 T4 = sector[sect].ceilingz;
2106
2107 else if( sp->lotag == 26 )
2108 {
2109 T4 = sp->x;
2110 T5 = sp->y;
2111 if(sp->shade==sector[sect].floorshade) //UP
2112 sp->zvel = -256;
2113 else
2114 sp->zvel = 256;
2115
2116 sp->shade = 0;
2117 }
2118 else if( sp->lotag == 2)
2119 {
2120 T6 = sector[sp->sectnum].floorheinum;
2121 sector[sp->sectnum].floorheinum = 0;
2122 }
2123 }
2124
2125 switch(sp->lotag)
2126 {
2127 case 6:
2128 case 14:
2129 j = callsound(sect,i);
2130 if(j == -1)
2131 {
2132 if (sector[sp->sectnum].floorpal == 7)
2133 j = 456;
2134 else
2135 j = 75;
2136 }
2137 hittype[i].lastvx = j;
2138 case 30:
2139 if(numplayers > 1) break;
2140 case 0:
2141 case 1:
2142 case 5:
2143 case 11:
2144 case 15:
2145 case 16:
2146 case 26:
2147 setsectinterpolate(i);
2148 break;
2149 }
2150
2151 #ifdef RRRA
2152 switch (sprite[i].lotag)
2153 {
2154 case 150:
2155 case 151:
2156 case 152:
2157 case 153:
2158 case 154:
2159 case 155:
2160 changespritestat(i,15);
2161 break;
2162 default:
2163 changespritestat(i,3);
2164 }
2165 #else
2166 changespritestat(i,3);
2167 #endif
2168
2169 break;
2170
2171 case SEENINE:
2172 case OOZFILTER:
2173
2174 sp->shade = -16;
2175 if(sp->xrepeat <= 8)
2176 {
2177 sp->cstat = (short)32768;
2178 sp->xrepeat=sp->yrepeat=0;
2179 }
2180 else sp->cstat = 1+256;
2181 sp->extra = impact_damage<<2;
2182 sp->owner = i;
2183
2184 changespritestat(i,6);
2185 break;
2186
2187 case CRACK1:
2188 case CRACK2:
2189 case CRACK3:
2190 case CRACK4:
2191 sp->cstat |= 17;
2192 sp->extra = 1;
2193 if( ud.multimode < 2 && sp->pal != 0)
2194 {
2195 sp->xrepeat = sp->yrepeat = 0;
2196 changespritestat(i,5);
2197 break;
2198 }
2199
2200 sp->pal = 0;
2201 sp->owner = i;
2202 changespritestat(i,6);
2203 sp->xvel = 8;
2204 ssp(i,CLIPMASK0);
2205 break;
2206
2207 #ifdef RRRA
2208 case EMPTYBIKE:
2209 if (ud.multimode < 2 && sp->pal == 1)
2210 {
2211 sp->xrepeat = sp->yrepeat = 0;
2212 break;
2213 }
2214 sp->pal = 0;
2215 sp->xrepeat = 18;
2216 sp->yrepeat = 18;
2217 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
2218 sp->owner = 100;
2219 sp->cstat = 257;
2220 sp->lotag = 1;
2221 changespritestat(i,1);
2222 break;
2223 case EMPTYBOAT:
2224 if (ud.multimode < 2 && sp->pal == 1)
2225 {
2226 sp->xrepeat = sp->yrepeat = 0;
2227 break;
2228 }
2229 sp->pal = 0;
2230 sp->xrepeat = 32;
2231 sp->yrepeat = 32;
2232 sp->clipdist = mulscale7(sp->xrepeat,tilesizx[sp->picnum]);
2233 sp->owner = 20;
2234 sp->cstat = 257;
2235 sp->lotag = 1;
2236 changespritestat(i,1);
2237 break;
2238 #endif
2239
2240 case TOILET:
2241 case STALL:
2242 case RRTILE2121:
2243 case RRTILE2122:
2244 sp->lotag = 1;
2245 sp->cstat |= 257;
2246 sp->clipdist = 8;
2247 sp->owner = i;
2248 break;
2249 case CANWITHSOMETHING:
2250 case RUBBERCAN:
2251 sp->extra = 0;
2252 case EXPLODINGBARREL:
2253 case HORSEONSIDE:
2254 case FIREBARREL:
2255 case NUKEBARREL:
2256 case FIREVASE:
2257 case NUKEBARRELDENTED:
2258 case NUKEBARRELLEAKED:
2259 case WOODENHORSE:
2260
2261 if(j >= 0)
2262 sp->xrepeat = sp->yrepeat = 32;
2263 sp->clipdist = 72;
2264 makeitfall(i);
2265 if(j >= 0)
2266 sp->owner = j;
2267 else sp->owner = i;
2268 case EGG:
2269 if( ud.monsters_off == 1 && sp->picnum == EGG )
2270 {
2271 sp->xrepeat = sp->yrepeat = 0;
2272 changespritestat(i,5);
2273 }
2274 else
2275 {
2276 if(sp->picnum == EGG)
2277 sp->clipdist = 24;
2278 sp->cstat = 257|(TRAND&4);
2279 changespritestat(i,2);
2280 }
2281 break;
2282 case TOILETWATER:
2283 sp->shade = -16;
2284 changespritestat(i,6);
2285 break;
2286 case RRTILE63:
2287 sp->cstat |= 32768;
2288 sp->xrepeat = 1;
2289 sp->yrepeat = 1;
2290 sp->clipdist = 1;
2291 changespritestat(i,100);
2292 break;
2293 }
2294 return i;
2295 }
2296