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 "duke3d.h"
29
30 #include "lava.h"
31
32 // PRIMITIVE
33
34
35 char haltsoundhack;
36
callsound2(short sn,short snum)37 short callsound2(short sn, short snum)
38 {
39 short i;
40 struct player_struct *p;
41 p = &ps[snum];
42 i = p->i;
43 spritesound(sn,i);
44 return 1;
45 }
callsound(short sn,short whatsprite)46 short callsound(short sn,short whatsprite)
47 {
48 short i;
49
50 i = headspritesect[sn];
51 while(i >= 0)
52 {
53 if( PN == MUSICANDSFX && SLT < 1000 )
54 {
55 if(whatsprite == -1) whatsprite = i;
56
57 if(T1 == 0)
58 {
59 if( (soundm[SLT]&16) == 0)
60 {
61 if(SLT)
62 {
63 spritesound(SLT,whatsprite);
64 if(SHT && SLT != SHT && SHT < NUM_SOUNDS)
65 stopsound(SHT);
66 }
67
68 if( (sector[SECT].lotag&0xff) != 22)
69 T1 = 1;
70 }
71 }
72 else if(SHT < NUM_SOUNDS)
73 {
74 if(SHT) spritesound(SHT,whatsprite);
75 if( (soundm[SLT]&1) || ( SHT && SHT != SLT ) )
76 stopsound(SLT);
77 T1 = 0;
78 }
79 return SLT;
80 }
81 i = nextspritesect[i];
82 }
83 return -1;
84 }
85
86
check_activator_motion(short lotag)87 short check_activator_motion( short lotag )
88 {
89 short i, j;
90 spritetype *s;
91
92 i = headspritestat[8];
93 while ( i >= 0 )
94 {
95 if ( sprite[i].lotag == lotag )
96 {
97 s = &sprite[i];
98
99 for ( j = animatecnt-1; j >= 0; j-- )
100 if ( s->sectnum == animatesect[j] )
101 return( 1 );
102
103 j = headspritestat[3];
104 while ( j >= 0 )
105 {
106 if(s->sectnum == sprite[j].sectnum)
107 switch(sprite[j].lotag)
108 {
109 case 11:
110 case 30:
111 if ( hittype[j].temp_data[4] )
112 return( 1 );
113 break;
114 case 20:
115 case 31:
116 case 32:
117 #ifndef RRRA
118 case 18:
119 #endif
120 if ( hittype[j].temp_data[0] )
121 return( 1 );
122 break;
123 }
124
125 j = nextspritestat[j];
126 }
127 }
128 i = nextspritestat[i];
129 }
130 return( 0 );
131 }
132
isadoorwall(short dapic)133 char isadoorwall(short dapic)
134 {
135 switch(dapic)
136 {
137 case DOORTILE1:
138 case DOORTILE2:
139 case DOORTILE3:
140 case DOORTILE4:
141 case DOORTILE5:
142 case DOORTILE6:
143 case DOORTILE7:
144 case DOORTILE8:
145 case DOORTILE9:
146 case DOORTILE10:
147 case DOORTILE11:
148 case DOORTILE12:
149 case DOORTILE14:
150 case DOORTILE15:
151 case DOORTILE16:
152 case DOORTILE17:
153 case DOORTILE18:
154 case DOORTILE19:
155 case DOORTILE20:
156 case DOORTILE21:
157 case DOORTILE22:
158 case RRTILE1856:
159 case RRTILE1877:
160 return 1;
161 }
162 return 0;
163 }
164
isablockdoor(short dapic)165 char isablockdoor(short dapic)
166 {
167 switch (dapic)
168 {
169 case RRTILE1792:
170 case RRTILE1801:
171 case RRTILE1805:
172 case RRTILE1807:
173 case RRTILE1808:
174 case RRTILE1812:
175 case RRTILE1821:
176 case RRTILE1826:
177 case RRTILE1850:
178 case RRTILE1851:
179 case RRTILE1856:
180 case RRTILE1877:
181 case RRTILE1938:
182 case RRTILE1942:
183 case RRTILE1944:
184 case RRTILE1945:
185 case RRTILE1951:
186 case RRTILE1961:
187 case RRTILE1964:
188 case RRTILE1985:
189 case RRTILE1995:
190 case RRTILE2022:
191 case RRTILE2052:
192 case RRTILE2053:
193 case RRTILE2060:
194 case RRTILE2074:
195 case RRTILE2132:
196 case RRTILE2136:
197 case RRTILE2139:
198 case RRTILE2150:
199 case RRTILE2178:
200 case RRTILE2186:
201 case RRTILE2319:
202 case RRTILE2321:
203 case RRTILE2326:
204 case RRTILE2329:
205 case RRTILE2578:
206 case RRTILE2581:
207 case RRTILE2610:
208 case RRTILE2613:
209 case RRTILE2621:
210 case RRTILE2622:
211 case RRTILE2676:
212 case RRTILE2732:
213 case RRTILE2831:
214 case RRTILE2832:
215 case RRTILE2842:
216 case RRTILE2940:
217 case RRTILE2970:
218 case RRTILE3083:
219 case RRTILE3100:
220 case RRTILE3155:
221 case RRTILE3195:
222 case RRTILE3232:
223 case RRTILE3600:
224 case RRTILE3631:
225 case RRTILE3635:
226 case RRTILE3637:
227 case RRTILE3643+2:
228 case RRTILE3643+3:
229 case RRTILE3647:
230 case RRTILE3652:
231 case RRTILE3653:
232 case RRTILE3671:
233 case RRTILE3673:
234 case RRTILE3684:
235 case RRTILE3708:
236 case RRTILE3714:
237 case RRTILE3716:
238 case RRTILE3723:
239 case RRTILE3725:
240 case RRTILE3737:
241 case RRTILE3754:
242 case RRTILE3762:
243 case RRTILE3763:
244 case RRTILE3764:
245 case RRTILE3765:
246 case RRTILE3767:
247 case RRTILE3793:
248 case RRTILE3814:
249 case RRTILE3815:
250 case RRTILE3819:
251 case RRTILE3827:
252 case RRTILE3837:
253 #ifdef RRRA
254 case RRTILE1996:
255 case RRTILE2382:
256 case RRTILE2961:
257 case RRTILE3804:
258 case RRTILE7430:
259 case RRTILE7467:
260 case RRTILE7469:
261 case RRTILE7470:
262 case RRTILE7475:
263 case RRTILE7566:
264 case RRTILE7576:
265 case RRTILE7716:
266 case RRTILE8063:
267 case RRTILE8067:
268 case RRTILE8076:
269 case RRTILE8106:
270 case RRTILE8379:
271 case RRTILE8380:
272 case RRTILE8565:
273 case RRTILE8605:
274 #endif
275 return 1;
276 }
277 return 0;
278 }
279
280
isanunderoperator(short lotag)281 char isanunderoperator(short lotag)
282 {
283 switch(lotag&0xff)
284 {
285 case 15:
286 case 16:
287 case 17:
288 case 18:
289 case 19:
290 case 26:
291 return 1;
292 }
293 return 0;
294 }
295
isanearoperator(short lotag)296 char isanearoperator(short lotag)
297 {
298 switch(lotag&0xff)
299 {
300 case 9:
301 case 15:
302 case 16:
303 case 17:
304 case 18:
305 case 19:
306 case 20:
307 case 21:
308 case 22:
309 case 23:
310 case 25:
311 case 26:
312 case 29://Toothed door
313 case 41:
314 return 1;
315 }
316 return 0;
317 }
318
checkcursectnums(short sect)319 short checkcursectnums(short sect)
320 {
321 short i;
322 for(i=connecthead;i>=0;i=connectpoint2[i])
323 if( sprite[ps[i].i].sectnum == sect ) return i;
324 return -1;
325 }
326
ldist(spritetype * s1,spritetype * s2)327 long ldist(spritetype *s1,spritetype *s2)
328 {
329 long vx,vy;
330 vx = s1->x - s2->x;
331 vy = s1->y - s2->y;
332 return(FindDistance2D(vx,vy) + 1);
333 }
334
dist(spritetype * s1,spritetype * s2)335 long dist(spritetype *s1,spritetype *s2)
336 {
337 long vx,vy,vz;
338 vx = s1->x - s2->x;
339 vy = s1->y - s2->y;
340 vz = s1->z - s2->z;
341 return(FindDistance3D(vx,vy,vz>>4));
342 }
343
findplayer(spritetype * s,long * d)344 short findplayer(spritetype *s,long *d)
345 {
346 short j, closest_player;
347 long x, closest;
348
349 if(ud.multimode < 2)
350 {
351 *d = klabs(ps[myconnectindex].oposx-s->x) + klabs(ps[myconnectindex].oposy-s->y) + ((klabs(ps[myconnectindex].oposz-s->z+(28<<8)))>>4);
352 return myconnectindex;
353 }
354
355 closest = 0x7fffffff;
356 closest_player = 0;
357
358 for(j=connecthead;j>=0;j=connectpoint2[j])
359 {
360 x = klabs(ps[j].oposx-s->x) + klabs(ps[j].oposy-s->y) + ((klabs(ps[j].oposz-s->z+(28<<8)))>>4);
361 if( x < closest && sprite[ps[j].i].extra > 0 )
362 {
363 closest_player = j;
364 closest = x;
365 }
366 }
367
368 *d = closest;
369 return closest_player;
370 }
371
findotherplayer(short p,long * d)372 short findotherplayer(short p,long *d)
373 {
374 short j, closest_player;
375 long x, closest;
376
377 closest = 0x7fffffff;
378 closest_player = p;
379
380 for(j=connecthead;j>=0;j=connectpoint2[j])
381 if(p != j && sprite[ps[j].i].extra > 0)
382 {
383 x = klabs(ps[j].oposx-ps[p].posx) + klabs(ps[j].oposy-ps[p].posy) + (klabs(ps[j].oposz-ps[p].posz)>>4);
384
385 if( x < closest )
386 {
387 closest_player = j;
388 closest = x;
389 }
390 }
391
392 *d = closest;
393 return closest_player;
394 }
395
396
397
doanimations(void)398 void doanimations(void)
399 {
400 long i, j, a, p, v, dasect;
401
402 for(i=animatecnt-1;i>=0;i--)
403 {
404 a = *animateptr[i];
405 v = animatevel[i]*TICSPERFRAME;
406 dasect = animatesect[i];
407
408 if (a == animategoal[i])
409 {
410 stopinterpolation(animateptr[i]);
411
412 animatecnt--;
413 animateptr[i] = animateptr[animatecnt];
414 animategoal[i] = animategoal[animatecnt];
415 animatevel[i] = animatevel[animatecnt];
416 animatesect[i] = animatesect[animatecnt];
417 if( sector[animatesect[i]].lotag == 18 || sector[animatesect[i]].lotag == 19 )
418 if(animateptr[i] == §or[animatesect[i]].ceilingz)
419 continue;
420
421 if( (sector[dasect].lotag&0xff) != 22 )
422 callsound(dasect,-1);
423
424 continue;
425 }
426
427 if (v > 0) { a = min(a+v,animategoal[i]); }
428 else { a = max(a+v,animategoal[i]); }
429
430 if( animateptr[i] == §or[animatesect[i]].floorz)
431 {
432 for(p=connecthead;p>=0;p=connectpoint2[p])
433 if (ps[p].cursectnum == dasect)
434 if ((sector[dasect].floorz-ps[p].posz) < (64<<8))
435 if (sprite[ps[p].i].owner >= 0)
436 {
437 ps[p].posz += v;
438 ps[p].poszv = 0;
439 if (p == myconnectindex)
440 {
441 myz += v;
442 myzvel = 0;
443 myzbak[((movefifoplc-1)&(MOVEFIFOSIZ-1))] = ps[p].posz;
444 }
445 }
446
447 for(j=headspritesect[dasect];j>=0;j=nextspritesect[j])
448 if (sprite[j].statnum != 3)
449 {
450 hittype[j].bposz = sprite[j].z;
451 sprite[j].z += v;
452 hittype[j].floorz = sector[dasect].floorz+v;
453 }
454 }
455
456 *animateptr[i] = a;
457 }
458 }
459
getanimationgoal(long * animptr)460 getanimationgoal(long *animptr)
461 {
462 long i, j;
463
464 j = -1;
465 for(i=animatecnt-1;i>=0;i--)
466 if (animptr == (long *)animateptr[i])
467 {
468 j = i;
469 break;
470 }
471 return(j);
472 }
473
setanimation(short animsect,long * animptr,long thegoal,long thevel)474 setanimation(short animsect,long *animptr, long thegoal, long thevel)
475 {
476 long i, j;
477
478 if (animatecnt >= MAXANIMATES-1)
479 return(-1);
480
481 j = animatecnt;
482 for(i=0;i<animatecnt;i++)
483 if (animptr == animateptr[i])
484 {
485 j = i;
486 break;
487 }
488
489 animatesect[j] = animsect;
490 animateptr[j] = animptr;
491 animategoal[j] = thegoal;
492 if (thegoal >= *animptr)
493 animatevel[j] = thevel;
494 else
495 animatevel[j] = -thevel;
496
497 if (j == animatecnt) animatecnt++;
498
499 setinterpolation(animptr);
500
501 return(j);
502 }
503
504
505
506
animatecamsprite(void)507 void animatecamsprite(void)
508 {
509 short i;
510
511 if(camsprite <= 0) return;
512
513 i = camsprite;
514
515 if(T1 >= 11)
516 {
517 T1 = 0;
518
519 if(ps[screenpeek].newowner >= 0)
520 OW = ps[screenpeek].newowner;
521
522 else if(OW >= 0 && dist(&sprite[ps[screenpeek].i],&sprite[i]) < 2048)
523 xyzmirror(OW,PN);
524 }
525 else T1++;
526 }
527
animatewalls(void)528 void animatewalls(void)
529 {
530 long i, j, p, t;
531
532 #ifdef RRRA
533 if (ps[screenpeek].raat5dd == 1)
534 {
535 for (i = 0; i < MAXWALLS; i++)
536 {
537 if (wall[i].picnum == RRTILE7873)
538 wall[i].xpanning += 6;
539 else if (wall[i].picnum == RRTILE7870)
540 wall[i].xpanning += 6;
541 }
542 }
543 #endif
544
545 for(p=0;p < numanimwalls ;p++)
546 // for(p=numanimwalls-1;p>=0;p--)
547 {
548 i = animwall[p].wallnum;
549 j = wall[i].picnum;
550
551 switch(j)
552 {
553 case SCREENBREAK1:
554 case SCREENBREAK2:
555 case SCREENBREAK3:
556 case SCREENBREAK4:
557 case SCREENBREAK5:
558
559 case SCREENBREAK9:
560 case SCREENBREAK10:
561 case SCREENBREAK11:
562 case SCREENBREAK12:
563 case SCREENBREAK13:
564
565 if( (TRAND&255) < 16)
566 {
567 animwall[p].tag = wall[i].picnum;
568 wall[i].picnum = SCREENBREAK6;
569 }
570
571 continue;
572
573 case SCREENBREAK6:
574 case SCREENBREAK7:
575 case SCREENBREAK8:
576
577 if(animwall[p].tag >= 0)
578 wall[i].picnum = animwall[p].tag;
579 else
580 {
581 wall[i].picnum++;
582 if(wall[i].picnum == (SCREENBREAK6+3) )
583 wall[i].picnum = SCREENBREAK6;
584 }
585 continue;
586
587 }
588
589 if(wall[i].cstat&16)
590 switch(wall[i].overpicnum)
591 {
592 case W_FORCEFIELD:
593 case W_FORCEFIELD+1:
594 case W_FORCEFIELD+2:
595
596 t = animwall[p].tag;
597
598 if(wall[i].cstat&254)
599 {
600 wall[i].xpanning -= t>>10; // sintable[(t+512)&2047]>>12;
601 wall[i].ypanning -= t>>10; // sintable[t&2047]>>12;
602
603 if(wall[i].extra == 1)
604 {
605 wall[i].extra = 0;
606 animwall[p].tag = 0;
607 }
608 else
609 animwall[p].tag+=128;
610
611 if( animwall[p].tag < (128<<4) )
612 {
613 if( animwall[p].tag&128 )
614 wall[i].overpicnum = W_FORCEFIELD;
615 else wall[i].overpicnum = W_FORCEFIELD+1;
616 }
617 else
618 {
619 if( (TRAND&255) < 32 )
620 animwall[p].tag = 128<<(TRAND&3);
621 else wall[i].overpicnum = W_FORCEFIELD+1;
622 }
623 }
624
625 break;
626 }
627 }
628 }
629
activatewarpelevators(short s,short d)630 char activatewarpelevators(short s,short d) //Parm = sectoreffectornum
631 {
632 short i, sn;
633
634 sn = sprite[s].sectnum;
635
636 // See if the sector exists
637
638 i = headspritestat[3];
639 while(i >= 0)
640 {
641 #ifdef RRRA
642 if( SLT == 17 || SLT == 18 )
643 #else
644 if( SLT == 17 )
645 #endif
646 if( SHT == sprite[s].hitag )
647 if( (klabs(sector[sn].floorz-hittype[s].temp_data[2]) > SP) ||
648 (sector[SECT].hitag == (sector[sn].hitag-d) ) )
649 break;
650 i = nextspritestat[i];
651 }
652
653 if(i==-1)
654 {
655 d = 0;
656 return 1; // No find
657 }
658 else
659 {
660 if(d == 0)
661 spritesound(ELEVATOR_OFF,s);
662 else spritesound(ELEVATOR_ON,s);
663 }
664
665
666 i = headspritestat[3];
667 while(i >= 0)
668 {
669 #ifdef RRRA
670 if( SLT == 17 || SLT == 18 )
671 #else
672 if( SLT == 17 )
673 #endif
674 if( SHT == sprite[s].hitag )
675 {
676 T1 = d;
677 T2 = d; //Make all check warp
678 }
679 i = nextspritestat[i];
680 }
681 return 0;
682 }
683
684
685
operatesectors(short sn,short ii)686 void operatesectors(short sn,short ii)
687 {
688 long j, l, q, startwall, endwall;
689 long u6,u7;
690 short i;
691 char sect_error;
692 sectortype *sptr;
693
694 long u1,u2,u3,u4,u5;
695
696 sect_error = 0;
697 sptr = §or[sn];
698
699 switch(sptr->lotag&(0xffff-49152))
700 {
701
702 case 41:
703 for (i = 0; i < jaildoorcnt; i++)
704 {
705 if (jaildoorsecthtag[i] == sptr->hitag)
706 {
707 if (jaildooropen[i] == 0)
708 {
709 jaildooropen[i] = 1;
710 jaildoordrag[i] = jaildoordist[i];
711 #ifdef RRRA
712 if (jaildoorsound[i] != 0)
713 #endif
714 callsound2(jaildoorsound[i],screenpeek);
715 }
716 if (jaildooropen[i] == 2)
717 {
718 jaildooropen[i] = 3;
719 jaildoordrag[i] = jaildoordist[i];
720 #ifdef RRRA
721 if (jaildoorsound[i] != 0)
722 #endif
723 callsound2(jaildoorsound[i],screenpeek);
724 }
725 }
726 }
727 break;
728
729 case 7:
730 startwall = sptr->wallptr;
731 endwall = startwall+sptr->wallnum;
732 for (j = startwall; j < endwall; j++)
733 {
734 setanimation(sn,&wall[j].x,wall[j].x+1024,4);
735 setanimation(sn,&wall[wall[j].nextwall].x,wall[wall[j].nextwall].x+1024,4);
736 }
737 break;
738
739 case 30:
740 j = sector[sn].hitag;
741 if( hittype[j].tempang == 0 ||
742 hittype[j].tempang == 256)
743 callsound(sn,ii);
744 if(sprite[j].extra == 1)
745 sprite[j].extra = 3;
746 else sprite[j].extra = 1;
747 break;
748
749 case 31:
750
751 j = sector[sn].hitag;
752 if(hittype[j].temp_data[4] == 0)
753 hittype[j].temp_data[4] = 1;
754
755 callsound(sn,ii);
756 break;
757
758 case 26: //The split doors
759 i = getanimationgoal(&sptr->ceilingz);
760 if(i == -1) //if the door has stopped
761 {
762 haltsoundhack = 1;
763 sptr->lotag &= 0xff00;
764 sptr->lotag |= 22;
765 operatesectors(sn,ii);
766 sptr->lotag &= 0xff00;
767 sptr->lotag |= 9;
768 operatesectors(sn,ii);
769 sptr->lotag &= 0xff00;
770 sptr->lotag |= 26;
771 }
772 return;
773
774 case 9:
775 {
776 long dax,day,dax2,day2,sp;
777 long wallfind[2];
778
779 startwall = sptr->wallptr;
780 endwall = startwall+sptr->wallnum-1;
781
782 sp = sptr->extra>>4;
783
784 //first find center point by averaging all points
785 dax = 0L, day = 0L;
786 for(i=startwall;i<=endwall;i++)
787 {
788 dax += wall[i].x;
789 day += wall[i].y;
790 }
791 dax /= (endwall-startwall+1);
792 day /= (endwall-startwall+1);
793
794 //find any points with either same x or same y coordinate
795 // as center (dax, day) - should be 2 points found.
796 wallfind[0] = -1;
797 wallfind[1] = -1;
798 for(i=startwall;i<=endwall;i++)
799 if ((wall[i].x == dax) || (wall[i].y == day))
800 {
801 if (wallfind[0] == -1)
802 wallfind[0] = i;
803 else wallfind[1] = i;
804 }
805
806 for(j=0;j<2;j++)
807 {
808 if ((wall[wallfind[j]].x == dax) && (wall[wallfind[j]].y == day))
809 {
810 //find what direction door should open by averaging the
811 // 2 neighboring points of wallfind[0] & wallfind[1].
812 i = wallfind[j]-1; if (i < startwall) i = endwall;
813 dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
814 day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
815 if (dax2 != 0)
816 {
817 dax2 = wall[wall[wall[wallfind[j]].point2].point2].x;
818 dax2 -= wall[wall[wallfind[j]].point2].x;
819 setanimation(sn,&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,sp);
820 setanimation(sn,&wall[i].x,wall[i].x+dax2,sp);
821 setanimation(sn,&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,sp);
822 callsound(sn,ii);
823 }
824 else if (day2 != 0)
825 {
826 day2 = wall[wall[wall[wallfind[j]].point2].point2].y;
827 day2 -= wall[wall[wallfind[j]].point2].y;
828 setanimation(sn,&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,sp);
829 setanimation(sn,&wall[i].y,wall[i].y+day2,sp);
830 setanimation(sn,&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,sp);
831 callsound(sn,ii);
832 }
833 }
834 else
835 {
836 i = wallfind[j]-1; if (i < startwall) i = endwall;
837 dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
838 day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
839 if (dax2 != 0)
840 {
841 setanimation(sn,&wall[wallfind[j]].x,dax,sp);
842 setanimation(sn,&wall[i].x,dax+dax2,sp);
843 setanimation(sn,&wall[wall[wallfind[j]].point2].x,dax+dax2,sp);
844 callsound(sn,ii);
845 }
846 else if (day2 != 0)
847 {
848 setanimation(sn,&wall[wallfind[j]].y,day,sp);
849 setanimation(sn,&wall[i].y,day+day2,sp);
850 setanimation(sn,&wall[wall[wallfind[j]].point2].y,day+day2,sp);
851 callsound(sn,ii);
852 }
853 }
854 }
855
856 }
857 return;
858
859 case 15://Warping elevators
860
861 if(sprite[ii].picnum != APLAYER) return;
862 // if(ps[sprite[ii].yvel].select_dir == 1) return;
863
864 i = headspritesect[sn];
865 while(i >= 0)
866 {
867 if(PN==SECTOREFFECTOR && SLT == 17 ) break;
868 i = nextspritesect[i];
869 }
870
871 if(sprite[ii].sectnum == sn)
872 {
873 if( activatewarpelevators(i,-1) )
874 activatewarpelevators(i,1);
875 else if( activatewarpelevators(i,1) )
876 activatewarpelevators(i,-1);
877 return;
878 }
879 else
880 {
881 if(sptr->floorz > SZ)
882 activatewarpelevators(i,-1);
883 else
884 activatewarpelevators(i,1);
885 }
886
887 return;
888
889 case 16:
890 case 17:
891
892 i = getanimationgoal(&sptr->floorz);
893
894 if(i == -1)
895 {
896 i = nextsectorneighborz(sn,sptr->floorz,1,1);
897 if( i == -1 )
898 {
899 i = nextsectorneighborz(sn,sptr->floorz,1,-1);
900 if( i == -1 ) return;
901 j = sector[i].floorz;
902 setanimation(sn,&sptr->floorz,j,sptr->extra);
903 }
904 else
905 {
906 j = sector[i].floorz;
907 setanimation(sn,&sptr->floorz,j,sptr->extra);
908 }
909 callsound(sn,ii);
910 }
911
912 return;
913
914 case 18:
915 case 19:
916
917 i = getanimationgoal(&sptr->floorz);
918
919 if(i==-1)
920 {
921 i = nextsectorneighborz(sn,sptr->floorz,1,-1);
922 if(i==-1) i = nextsectorneighborz(sn,sptr->floorz,1,1);
923 if(i==-1) return;
924 j = sector[i].floorz;
925 q = sptr->extra;
926 l = sptr->ceilingz-sptr->floorz;
927 setanimation(sn,&sptr->floorz,j,q);
928 setanimation(sn,&sptr->ceilingz,j+l,q);
929 callsound(sn,ii);
930 }
931 return;
932
933 case 29:
934
935 if(sptr->lotag&0x8000)
936 j = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz;
937 else
938 j = sector[nextsectorneighborz(sn,sptr->ceilingz,-1,-1)].ceilingz;
939
940 i = headspritestat[3]; //Effectors
941 while(i >= 0)
942 {
943 if( (SLT == 22) &&
944 (SHT == sptr->hitag) )
945 {
946 sector[SECT].extra = -sector[SECT].extra;
947
948 T1 = sn;
949 T2 = 1;
950 }
951 i = nextspritestat[i];
952 }
953
954 sptr->lotag ^= 0x8000;
955
956 setanimation(sn,&sptr->ceilingz,j,sptr->extra);
957
958 callsound(sn,ii);
959
960 return;
961
962 case 20:
963
964 REDODOOR:
965
966 if(sptr->lotag&0x8000)
967 {
968 i = headspritesect[sn];
969 while(i >= 0)
970 {
971 if(sprite[i].statnum == 3 && SLT==9)
972 {
973 j = SZ;
974 break;
975 }
976 i = nextspritesect[i];
977 }
978 if(i==-1)
979 j = sptr->floorz;
980 }
981 else
982 {
983 j = nextsectorneighborz(sn,sptr->ceilingz,-1,-1);
984
985 if(j >= 0) j = sector[j].ceilingz;
986 else
987 {
988 sptr->lotag |= 32768;
989 goto REDODOOR;
990 }
991 }
992
993 sptr->lotag ^= 0x8000;
994
995 setanimation(sn,&sptr->ceilingz,j,sptr->extra);
996 callsound(sn,ii);
997
998 return;
999
1000 case 21:
1001 i = getanimationgoal(&sptr->floorz);
1002 if (i >= 0)
1003 {
1004 if (animategoal[sn] == sptr->ceilingz)
1005 animategoal[i] = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz;
1006 else animategoal[i] = sptr->ceilingz;
1007 j = animategoal[i];
1008 }
1009 else
1010 {
1011 if (sptr->ceilingz == sptr->floorz)
1012 j = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz;
1013 else j = sptr->ceilingz;
1014
1015 sptr->lotag ^= 0x8000;
1016
1017 if(setanimation(sn,&sptr->floorz,j,sptr->extra) >= 0)
1018 callsound(sn,ii);
1019 }
1020 return;
1021
1022 case 22:
1023
1024 // REDODOOR22:
1025
1026 if ( (sptr->lotag&0x8000) )
1027 {
1028 q = (sptr->ceilingz+sptr->floorz)>>1;
1029 j = setanimation(sn,&sptr->floorz,q,sptr->extra);
1030 j = setanimation(sn,&sptr->ceilingz,q,sptr->extra);
1031 }
1032 else
1033 {
1034 q = sector[nextsectorneighborz(sn,sptr->floorz,1,1)].floorz;
1035 j = setanimation(sn,&sptr->floorz,q,sptr->extra);
1036 q = sector[nextsectorneighborz(sn,sptr->ceilingz,-1,-1)].ceilingz;
1037 j = setanimation(sn,&sptr->ceilingz,q,sptr->extra);
1038 }
1039
1040 sptr->lotag ^= 0x8000;
1041
1042 callsound(sn,ii);
1043
1044 return;
1045
1046 case 23: //Swingdoor
1047
1048 j = -1;
1049 q = 0;
1050
1051 i = headspritestat[3];
1052 while(i >= 0)
1053 {
1054 if( SLT == 11 && SECT == sn && !T5)
1055 {
1056 j = i;
1057 break;
1058 }
1059 i = nextspritestat[i];
1060 }
1061
1062 l = sector[SECT].lotag&0x8000;
1063
1064 if(j >= 0)
1065 {
1066 i = headspritestat[3];
1067 while(i >= 0)
1068 {
1069 if( l == (sector[SECT].lotag&0x8000) && SLT == 11 && sprite[j].hitag == SHT && !T5 )
1070 {
1071 if(sector[SECT].lotag&0x8000) sector[SECT].lotag &= 0x7fff;
1072 else sector[SECT].lotag |= 0x8000;
1073 T5 = 1;
1074 T4 = -T4;
1075 if(q == 0)
1076 {
1077 callsound(sn,i);
1078 q = 1;
1079 }
1080 }
1081 i = nextspritestat[i];
1082 }
1083 }
1084 return;
1085
1086 case 25: //Subway type sliding doors
1087
1088 j = headspritestat[3];
1089 while(j >= 0)//Find the sprite
1090 {
1091 if( (sprite[j].lotag) == 15 && sprite[j].sectnum == sn )
1092 break; //Found the sectoreffector.
1093 j = nextspritestat[j];
1094 }
1095
1096 if(j < 0)
1097 return;
1098
1099 i = headspritestat[3];
1100 while(i >= 0)
1101 {
1102 if( SHT==sprite[j].hitag )
1103 {
1104 if( SLT == 15 )
1105 {
1106 sector[SECT].lotag ^= 0x8000; // Toggle the open or close
1107 SA += 1024;
1108 if(T5) callsound(SECT,i);
1109 callsound(SECT,i);
1110 if(sector[SECT].lotag&0x8000) T5 = 1;
1111 else T5 = 2;
1112 }
1113 }
1114 i = nextspritestat[i];
1115 }
1116 return;
1117
1118 case 27: //Extended bridge
1119
1120 j = headspritestat[3];
1121 while(j >= 0)
1122 {
1123 if( (sprite[j].lotag&0xff)==20 && sprite[j].sectnum == sn) //Bridge
1124 {
1125
1126 sector[sn].lotag ^= 0x8000;
1127 if(sector[sn].lotag&0x8000) //OPENING
1128 hittype[j].temp_data[0] = 1;
1129 else hittype[j].temp_data[0] = 2;
1130 callsound(sn,ii);
1131 break;
1132 }
1133 j = nextspritestat[j];
1134 }
1135 return;
1136
1137
1138 case 28:
1139 //activate the rest of them
1140
1141 j = headspritesect[sn];
1142 while(j >= 0)
1143 {
1144 if(sprite[j].statnum==3 && (sprite[j].lotag&0xff)==21)
1145 break; //Found it
1146 j = nextspritesect[j];
1147 }
1148
1149 j = sprite[j].hitag;
1150
1151 l = headspritestat[3];
1152 while(l >= 0)
1153 {
1154 if( (sprite[l].lotag&0xff)==21 && !hittype[l].temp_data[0] &&
1155 (sprite[l].hitag) == j )
1156 hittype[l].temp_data[0] = 1;
1157 l = nextspritestat[l];
1158 }
1159 callsound(sn,ii);
1160
1161 return;
1162 }
1163 }
1164
1165
1166
operaterespawns(short low)1167 void operaterespawns(short low)
1168 {
1169 short i, j, nexti;
1170
1171 i = headspritestat[11];
1172 while(i >= 0)
1173 {
1174 nexti = nextspritestat[i];
1175 if(SLT == low) switch(PN)
1176 {
1177 case RESPAWN:
1178 if( badguypic(SHT) && ud.monsters_off ) break;
1179
1180 j = spawn(i,TRANSPORTERSTAR);
1181 sprite[j].z -= (32<<8);
1182
1183 sprite[i].extra = 66-12; // Just a way to killit
1184 break;
1185 #ifdef RRRA
1186 case RRTILE7424:
1187 if (!ud.monsters_off)
1188 changespritestat(i,119);
1189 break;
1190
1191 #endif
1192 }
1193 i = nexti;
1194 }
1195 }
1196