1 /***************************************************************************
2 * TEKTAG.C - Tag specific code for TEKWAR game *
3 * *
4 * *
5 ***************************************************************************/
6
7 #include "build.h"
8 #include "names.h"
9 #include "pragmas.h"
10 #include "mmulti.h"
11
12 #include "tekwar.h"
13
14 #define AMBUPDATEDIST 4000L
15
16 #define BOBBMAX 512
17 #define BOBBDELTA 128
18
19 int headbobon=1;
20 int headbob,bobstep=BOBBDELTA;
21
22 #define VEHICLEHEIGHT -13312
23
24 #define MAXANIMPICS 32
25 #define MAXDELAYFUNCTIONS 32
26
27 #define BLUEKEYITEM 0
28 #define REDKEYITEM 1
29 #define ELEVACTIVATED 31
30
31 #define DOORUPTAG 6
32 #define DOORDOWNTAG 7
33 #define DOORSPLITHOR 8
34 #define DOORSPLITVER 9
35 #define DOORSWINGTAG 13
36 #define DOORREVOLVETAG 14 // sector tags
37
38 #define PLATFORMELEVTAG 1000 // additional sector tags
39 #define BOXELEVTAG 1003
40 #define PLATFORMDELAYTAG 1004
41 #define BOXDELAYTAG 1005
42 #define DOORFLOORTAG 1006
43 #define PLATFORMDROPTAG 1007
44
45 #define DST_BAYDOOR 10
46 #define DST_HYDRAULICDOOR 20
47 #define DST_ELEVATORDOOR 30
48 #define DST_MATRIXDOOR1 40
49 #define DST_MATRIXDOOR2 50
50 #define DST_MATRIXDOOR3 60
51 #define DST_MATRIXDOOR4 70
52
53 #define SPRITEELEVATORTAG 1500
54
55 #define PULSELIGHT 0 // sector effect tags flags32[]
56 #define FLICKERLIGHT 1
57 #define DELAYEFFECT 2
58 #define WPANNING 3
59 #define FPANNING 4
60 #define CPANNING 5
61 #define FLICKERDELAY 6
62 #define BLINKDELAY 7
63 #define STEADYLIGHT 8
64 #define WARPSECTOR 9
65 #define KILLSECTOR 10
66 #define DOORSPEEDEFFECT 11
67 #define QUICKCLOSE 12
68 #define SOUNDON 13
69 #define SOUNDOFF 14
70 #define DOORSUBTYPE 15
71
72 #define DOORDELAY (CLKIPS*4)
73 #define DOORSPEED 128L
74 #define ELEVSPEED 256L
75
76 char onelev[MAXPLAYERS];
77
78 struct sectoreffect {
79 unsigned int sectorflags;
80 int animate;
81 int hi,lo;
82 int delay,delayreset;
83 int ang;
84 int triggerable;
85 int warpto;
86 int warpx,warpy,warpz;
87 int sin,cos;
88 short damage;
89 };
90 struct sectoreffect sectoreffect[MAXSECTORS];
91 struct sectoreffect *septrlist[MAXSECTORS];
92 int secnt,sexref[MAXSECTORS];
93
94 #define MAXDOORS 200
95 enum {
96 D_NOTHING=0,
97 D_OPENDOOR,
98 D_CLOSEDOOR,
99 D_OPENING,
100 D_CLOSING,
101 D_WAITING,
102 D_SHUTSOUND,
103 D_OPENSOUND
104 };
105 enum {
106 DOORCLOSED=0,
107 DOOROPENING,
108 DOOROPENED,
109 DOORCLOSING
110 };
111 struct doortype {
112 int type;
113 int state;
114 int sector;
115 int step;
116 int delay;
117 int goalz[4];
118 int points[4];
119 int walls[8];
120 int centx;
121 int centy;
122 int centz;
123 int subtype; // jeff added 9-20
124 };
125 struct doortype doortype[MAXDOORS];
126 struct doortype *doorptr[MAXDOORS];
127 int doorxref[MAXSECTORS],numdoors;
128
129 #define MAXFLOORDOORS 25
130 struct floordoor {
131 int state;
132 int sectnum;
133 int wall1,wall2;
134 int dist1,dist2;
135 int dir;
136 };
137 struct floordoor floordoor[MAXFLOORDOORS];
138 struct floordoor *floordoorptr[MAXFLOORDOORS];
139 int fdxref[MAXSECTORS],numfloordoors;
140
141 #define MAXSECTORVEHICLES 10
142 #define MAXVEHICLEPOINTS 200
143 #define MAXVEHICLETRACKS 50
144 #define MAXVEHICLESECTORS 30
145 #define SECTORVEHICLETAG 1010
146 struct sectorvehicle {
147 short acceleration,accelto;
148 short speed,speedto,movespeed;
149 short angle,angleto;
150 int pivotx,pivoty;
151 short numpoints;
152 short point[MAXVEHICLEPOINTS];
153 int pointx[MAXVEHICLEPOINTS];
154 int pointy[MAXVEHICLEPOINTS];
155 short track;
156 short tracknum;
157 int trackx[MAXVEHICLETRACKS];
158 int tracky[MAXVEHICLETRACKS];
159 char stop[MAXVEHICLETRACKS];
160 int distx,disty;
161 short sector[MAXVEHICLESECTORS];
162 short numsectors;
163 int waittics,waitdelay;
164 short stoptrack;
165 short killw[4];
166 int soundindex;
167 };
168 struct sectorvehicle sectorvehicle[MAXSECTORVEHICLES];
169 struct sectorvehicle *sectvehptr[MAXSECTORVEHICLES];
170 int numvehicles;
171
172 #define MAXSPRITEELEVS 25
173 #define MAXPARTS 20
174 #define MAXELEVFLOORS 20
175 #define MAXELEVDOORS 4
176 enum {
177 E_OPENINGDOOR=0,
178 E_CLOSINGDOOR,
179 E_WAITING,
180 E_MOVING,
181 E_NEXTFLOOR
182 };
183 enum {
184 E_GOINGUP=0,
185 E_GOINGDOWN
186 };
187 #define E_WAITDELAY CLKIPS*4
188 #define E_DOOROPENPOS 15360
189 struct elevatortype {
190 int hilevel;
191 int lolevel;
192 };
193 struct elevatortype elevator[MAXSECTORS];
194 struct elevatortype *evptrlist[MAXSECTORS];
195
196 struct spriteelev {
197 int state;
198 int parts;
199 int sprnum[MAXPARTS];
200 int door[MAXELEVDOORS];
201 int doorpos;
202 int startz[MAXPARTS];
203 int floorz[MAXELEVFLOORS];
204 int curfloor;
205 int curdir;
206 int delay;
207 int floors;
208 int floorpos;
209 int doors;
210 };
211 struct spriteelev spriteelev[MAXSPRITEELEVS];
212 struct spriteelev *sprelevptr[MAXSPRITEELEVS];
213 int sprelevcnt;
214
215 uint32_t flags32[32]={
216 0x80000000,0x40000000,0x20000000,0x10000000,
217 0x08000000,0x04000000,0x02000000,0x01000000,
218 0x00800000,0x00400000,0x00200000,0x00100000,
219 0x00080000,0x00040000,0x00020000,0x00010000,
220 0x00008000,0x00004000,0x00002000,0x00001000,
221 0x00000800,0x00000400,0x00000200,0x00000100,
222 0x00000080,0x00000040,0x00000020,0x00000010,
223 0x00000008,0x00000004,0x00000002,0x00000001
224 };
225
226 #define MAXMAPSOUNDFX 32
227 #define MAP_SFX_AMBIENT 0
228 #define MAP_SFX_SECTOR 1
229 #define MAP_SFX_TOGGLED 2
230 #define MAP_SFX_TURN_ON 3
231 #define MAP_SFX_TURN_OFF 4
232 struct mapsndfxtype {
233 int x,y;
234 short sector;
235 int snum;
236 int loops;
237 int type;
238 int id;
239 };
240 struct mapsndfxtype mapsndfx[MAXMAPSOUNDFX];
241 struct mapsndfxtype *mapsndfxptr[MAXMAPSOUNDFX];
242 int totalmapsndfx=0;
243
244 int ambupdateclock;
245
246 struct animpic {
247 short frames;
248 short *pic;
249 short tics;
250 int nextclock;
251 } animpic[MAXANIMPICS],*animpicptr[MAXANIMPICS];
252
253 struct delayfunc {
254 void (*func)(short);
255 int tics;
256 short parm;
257 } delayfunc[MAXDELAYFUNCTIONS],*delayfuncptr[MAXDELAYFUNCTIONS];
258
259 int subwaystopdir[4] = { 1L, 1L, 1L, 1L };
260 void checktoggledmapsndfx(short dasect) ;
261 int numanimates;
262 short numdelayfuncs;
263 int loopinsound=-1;
264 int baydoorloop=-1;
265 int ambsubloop=-1;
266
267 void
operatesector(short dasector)268 operatesector(short dasector)
269 { //Door code
270 int i, j, datag;
271 int dax2, day2, centx, centy;
272 short startwall, endwall, wallfind[2];
273
274 datag = sector[dasector].lotag;
275
276 // lights out / on
277 if( datag == 33 ) {
278 if( sectptr[dasector]->visibility >= 212 ) {
279 sectptr[dasector]->visibility=0;
280 }
281 else {
282 sectptr[dasector]->visibility=212;
283 }
284 return;
285 }
286
287 startwall = sector[dasector].wallptr;
288 endwall = startwall + sector[dasector].wallnum - 1;
289 centx = 0L, centy = 0L;
290 for(i=startwall;i<=endwall;i++)
291 {
292 centx += wall[i].x;
293 centy += wall[i].y;
294 }
295 centx /= (endwall-startwall+1);
296 centy /= (endwall-startwall+1);
297
298 // kens swinging door
299 if( datag == 13 ) {
300 for( i=0; i<swingcnt; i++ ) {
301 if( swingsector[i] == dasector ) {
302 if( swinganginc[i] == 0 ) {
303 if( swingang[i] == swingangclosed[i] ) {
304 swinganginc[i] = swingangopendir[i];
305 }
306 else {
307 swinganginc[i] = -swingangopendir[i];
308 }
309 }
310 else {
311 swinganginc[i] = -swinganginc[i];
312 }
313 }
314 }
315 }
316
317 // kens true sideways double-sliding door
318 if( datag == 16 ) {
319 // get 2 closest line segments to center (dax, day)
320 wallfind[0] = -1;
321 wallfind[1] = -1;
322 for( i=startwall;i<=endwall;i++ )
323 if (wall[i].lotag == 6)
324 {
325 if (wallfind[0] == -1)
326 wallfind[0] = i;
327 else
328 wallfind[1] = i;
329 }
330
331 for(j=0;j<2;j++)
332 {
333 if ((((wall[wallfind[j]].x+wall[wall[wallfind[j]].point2].x)>>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy))
334 { //door was closed
335 //find what direction door should open
336 i = wallfind[j]-1; if (i < startwall) i = endwall;
337 dax2 = wall[i].x-wall[wallfind[j]].x;
338 day2 = wall[i].y-wall[wallfind[j]].y;
339 if (dax2 != 0)
340 {
341 dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x;
342 dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x;
343 setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L);
344 setanimation(&wall[i].x,wall[i].x+dax2,4L,0L);
345 setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L);
346 setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L);
347 }
348 else if (day2 != 0)
349 {
350 day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y;
351 day2 -= wall[wall[wall[wallfind[j]].point2].point2].y;
352 setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L);
353 setanimation(&wall[i].y,wall[i].y+day2,4L,0L);
354 setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L);
355 setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L);
356 }
357 }
358 else
359 { //door was not closed
360 i = wallfind[j]-1; if (i < startwall) i = endwall;
361 dax2 = wall[i].x-wall[wallfind[j]].x;
362 day2 = wall[i].y-wall[wallfind[j]].y;
363 if (dax2 != 0)
364 {
365 setanimation(&wall[wallfind[j]].x,centx,4L,0L);
366 setanimation(&wall[i].x,centx+dax2,4L,0L);
367 setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L);
368 setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L);
369 }
370 else if (day2 != 0)
371 {
372 setanimation(&wall[wallfind[j]].y,centy,4L,0L);
373 setanimation(&wall[i].y,centy+day2,4L,0L);
374 setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L);
375 setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L);
376 }
377 }
378 }
379 }
380
381 tekoperatesector(dasector);
382 }
383
384
385 void
tagcode()386 tagcode()
387 {
388 int i, j, k, l, s, dax, day, cnt, good;
389 short startwall, endwall, dasector, p, oldang;
390
391 for(i=0;i<warpsectorcnt;i++)
392 {
393 dasector = warpsectorlist[i];
394 j = ((lockclock&127)>>2);
395 if (j >= 16) j = 31-j;
396 {
397 sector[dasector].ceilingshade = j;
398 sector[dasector].floorshade = j;
399 startwall = sector[dasector].wallptr;
400 endwall = startwall+sector[dasector].wallnum-1;
401 for(s=startwall;s<=endwall;s++)
402 wall[s].shade = j;
403 }
404 }
405
406 for(p=connecthead;p>=0;p=connectpoint2[p])
407 if (sector[cursectnum[p]].lotag == 10) //warp sector
408 {
409 if (cursectnum[p] != ocursectnum[p])
410 {
411 warpsprite(playersprite[p]);
412 posx[p] = sprite[playersprite[p]].x;
413 posy[p] = sprite[playersprite[p]].y;
414 posz[p] = sprite[playersprite[p]].z;
415 ang[p] = sprite[playersprite[p]].ang;
416 cursectnum[p] = sprite[playersprite[p]].sectnum;
417 sprite[playersprite[p]].z += (KENSPLAYERHEIGHT<<8);
418 }
419 }
420
421
422 for( i=0; i<xpanningsectorcnt; i++ ) {
423 dasector = xpanningsectorlist[i];
424 startwall = sector[dasector].wallptr;
425 endwall = startwall+sector[dasector].wallnum-1;
426 for( s=startwall; s<=endwall; s++ ) {
427 wall[s].xpanning = ((lockclock>>2)&255);
428 }
429 }
430
431 for( i=0; i<ypanningwallcnt; i++ ) {
432 wall[ypanningwalllist[i]].ypanning = ~(lockclock&255);
433 }
434
435 for( i=0; i<rotatespritecnt; i++ ) {
436 sprite[rotatespritelist[i]].ang += (TICSPERFRAME<<2);
437 sprite[rotatespritelist[i]].ang &= 2047;
438 }
439
440 // kens slime floor
441 for( i=0; i<floorpanningcnt; i++ ) {
442 sector[floorpanninglist[i]].floorxpanning = ((lockclock>>2)&255);
443 sector[floorpanninglist[i]].floorypanning = ((lockclock>>2)&255);
444 }
445
446 for( i=0; i<dragsectorcnt; i++ ) {
447 dasector = dragsectorlist[i];
448 startwall = sector[dasector].wallptr;
449 endwall = startwall+sector[dasector].wallnum-1;
450 if (wall[startwall].x+dragxdir[i] < dragx1[i]) dragxdir[i] = 16;
451 if (wall[startwall].y+dragydir[i] < dragy1[i]) dragydir[i] = 16;
452 if (wall[startwall].x+dragxdir[i] > dragx2[i]) dragxdir[i] = -16;
453 if (wall[startwall].y+dragydir[i] > dragy2[i]) dragydir[i] = -16;
454 for( j=startwall; j<=endwall; j++) {
455 dragpoint(j,wall[j].x+dragxdir[i],wall[j].y+dragydir[i], 0);
456 }
457 j = sector[dasector].floorz;
458 sector[dasector].floorz = dragfloorz[i]+(sintable[(lockclock<<4)&2047]>>3);
459 for( p=connecthead; p>=0; p=connectpoint2[p] ) {
460 if( cursectnum[p] == dasector ) {
461 posx[p] += dragxdir[i];
462 posy[p] += dragydir[i];
463 posz[p] += (sector[dasector].floorz-j);
464 vec3_t pos;
465 pos.x = posx[p]; pos.y = posy[p]; pos.z = posz[p] + (KENSPLAYERHEIGHT << 8);
466 setsprite(playersprite[p],&pos);
467 sprite[playersprite[p]].ang = ang[p];
468 frameinterpolate = 0;
469 }
470 }
471 }
472
473 for(i=0;i<swingcnt;i++)
474 {
475 if (swinganginc[i] != 0)
476 {
477 oldang = swingang[i];
478 for(j=0;j<(TICSPERFRAME<<2);j++)
479 {
480 swingang[i] = ((swingang[i]+2048+swinganginc[i])&2047);
481 if (swingang[i] == swingangclosed[i])
482 {
483 if( j == ((TICSPERFRAME<<2)-1) ) {
484 playsound(S_JUMP,swingx[i][0],swingy[i][0],0,ST_UPDATE);
485 }
486 swinganginc[i] = 0;
487 }
488 if (swingang[i] == swingangopen[i]) {
489 if( j == ((TICSPERFRAME<<2)-1) ) {
490 playsound(S_JUMP,swingx[i][0],swingy[i][0],0,ST_UPDATE);
491 }
492 swinganginc[i] = 0;
493 }
494 }
495 for (k = 1; k <= 3; k++)
496 {
497 vec2_t pivot;
498 pivot.x = swingx[i][0]; pivot.y = swingy[i][0];
499 vec2_t p;
500 p.x = swingx[i][k]; p.y = swingy[i][k];
501 vec2_t p2;
502 rotatepoint(pivot, p, swingang[i], &p2);
503 wall[swingwall[i][k]].x = p.x;
504 wall[swingwall[i][k]].y = p.y;
505 }
506
507 if (swinganginc[i] != 0)
508 {
509 for(p=connecthead;p>=0;p=connectpoint2[p])
510 if ((cursectnum[p] == swingsector[i]) || (testneighborsectors(cursectnum[p],swingsector[i]) == 1))
511 {
512 cnt = 256;
513 do
514 {
515 good = 1;
516
517 //swingangopendir is -1 if forwards, 1 is backwards
518 l = (swingangopendir[i] > 0);
519 for (k = l + 3; k >= l; k--)
520 {
521 vec2_t pos;
522 pos.x = posx[p]; pos.y = posy[p];
523 if (clipinsidebox(&pos, swingwall[i][k], 128L) != 0)
524 {
525 good = 0;
526 break;
527 }
528 }
529
530 if (good == 0)
531 {
532 if (cnt == 256)
533 {
534 swinganginc[i] = -swinganginc[i];
535 swingang[i] = oldang;
536 }
537 else
538 {
539 swingang[i] = ((swingang[i]+2048-swinganginc[i])&2047);
540 }
541
542 for (k = 1; k <= 3; k++)
543 {
544 vec2_t pivot;
545 pivot.x = swingx[i][0]; pivot.y = swingy[i][0];
546 vec2_t p;
547 p.x = swingx[i][k]; p.y = swingy[i][k];
548 vec2_t p2;
549 rotatepoint(pivot, p, swingang[i], &p2);
550 wall[swingwall[i][k]].x = p2.x;
551 wall[swingwall[i][k]].y = p2.y;
552 }
553
554 if (swingang[i] == swingangclosed[i])
555 {
556 swinganginc[i] = 0;
557 break;
558 }
559 if (swingang[i] == swingangopen[i])
560 {
561 swinganginc[i] = 0;
562 break;
563 }
564 cnt--;
565 }
566 } while ((good == 0) && (cnt > 0));
567 }
568 }
569
570 }
571 }
572
573 for(i=0;i<revolvecnt;i++)
574 {
575 startwall = sector[revolvesector[i]].wallptr;
576 endwall = startwall + sector[revolvesector[i]].wallnum - 1;
577
578 revolveang[i] = ((revolveang[i]+2048-(TICSPERFRAME<<2))&2047);
579 for(k=startwall;k<=endwall;k++)
580 {
581 vec2_t pivot;
582 pivot.x = revolvepivotx[i]; pivot.y = revolvepivoty[i];
583 vec2_t p;
584 p.x = revolvex[i][k - startwall];
585 p.y = revolvey[i][k - startwall];
586 vec2_t p2;
587 rotatepoint(pivot,p,revolveang[i],&p2);
588 dax = p2.x; day = p2.y;
589 dragpoint(k,dax,day, 0);
590 }
591 }
592
593 for(i=0;i<subwaytrackcnt;i++)
594 {
595 if( subwaysound[i] == -1 ) {
596 subwaysound[i]=playsound(S_SUBWAYLOOP,subwayx[i],subwaytracky1[i],-1,ST_VEHUPDATE);
597 }
598 else {
599 updatevehiclesnds(subwaysound[i],subwayx[i],subwaytracky1[i]);
600 }
601
602 dasector = subwaytracksector[i][0];
603 startwall = sector[dasector].wallptr;
604 endwall = startwall+sector[dasector].wallnum-1;
605 for(k=startwall;k<=endwall;k++)
606 {
607 if (wall[k].x > subwaytrackx1[i])
608 if (wall[k].y > subwaytracky1[i])
609 if (wall[k].x < subwaytrackx2[i])
610 if (wall[k].y < subwaytracky2[i])
611 wall[k].x += (subwayvel[i]&0xfffffffc);
612 }
613
614 for(j=1;j<subwaynumsectors[i];j++)
615 {
616 dasector = subwaytracksector[i][j];
617
618 startwall = sector[dasector].wallptr;
619 endwall = startwall+sector[dasector].wallnum-1;
620 for(k=startwall;k<=endwall;k++)
621 wall[k].x += (subwayvel[i]&0xfffffffc);
622
623 s = headspritesect[dasector];
624 while (s != -1)
625 {
626 k = nextspritesect[s];
627 sprite[s].x += (subwayvel[i]&0xfffffffc);
628 s = k;
629 }
630 }
631
632 for(p=connecthead;p>=0;p=connectpoint2[p])
633 if (cursectnum[p] != subwaytracksector[i][0])
634 if (sector[cursectnum[p]].floorz != sector[subwaytracksector[i][0]].floorz)
635 if (posx[p] > subwaytrackx1[i])
636 if (posy[p] > subwaytracky1[i])
637 if (posx[p] < subwaytrackx2[i])
638 if (posy[p] < subwaytracky2[i])
639 {
640 posx[p] += (subwayvel[i]&0xfffffffc);
641
642 //Update sprite representation of player
643 vec3_t pos;
644 pos.x = posx[p]; pos.y = posy[p]; pos.z = posz[p]+(KENSPLAYERHEIGHT << 8);
645 setsprite(playersprite[p],&pos);
646 sprite[playersprite[p]].ang = ang[p];
647 frameinterpolate = 0;
648 }
649
650 subwayx[i] += (subwayvel[i]&0xfffffffc);
651
652 k = subwaystop[i][subwaygoalstop[i]] - subwayx[i];
653 if( k > 0 ) {
654 if( k > 2048 ) {
655 if( subwayvel[i] == 12 ) {
656 playsound(S_SUBWAYSTART,subwayx[0],subwaytracky1[0],0,ST_UNIQUE | ST_NOUPDATE);
657 }
658 if (subwayvel[i] < 128) subwayvel[i]++;
659 }
660 else {
661 if( subwayvel[i] == 32 ) {
662 playsound(S_SUBWAYSTOP,subwayx[0],subwaytracky1[0],0,ST_UNIQUE | ST_NOUPDATE);
663 }
664 subwayvel[i] = (k>>4)+1;
665 }
666 }
667 else if( k < 0 ) {
668 if( k < -2048 ) {
669 if( subwayvel[i] == -12 ) {
670 playsound(S_SUBWAYSTART,subwayx[0],subwaytracky1[0],0,ST_UNIQUE | ST_NOUPDATE);
671 }
672 if (subwayvel[i] > -128) subwayvel[i]--;
673 }
674 else {
675 if( subwayvel[i] == -32) {
676 playsound(S_SUBWAYSTOP,subwayx[0],subwaytracky1[0],0,ST_UNIQUE | ST_NOUPDATE);
677 }
678 subwayvel[i] = ((k>>4)-1);
679 }
680 }
681
682 if (((subwayvel[i]>>2) == 0) && (labs(k) < 2048))
683 {
684 if (subwaypausetime[i] == 720)
685 {
686 for(j=1;j<subwaynumsectors[i];j++) //Open all subway doors
687 {
688 dasector = subwaytracksector[i][j];
689 if (sector[dasector].lotag == 17)
690 {
691 sector[dasector].lotag = 16;
692 playsound(S_BIGSWINGCL,subwayx[i],subwaytracky1[i],0,ST_NOUPDATE | ST_UNIQUE);
693 operatesector(dasector);
694 sector[dasector].lotag = 17;
695 }
696 }
697 }
698 if ((subwaypausetime[i] >= 120) && (subwaypausetime[i]-TICSPERFRAME < 120))
699 {
700 for(j=1;j<subwaynumsectors[i];j++) //Close all subway doors
701 {
702 dasector = subwaytracksector[i][j];
703 if (sector[dasector].lotag == 17)
704 {
705 sector[dasector].lotag = 16;
706 playsound(S_BIGSWINGCL,subwayx[i],subwaytracky1[i],0,ST_NOUPDATE | ST_UNIQUE);
707 operatesector(dasector);
708 sector[dasector].lotag = 17;
709 }
710 }
711 }
712
713 subwaypausetime[i] -= TICSPERFRAME;
714 if (subwaypausetime[i] < 0)
715 {
716 subwaypausetime[i] = 720;
717 if( subwaygoalstop[i] == (subwaystopcnt[i]-1) ) {
718 subwaystopdir[i]=-1;
719 subwaygoalstop[i]=subwaystopcnt[i]-2;
720 }
721 else if( subwaygoalstop[i] == 0 ) {
722 subwaygoalstop[i]=1;
723 subwaystopdir[i]= 1;
724 }
725 else {
726 subwaygoalstop[i]+=subwaystopdir[i];
727 }
728 }
729 }
730 }
731
732 tektagcode();
733 }
734
735 int
testneighborsectors(short sect1,short sect2)736 testneighborsectors(short sect1, short sect2)
737 {
738 short i, startwall, num1, num2;
739
740 num1 = sector[sect1].wallnum;
741 num2 = sector[sect2].wallnum;
742
743 // traverse walls of sector with fewest walls (for speed)
744 if( num1 < num2 ) {
745 startwall = sector[sect1].wallptr;
746 for(i=num1-1;i>=0;i--)
747 if (wall[i+startwall].nextsector == sect2)
748 return(1);
749 }
750 else {
751 startwall = sector[sect2].wallptr;
752 for(i=num2-1;i>=0;i--)
753 if (wall[i+startwall].nextsector == sect1)
754 return(1);
755 }
756 return(0);
757 }
758
759 void
tekpreptags()760 tekpreptags()
761 {
762 int angle,i,j,k,n,s,w1,w2,w3,w4;
763 int dax,day,endwall,startwall,x1,x2,y1,y2;
764 short killwcnt;
765 unsigned int effect;
766 spritetype *spr;
767
768 totalmapsndfx=0;
769 secnt=0;
770 memset(sexref,0,sizeof(int)*MAXSECTORS);
771
772 for (j=0 ; j < MAXSECTORS ; j++) {
773 memset(§oreffect[j],0,sizeof(struct sectoreffect));
774 sectoreffect[j].warpto=-1;
775 if (septrlist[j] != NULL) {
776 septrlist[j]=NULL;
777 }
778 if (evptrlist[j] != NULL) {
779 memset(evptrlist[j],0,sizeof(struct elevatortype));
780 evptrlist[j]=NULL;
781 }
782 }
783 for (j=0 ; j < MAXDOORS ; j++) {
784 doorptr[j]=&doortype[j];
785 memset(doorptr[j],0,sizeof(struct doortype));
786 }
787 numfloordoors=0;
788 for (j=0 ; j < MAXSECTORS ; j++) {
789 fdxref[j]=-1;
790 }
791 for (j=0 ; j < MAXFLOORDOORS ; j++) {
792 floordoorptr[j]=&floordoor[j];
793 memset(floordoorptr[j],0,sizeof(struct floordoor));
794 }
795 for (j=0 ; j < MAXSPRITEELEVS ; j++) {
796 sprelevptr[j]=&spriteelev[j];
797 memset(&spriteelev[j],0,sizeof(struct spriteelev));
798 }
799 for (j=0 ; j < MAXMAPSOUNDFX ; j++) {
800 mapsndfxptr[j]=&mapsndfx[j];
801 memset(mapsndfxptr[j], 0, sizeof(struct mapsndfxtype));
802 }
803 numvehicles=0;
804 for (j=0 ; j < MAXSECTORVEHICLES ; j++) {
805 sectvehptr[j]=§orvehicle[j];
806 memset(sectvehptr[j],0,sizeof(struct sectorvehicle));
807 sectvehptr[j]->soundindex=-1;
808 }
809
810 numdoors=0;
811 for (j=0 ; j < numsectors ; j++) {
812 if (sectptr[j]->ceilingpal != 0) {
813 startwall=sectptr[j]->wallptr;
814 endwall=startwall+sectptr[j]->wallnum-1;
815 for (i=startwall ; i <= endwall ; i++) {
816 wallptr[i]->pal=sectptr[j]->ceilingpal;
817 }
818 }
819 switch (sectptr[j]->lotag) {
820 case DOORUPTAG:
821 case DOORDOWNTAG:
822 case DOORSPLITHOR:
823 case DOORSPLITVER:
824 case PLATFORMELEVTAG:
825 case PLATFORMDELAYTAG:
826 case BOXELEVTAG:
827 case BOXDELAYTAG:
828 case PLATFORMDROPTAG:
829 if (sectptr[j]->lotag == BOXDELAYTAG
830 || sectptr[j]->lotag == PLATFORMDELAYTAG) {
831 evptrlist[j]=&elevator[j];
832 k=nextsectorneighborz(j,sectptr[j]->floorz,1,1);
833 evptrlist[j]->hilevel=sectptr[j]->floorz;
834 evptrlist[j]->lolevel=sectptr[k]->floorz;
835 }
836 n=numdoors++;
837 if (numdoors >= MAXDOORS) {
838 break;
839 }
840 switch (sectptr[j]->lotag) {
841 case DOORUPTAG:
842 case DOORDOWNTAG:
843 case DOORSPLITHOR:
844 doorptr[n]->step=DOORSPEED;
845 break;
846 case DOORSPLITVER:
847 doorptr[n]->step=4L;
848 break;
849 case PLATFORMELEVTAG:
850 case PLATFORMDELAYTAG:
851 case BOXELEVTAG:
852 case BOXDELAYTAG:
853 case PLATFORMDROPTAG:
854 doorptr[n]->step=ELEVSPEED;
855 break;
856 }
857 doorptr[n]->centx=doorptr[n]->centy=0L;
858 startwall=sectptr[j]->wallptr;
859 endwall=startwall+sectptr[j]->wallnum-1;
860 for (k=0,i=startwall ; i <= endwall ; i++) {
861 if (wallptr[i]->lotag == 6 && k < 8) {
862 doorptr[n]->walls[k]=i;
863 doorptr[n]->walls[k+1]=i+1;
864 doorptr[n]->walls[k+2]=i+2;
865 doorptr[n]->walls[k+3]=i-1;
866 dax=wallptr[doorptr[n]->walls[k]]->x;
867 if (wallptr[doorptr[n]->walls[k+3]]->x == dax) {
868 day=wallptr[i+2]->y;
869 doorptr[n]->points[k/2]=day;
870 day=wallptr[wallptr[i+2]->point2]->y;
871 doorptr[n]->points[(k/2)+1]=day;
872 }
873 else {
874 dax=wallptr[i+2]->x;
875 doorptr[n]->points[k/2]=dax;
876 dax=wallptr[wallptr[i+2]->point2]->x;
877 doorptr[n]->points[(k/2)+1]=dax;
878 }
879 k+=4;
880 }
881 doorptr[n]->centx+=wallptr[i]->x;
882 doorptr[n]->centy+=wallptr[i]->y;
883 }
884 doorptr[n]->centx/=(endwall-startwall+1);
885 doorptr[n]->centy/=(endwall-startwall+1);
886 doorptr[n]->centz=(sectptr[j]->ceilingz+sectptr[j]->floorz)/2;
887 doorptr[n]->type=sectptr[j]->lotag;
888 doorptr[n]->sector=j;
889 doorxref[j]=n;
890 break;
891 case DOORFLOORTAG:
892 k=fdxref[j]=numfloordoors++;
893 floordoorptr[k]->state=DOORCLOSED;
894 floordoorptr[k]->sectnum=i;
895 startwall=sectptr[j]->wallptr;
896 endwall=startwall+sectptr[j]->wallnum-1;
897 for (i=startwall ; i <= endwall ; i++) {
898 if (wallptr[i]->lotag == 6) {
899 if (floordoorptr[k]->wall1 == 0) {
900 w1=floordoorptr[k]->wall1=i;
901 w2=wallptr[w1]->point2;
902 }
903 else {
904 w3=floordoorptr[k]->wall2=i;
905 w4=wallptr[w3]->point2;
906 }
907 }
908 }
909 x1=wallptr[w1]->x; // close the doors all the way
910 y1=wallptr[w1]->y;
911 x2=wallptr[w4]->x;
912 y2=wallptr[w4]->y;
913 dragpoint(w1,(x1+x2)/2,(y1+y2)/2, 0);
914 if (x1 != x2) {
915 if (x1 < x2) {
916 dragpoint(w4,(x1+x2)/2+1,(y1+y2)/2, 0);
917 floordoorptr[k]->dir=3;
918 }
919 else {
920 dragpoint(w4,(x1+x2)/2-1,(y1+y2)/2, 0);
921 floordoorptr[k]->dir=1;
922 }
923 x1=wallptr[w1]->x;
924 w1=wallptr[wallptr[wallptr[w1]->nextwall]->point2]->point2;
925 floordoorptr[k]->dist1=abs(x1-wallptr[w1]->x)-50;
926 }
927 else if (y1 != y2) {
928 if (y1 < y2) {
929 dragpoint(w4,(x1+x2)/2,(y1+y2)/2+1, 0);
930 floordoorptr[k]->dir=0;
931 }
932 else {
933 dragpoint(w4,(x1+x2)/2,(y1+y2)/2-1, 0);
934 floordoorptr[k]->dir=2;
935 }
936 y1=wallptr[w1]->y;
937 w1=wallptr[wallptr[wallptr[w1]->nextwall]->point2]->point2;
938 floordoorptr[k]->dist1=abs(y1-wallptr[w1]->y)-50;
939 }
940 x1=wallptr[w2]->x;
941 y1=wallptr[w2]->y;
942 x2=wallptr[w3]->x;
943 y2=wallptr[w3]->y;
944 dragpoint(w2,(x1+x2)/2,(y1+y2)/2, 0);
945 if (x1 != x2) {
946 if (x1 < x2) {
947 dragpoint(w3,(x1+x2)/2+1,(y1+y2)/2, 0);
948 }
949 else {
950 dragpoint(w3,(x1+x2)/2-1,(y1+y2)/2, 0);
951 }
952 x1=wallptr[w2]->x;
953 w2=wallptr[wallptr[wallptr[w2]->nextwall]->point2]->point2;
954 floordoorptr[k]->dist2=abs(x1-wallptr[w2]->x)-50;
955 }
956 else if (y1 != y2) {
957 if (y1 < y2) {
958 dragpoint(w3,(x1+x2)/2,(y1+y2)/2+1, 0);
959 }
960 else {
961 dragpoint(w3,(x1+x2)/2,(y1+y2)/2-1, 0);
962 }
963 y1=wallptr[w2]->y;
964 w2=wallptr[wallptr[wallptr[w2]->nextwall]->point2]->point2;
965 floordoorptr[k]->dist2=abs(y1-wallptr[w2]->y)-50;
966 }
967 break;
968 default:
969 break;
970 }
971 if (sectptr[j]->hitag >= SECTORVEHICLETAG &&
972 sectptr[j]->hitag < SECTORVEHICLETAG+MAXSECTORVEHICLES) {
973 k=sectptr[j]->hitag-SECTORVEHICLETAG;
974 if (sectvehptr[k]->pivotx == 0 && sectvehptr[k]->pivoty == 0) {
975 numvehicles++;
976 for (i=0 ; i < MAXSPRITES ; i++) {
977 spr=sprptr[i];
978 if (spr->lotag == sectptr[j]->hitag
979 && spr->hitag == sectptr[j]->hitag) {
980 sectvehptr[k]->pivotx=spr->x;
981 sectvehptr[k]->pivoty=spr->y;
982 jsdeletesprite(i);
983 break;
984 }
985 }
986 }
987 x1=sectvehptr[k]->pivotx;
988 y1=sectvehptr[k]->pivoty;
989 n=sectvehptr[k]->numpoints;
990 startwall=sectptr[j]->wallptr;
991 endwall=startwall+sectptr[j]->wallnum-1;
992 killwcnt=0;
993 for (i=startwall ; i <= endwall ; i++) {
994 if (wallptr[i]->lotag == 6) {
995 sectvehptr[k]->killw[killwcnt++]=i;
996 }
997 sectvehptr[k]->point[n]=i;
998 sectvehptr[k]->pointx[n]=x1-wallptr[i]->x;
999 sectvehptr[k]->pointy[n]=y1-wallptr[i]->y;
1000 n++;
1001 if (n >= MAXVEHICLEPOINTS) {
1002 crash("tekprepareboard: vehicle #%d has too "
1003 "many points",sectptr[j]->hitag);
1004 }
1005 }
1006 sectvehptr[k]->numpoints=n;
1007 n=sectvehptr[k]->numsectors++;
1008 sectvehptr[k]->sector[n]=j;
1009 sectvehptr[k]->soundindex=-1;
1010 }
1011 }
1012
1013 sprelevcnt=0;
1014 for (i=0 ; i < MAXSPRITES ; i++) {
1015 spr=sprptr[i];
1016 if (spr->statnum < MAXSTATUS) {
1017 switch (spr->picnum) {
1018 case SNDFX_SECTOR:
1019 case SNDFX_AMBIENT:
1020 case SNDFX_TOGGLED:
1021 if( totalmapsndfx == MAXMAPSOUNDFX ) {
1022 jsdeletesprite(i);
1023 break;
1024 }
1025 mapsndfxptr[totalmapsndfx]->x=sprite[i].x;
1026 mapsndfxptr[totalmapsndfx]->y=sprite[i].y;
1027 mapsndfxptr[totalmapsndfx]->sector=sprite[i].sectnum;
1028 mapsndfxptr[totalmapsndfx]->snum=sprite[i].lotag;
1029 mapsndfxptr[totalmapsndfx]->id=-1;
1030 if( mapsndfxptr[totalmapsndfx]->snum > TOTALSOUNDS ) {
1031 mapsndfxptr[totalmapsndfx]->snum=(TOTALSOUNDS-1);
1032 }
1033 mapsndfxptr[totalmapsndfx]->loops=sprite[i].hitag-1;
1034 switch( spr->picnum ) {
1035 case SNDFX_AMBIENT:
1036 mapsndfxptr[totalmapsndfx]->type=MAP_SFX_AMBIENT;
1037 break;
1038 case SNDFX_SECTOR:
1039 mapsndfxptr[totalmapsndfx]->type=MAP_SFX_SECTOR;
1040 break;
1041 case SNDFX_TOGGLED:
1042 mapsndfxptr[totalmapsndfx]->type=MAP_SFX_TOGGLED;
1043 break;
1044 }
1045 totalmapsndfx++;
1046 jsdeletesprite(i);
1047 break;
1048 case SECTOREFFECT:
1049 if (spr->lotag < 1000) {
1050 continue;
1051 }
1052 s=spr->sectnum;
1053 septrlist[s]=§oreffect[s];
1054 if (septrlist[s]->sectorflags == 0) {
1055 s=sexref[secnt++]=spr->sectnum;
1056 if (secnt == MAXSECTORS) {
1057 crash("setupboard: Sector Effector limit exceeded");
1058 }
1059 septrlist[s]->warpto=-1;
1060 }
1061 effect=flags32[spr->lotag-1000];
1062 septrlist[s]->sectorflags|=effect;
1063 if( (effect&flags32[QUICKCLOSE]) != 0 ) {
1064 }
1065 else if( (effect&flags32[SOUNDON]) != 0 ) {
1066 // match mapsndfx with same hitag
1067 septrlist[s]->hi=spr->hitag;
1068 }
1069 else if( (effect&flags32[SOUNDOFF]) != 0 ) {
1070 // match mapsndfx with same hitag
1071 septrlist[s]->hi=spr->hitag;
1072 }
1073 else if ((effect&flags32[PULSELIGHT]) != 0
1074 || (effect&flags32[FLICKERLIGHT]) != 0
1075 || (effect&flags32[FLICKERDELAY]) != 0
1076 || (effect&flags32[BLINKDELAY]) != 0
1077 || (effect&flags32[STEADYLIGHT]) != 0) {
1078 septrlist[s]->lo=sectptr[s]->floorshade;
1079 septrlist[s]->hi=sectptr[s]->ceilingshade;
1080 septrlist[s]->animate=1;
1081 if (spr->hitag != 0) {
1082 septrlist[s]->triggerable=spr->hitag;
1083 }
1084 else {
1085 septrlist[s]->triggerable=0;
1086 }
1087 startwall=sectptr[s]->wallptr;
1088 endwall=startwall+sectptr[s]->wallnum-1;
1089 for (j=startwall ; j <= endwall ; j++) {
1090 wallptr[j]->shade=sectptr[s]->floorshade;
1091 }
1092 sectptr[s]->ceilingshade=sectptr[s]->floorshade;
1093 }
1094 else if ((effect&flags32[DELAYEFFECT]) != 0) {
1095 septrlist[s]->delay=spr->hitag;
1096 septrlist[s]->delayreset=septrlist[s]->delay;
1097 }
1098 if ((effect&flags32[WPANNING]) != 0) {
1099 angle=septrlist[s]->ang=spr->ang;
1100 septrlist[s]->sin=(int)sintable[((angle+2048)&2047)];
1101 septrlist[s]->cos=(int)sintable[((angle+2560)&2047)];
1102 startwall=sectptr[s]->wallptr;
1103 endwall=startwall+sectptr[s]->wallnum-1;
1104 for (j=startwall ; j <= endwall ; j++) {
1105 if (wallptr[j]->lotag == 0) {
1106 wallptr[j]->lotag=spr->lotag;
1107 }
1108 }
1109 }
1110 if ((effect&flags32[FPANNING]) != 0 ||
1111 (effect&flags32[CPANNING]) != 0) {
1112 angle=septrlist[s]->ang=spr->ang;
1113 septrlist[s]->sin=(int)sintable[((angle+2048)&2047)];
1114 septrlist[s]->cos=(int)sintable[((angle+2560)&2047)];
1115 }
1116 if ((effect&flags32[WARPSECTOR]) != 0) {
1117 for( j=0; j<MAXSECTORS; j++ ) {
1118 if( sector[j].hitag == spr->hitag ) {
1119 septrlist[s]->warpto=j;
1120 j=MAXSECTORS;
1121 }
1122 }
1123 }
1124 if ((effect&flags32[KILLSECTOR]) != 0) {
1125 if (spr->hitag == 0) {
1126 septrlist[s]->damage=9999;
1127 }
1128 else {
1129 septrlist[s]->damage=spr->hitag;
1130 }
1131 }
1132 if ((effect&flags32[DOORSPEEDEFFECT]) != 0) {
1133 doorptr[doorxref[spr->sectnum]]->step=spr->hitag;
1134 }
1135 // jeff added 9-20
1136 if ((effect&flags32[DOORSUBTYPE]) != 0) {
1137 doorptr[doorxref[spr->sectnum]]->subtype=spr->hitag;
1138 }
1139 jsdeletesprite(i);
1140 break;
1141 default:
1142 if (spr->lotag >= SECTORVEHICLETAG
1143 && spr->lotag < SECTORVEHICLETAG+MAXSECTORVEHICLES) {
1144 k=spr->lotag-SECTORVEHICLETAG;
1145 n=spr->hitag;
1146 sectvehptr[k]->trackx[n]=spr->x;
1147 sectvehptr[k]->tracky[n]=spr->y;
1148 if (spr->picnum == STOPPIC) {
1149 sectvehptr[k]->stop[n]=1;
1150 sectvehptr[k]->waitdelay=CLKIPS*8;
1151 }
1152 else {
1153 sectvehptr[k]->stop[n]=0;
1154 }
1155 if (spr->picnum == SPEEDPIC) {
1156 if (sectvehptr[k]->speedto == 0 && spr->hitag > 0) {
1157 sectvehptr[k]->speedto=spr->hitag;
1158 sectvehptr[k]->movespeed=sectvehptr[k]->speedto;
1159 }
1160 jsdeletesprite(i);
1161 break;
1162 }
1163 sectvehptr[k]->tracknum++;
1164 jsdeletesprite(i);
1165 }
1166 if ((spr->lotag < 2000) && (spr->lotag >= SPRITEELEVATORTAG)) {
1167 j=spr->lotag-SPRITEELEVATORTAG;
1168 if (spr->hitag >= 100) {
1169 k=(spr->hitag-100)+1;
1170 if (k >= MAXELEVFLOORS) {
1171 crash("setupboard: Only %d levels allowed "
1172 "for sprite elevators",MAXELEVFLOORS);
1173 }
1174 sprelevptr[j]->floorz[k]=spr->z;
1175 sprelevptr[j]->floors++;
1176 }
1177 else {
1178 k=sprelevptr[j]->parts;
1179 sprelevptr[j]->sprnum[k]=i;
1180 if (spr->hitag == 6 || spr->hitag == 7) {
1181 if (sprelevptr[j]->floorpos == 0) {
1182 sprelevcnt++;
1183 }
1184 sprelevptr[j]->door[sprelevptr[j]->doors]=i;
1185 sprelevptr[j]->floorz[0]=spr->z;
1186 sprelevptr[j]->floorpos=spr->z;
1187 sprelevptr[j]->doors++;
1188 }
1189 sprelevptr[j]->startz[k]=spr->z;
1190 sprelevptr[j]->parts++;
1191 }
1192 }
1193 break;
1194 }
1195 }
1196
1197 }
1198
1199 numanimates=0;
1200 for (j=0 ; j < MAXANIMPICS ; j++) {
1201 animpicptr[j]=&animpic[j];
1202 memset(animpicptr[j],0,sizeof(struct animpic));
1203 }
1204 numdelayfuncs=0;
1205 for (j=0 ; j < MAXDELAYFUNCTIONS ; j++) {
1206 delayfuncptr[j]=&delayfunc[j];
1207 memset(delayfuncptr[j],0,sizeof(struct delayfunc));
1208 }
1209 }
1210
1211 void
tekoperatesector(short dasector)1212 tekoperatesector(short dasector)
1213 {
1214 short s;
1215 int datag,i;
1216
1217 s=dasector;
1218 datag=sectptr[s]->lotag;
1219
1220 switch (datag) {
1221 case BOXELEVTAG:
1222 case PLATFORMELEVTAG:
1223 case BOXDELAYTAG:
1224 case PLATFORMDELAYTAG:
1225 case DOORUPTAG: // a door that opens up
1226 case DOORDOWNTAG:
1227 case DOORSPLITHOR:
1228 case DOORSPLITVER:
1229 case PLATFORMDROPTAG:
1230 i=doorxref[s];
1231 if (i == -1) {
1232 crash("operatesector: invalid door reference for sector %d",s);
1233 }
1234 switch (doorptr[i]->state) {
1235 case D_NOTHING:
1236 case D_CLOSING:
1237 case D_CLOSEDOOR:
1238 case D_SHUTSOUND:
1239 doorptr[i]->state=D_OPENDOOR;
1240 break;
1241 default:
1242 if (datag != PLATFORMDROPTAG) {
1243 doorptr[i]->state=D_CLOSEDOOR;
1244 }
1245 break;
1246 }
1247 break;
1248 case DOORFLOORTAG:
1249 floordoorptr[fdxref[s]]->state=DOOROPENING;
1250 playsound(S_FLOOROPEN,0,0,0,ST_IMMEDIATE);
1251 break;
1252 }
1253 }
1254
1255 void
warp(int * x,int * y,int * z,short * UNUSED (daang),short * dasector)1256 warp(int *x, int *y, int *z, short * UNUSED(daang), short *dasector)
1257 {
1258 short startwall, endwall, s;
1259 int i, j, dax, day, ox, oy;
1260
1261 ox = *x; oy = *y;
1262
1263 for( i=0; i<warpsectorcnt; i++ ) {
1264 if( warpsectorlist[i] == *dasector ) {
1265 j = sector[*dasector].hitag;
1266 do {
1267 i++;
1268 if (i >= warpsectorcnt) i = 0;
1269 } while( sector[warpsectorlist[i]].hitag != j );
1270 *dasector = warpsectorlist[i];
1271 break;
1272 }
1273 }
1274
1275 // find center of sector
1276 startwall = sector[*dasector].wallptr;
1277 endwall = startwall+sector[*dasector].wallnum-1;
1278 dax = 0L, day = 0L;
1279 for( s=startwall; s<=endwall; s++ ) {
1280 dax += wall[s].x, day += wall[s].y;
1281 if( wall[s].nextsector >= 0 ) {
1282 i = s;
1283 }
1284 }
1285 *x = dax / (endwall-startwall+1);
1286 *y = day / (endwall-startwall+1);
1287 *z = sector[*dasector].floorz-(42<<8);
1288
1289 updatesector(*x,*y,dasector);
1290 }
1291
1292 void
tekwarp(int * x,int * y,int * z,short * dasector)1293 tekwarp(int *x, int *y, int *z, short *dasector)
1294 {
1295 short startwall, endwall, s;
1296 int i, dax, day;
1297
1298 // find center of sector
1299 startwall = sector[*dasector].wallptr;
1300 endwall = startwall+sector[*dasector].wallnum-1;
1301 dax = 0L, day = 0L;
1302 for( s=startwall; s<=endwall; s++ ) {
1303 dax += wall[s].x, day += wall[s].y;
1304 if( wall[s].nextsector >= 0 ) {
1305 i = s;
1306 }
1307 }
1308 *x = dax / (endwall-startwall+1);
1309 *y = day / (endwall-startwall+1);
1310 *z = sector[*dasector].floorz-(42<<8);
1311
1312 updatesector(*x,*y,dasector);
1313 }
1314
1315 void
warpsprite(short spritenum)1316 warpsprite(short spritenum)
1317 {
1318 short dasectnum;
1319
1320 dasectnum = sprite[spritenum].sectnum;
1321 warp(&sprite[spritenum].x,&sprite[spritenum].y,&sprite[spritenum].z,
1322 &sprite[spritenum].ang,&dasectnum);
1323 copybuf(&sprite[spritenum].x,&osprite[spritenum].x,3);
1324 changespritesect(spritenum,dasectnum);
1325 }
1326
1327 void
teknewsector(short p)1328 teknewsector(short p)
1329 {
1330 int i,n,nexti,s;
1331 int sn;
1332 struct sectoreffect *septr;
1333
1334 s=cursectnum[p];
1335 septr=septrlist[s];
1336
1337 #define NEWMAPLOTAG 25
1338 if( (sector[s].lotag == NEWMAPLOTAG) && (option[4] == 0) ) {
1339 newmap(sector[s].hitag);
1340 return;
1341 }
1342
1343 if( sectptr[cursectnum[p]]->lotag == 4 ) {
1344 playsound(S_SPLASH,posx[p],posy[p],0,ST_UPDATE);
1345 }
1346
1347 if( septr != NULL ) {
1348 if( septr->warpto >= 0 ) {
1349 sn=playersprite[p];
1350 tekwarp(&sprite[sn].x,&sprite[sn].y,&sprite[sn].z,( short *)&(septr->warpto));
1351 copybuf(&sprite[sn].x,&osprite[sn].x,3);
1352 changespritesect(sn,septr->warpto);
1353 posx[p] = sprite[playersprite[p]].x;
1354 posy[p] = sprite[playersprite[p]].y;
1355 posz[p] = sprite[playersprite[p]].z;
1356 ang[p] = sprite[playersprite[p]].ang;
1357 cursectnum[p] = sprite[playersprite[p]].sectnum;
1358 sprite[playersprite[p]].z += (KENSPLAYERHEIGHT<<8);
1359 }
1360 }
1361
1362 for( n=connecthead; n >= 0; n=connectpoint2[n] ) {
1363 if( (sectptr[cursectnum[n]]->lotag == 1) || (sectptr[cursectnum[n]]->lotag == 2) ) {
1364 for( i=0; i < numsectors; i++ ) {
1365 if( sectptr[i]->hitag == sectptr[cursectnum[n]]->hitag ) {
1366 if( (sectptr[i]->lotag != 1) && (sectptr[i]->lotag != 2) ) {
1367 operatesector(i);
1368 }
1369 }
1370 }
1371 i=headspritestat[0];
1372 while( i != -1 ) {
1373 nexti=nextspritestat[i];
1374 if( sprptr[i]->hitag == sectptr[cursectnum[n]]->hitag ) {
1375 operatesprite(i);
1376 }
1377 i=nexti;
1378 }
1379 }
1380 }
1381
1382 checkmapsndfx(p);
1383 sectortriggersprites(p);
1384 }
1385
1386
1387 void
tektagcode(void)1388 tektagcode(void)
1389 {
1390 int floorz,hi,i,j,k,lo,oldang,p,r,s,tics;
1391 int dax,dax2,day,day2,endwall,startwall;
1392 unsigned int effect;
1393 sectortype *sect;
1394 struct sectoreffect *septr;
1395
1396 for( p=connecthead; p >= 0; p=connectpoint2[p] ) {
1397 tekanimweap((syncbits[p]>>13)&15,p);
1398 tekhealstun(p);
1399 }
1400
1401 for( i=0; i < numdoors; i++ ) {
1402 movedoors(i);
1403 }
1404
1405 if( option[4] == 0 ) {
1406 for( i=0; i < secnt; i++ ) {
1407 s=sexref[i];
1408 if (s < 0 || s >= numsectors) {
1409 crash("tag1402: Invalid sector effect index (%d,e=%d)",s,i);
1410 }
1411 sect=sectptr[s];
1412 septr=septrlist[s];
1413 if( septr->triggerable != 0 ) {
1414 continue;
1415 }
1416 effect=septr->sectorflags;
1417 if( (effect&flags32[WPANNING]) != 0 ) {
1418 oldang=septr->ang;
1419 tics=TICSPERFRAME;
1420 startwall=sect->wallptr;
1421 endwall=startwall+sect->wallnum-1;
1422 dax=(tics*septr->cos)>>15;
1423 day=(tics*septr->sin)>>13;
1424 for( j=startwall; j <= endwall; j++ ) {
1425 wallptr[j]->xpanning+=(unsigned char)dax;
1426 wallptr[j]->ypanning-=(unsigned char)day;
1427 }
1428 }
1429 if( (effect&flags32[FPANNING]) != 0 ) {
1430 tics=TICSPERFRAME;
1431 dax=(tics*septr->cos);
1432 day=(tics*septr->sin);
1433 j=headspritesect[s];
1434 while( j != -1 ) {
1435 k=nextspritesect[j];
1436 if( sprptr[j]->owner < MAXSPRITES ) {
1437 dax2=dax>>10;
1438 day2=day>>10;
1439 movesprite(j,dax2,day2,0,4<<8,4<<8,0);
1440 }
1441 j=k;
1442 }
1443 for( p=connecthead; p >= 0; p=connectpoint2[p] ) {
1444 if( cursectnum[p] == s ) {
1445 if( posz[p] >= (sect->floorz-(42<<8)) )
1446 {
1447 vec3_t pos;
1448 pos.x = posx[p]; pos.y = posy[p]; pos.z = posz[p];
1449
1450 clipmove(&pos, &cursectnum[p],dax<<4,day<<4,128L,4<<8,4<<8,CLIPMASK0);
1451
1452 posx[p] = pos.x; posy[p] = pos.y; posz[p] = pos.z;
1453
1454 pos.z += (42 << 8);
1455
1456 setsprite(playersprite[p], &pos);
1457 revolvedoorstat[p]=1;
1458 }
1459 }
1460 }
1461 dax>>=12;
1462 day>>=12;
1463 sect->floorxpanning-=(unsigned char)dax;
1464 sect->floorypanning+=(unsigned char)day;
1465 }
1466 if( (effect&flags32[CPANNING]) != 0 ) {
1467 tics=TICSPERFRAME;
1468 dax=(tics*septr->cos)>>12;
1469 day=(tics*septr->sin)>>12;
1470 sect->ceilingxpanning-=(unsigned char)dax;
1471 sect->ceilingypanning+=(unsigned char)day;
1472 }
1473 if( (septr->delay-=TICSPERFRAME) > 0 ) {
1474 continue;
1475 }
1476 // negative overflow here without this - jeffy
1477 if( septr->delay < 0 ) {
1478 septr->delay=0;
1479 }
1480 septr->delay+=septr->delayreset;
1481 if( (effect&flags32[PULSELIGHT]) != 0 ) {
1482 sect->ceilingshade+=septr->animate;
1483 if( septr->hi > septr->lo ) {
1484 hi=septr->hi;
1485 lo=septr->lo;
1486 }
1487 else {
1488 hi=septr->lo;
1489 lo=septr->hi;
1490 }
1491 if( septr->animate < 0 ) {
1492 if( sect->ceilingshade <= lo ) {
1493 septr->animate=abs(septr->animate);
1494 }
1495 }
1496 else {
1497 if( sect->ceilingshade >= hi ) {
1498 septr->animate=-septr->animate;
1499 }
1500 }
1501 sect->floorshade=sect->ceilingshade;
1502 startwall=sect->wallptr;
1503 endwall=startwall+sect->wallnum-1;
1504 for( j=startwall; j <= endwall; j++ ) {
1505 wallptr[j]->shade=sect->ceilingshade;
1506 }
1507 }
1508 else if( (effect&flags32[FLICKERLIGHT]) != 0 ) {
1509 r=krand_intercept("TAG 1491");
1510 if( r < 16384 ) {
1511 sect->ceilingshade=septr->hi;
1512 }
1513 else if( r > 16384 ) {
1514 sect->ceilingshade=septr->lo;
1515 }
1516 sect->floorshade=sect->ceilingshade;
1517 startwall=sect->wallptr;
1518 endwall=startwall+sect->wallnum-1;
1519 for( j=startwall; j <= endwall; j++ ) {
1520 wallptr[j]->shade=sect->ceilingshade;
1521 }
1522 }
1523 else if( (effect&flags32[FLICKERDELAY]) != 0 ) {
1524 if( sect->ceilingshade == septr->lo ) {
1525 sect->ceilingshade=septr->hi;
1526 }
1527 else {
1528 sect->ceilingshade=septr->lo;
1529 septr->delay>>=2;
1530 }
1531 sect->floorshade=sect->ceilingshade;
1532 startwall=sect->wallptr;
1533 endwall=startwall+sect->wallnum-1;
1534 for( j=startwall; j <= endwall; j++ ) {
1535 wallptr[j]->shade=sect->ceilingshade;
1536 }
1537 }
1538 else if( (effect&flags32[BLINKDELAY]) != 0 ) {
1539 if( sect->ceilingshade == septr->lo ) {
1540 sect->ceilingshade=septr->hi;
1541 }
1542 else {
1543 sect->ceilingshade=septr->lo;
1544 }
1545 sect->floorshade=sect->ceilingshade;
1546 startwall=sect->wallptr;
1547 endwall=startwall+sect->wallnum-1;
1548 for( j=startwall; j <= endwall; j++ ) {
1549 wallptr[j]->shade=sect->ceilingshade;
1550 }
1551 }
1552 if( (effect&flags32[KILLSECTOR]) != 0 ) {
1553 floorz=sectptr[s]->floorz;
1554 for( p=connecthead ; p >= 0 ; p=connectpoint2[p] ) {
1555 if( cursectnum[p] == s ) {
1556 // matrix specific check here
1557 if( (klabs(posz[p] - floorz) < 10240) || (mission == 7) ) {
1558 if( (k=fdxref[s]) != -1 ) {
1559 if( floordoorptr[k]->state != DOORCLOSED ) {
1560 changehealth(p,-septr->damage);
1561 changescore(p,-10);
1562 }
1563 }
1564 else {
1565 if( septr->delay == septr->delayreset ) {
1566 changehealth(p,-septr->damage);
1567 changescore(p,-10);
1568 }
1569 }
1570 }
1571 }
1572 }
1573 }
1574 }
1575 }
1576
1577 if( option[4] == 0 ) {
1578 for( i=0; i < sprelevcnt; i++ ) {
1579 movesprelevs(i);
1580 }
1581 for( i=0; i < numfloordoors; i++ ) {
1582 movefloordoor(i);
1583 }
1584 for( i=0; i < numvehicles; i++ ) {
1585 movevehicles(i);
1586 }
1587 }
1588
1589 tekdoanimpic();
1590 tekdodelayfuncs();
1591 if( (lockclock-ambupdateclock) > 120 ) {
1592 checkmapsndfx(screenpeek);
1593 }
1594 }
1595
1596 int
stepdoor(int z,int z2,struct doortype * door,int newstate)1597 stepdoor(int z,int z2,struct doortype *door,int newstate)
1598 {
1599 if (z < z2) {
1600 z+=(door->step*TICSPERFRAME);
1601 if (z >= z2) {
1602 door->delay=DOORDELAY;
1603 door->state=newstate;
1604 z=z2;
1605 }
1606 }
1607 else if (z > z2) {
1608 z-=(door->step*TICSPERFRAME);
1609 if (z <= z2) {
1610 door->delay=DOORDELAY;
1611 door->state=newstate;
1612 z=z2;
1613 }
1614 }
1615 return(z);
1616 }
1617
1618 void
showwall2d(int w,int onoff)1619 showwall2d(int w,int onoff)
1620 {
1621 if (onoff) {
1622 show2dwall[w>>3]|=(1<<(w&7));
1623 }
1624 else {
1625 show2dwall[w>>3]&=~(1<<(w&7));
1626 }
1627 }
1628
1629 void
showsect2d(int s,int z)1630 showsect2d(int s,int z)
1631 {
1632 int endwall,i,startwall;
1633
1634 startwall=sectptr[s]->wallptr;
1635 endwall=startwall+sectptr[s]->wallnum-1;
1636 for (i=startwall ; i <= endwall ; i++) {
1637 if (wallptr[i]->nextwall != -1) {
1638 if (sectptr[wallptr[i]->nextsector]->floorz == z) {
1639 showwall2d(i,0);
1640 showwall2d(wallptr[i]->nextwall,0);
1641 }
1642 else {
1643 showwall2d(i,1);
1644 showwall2d(wallptr[i]->nextwall,1);
1645 }
1646 }
1647 }
1648 }
1649
1650 void
showsect2dtoggle(int s,int onoff)1651 showsect2dtoggle(int s,int onoff)
1652 {
1653 int endwall,i,startwall;
1654
1655 startwall=sectptr[s]->wallptr;
1656 endwall=startwall+sectptr[s]->wallnum-1;
1657 for (i=startwall ; i <= endwall ; i++) {
1658 if (wallptr[i]->nextwall != -1) {
1659 showwall2d(i,onoff);
1660 showwall2d(wallptr[i]->nextwall,onoff);
1661 }
1662 }
1663 }
1664
1665 int
sectorblocked(int s)1666 sectorblocked(int s)
1667 {
1668 int i,rv;
1669
1670 rv=0;
1671
1672 for( i=connecthead ; i >= 0 ; i=connectpoint2[i] ) {
1673 if( cursectnum[i] == s )
1674 rv=1;
1675 if( testneighborsectors(cursectnum[i], s) == 1 )
1676 rv=1;
1677 }
1678 if( headspritesect[s] != -1 )
1679 rv=1;
1680
1681 return(rv);
1682 }
1683
1684 void
movedoors(int d)1685 movedoors(int d)
1686 {
1687 int hitag,i,j,s,sx;
1688 int size,z;
1689 struct doortype *door;
1690 spritetype *spr;
1691 walltype *wall;
1692 char stayopen;
1693
1694 door=doorptr[d];
1695 s=door->sector;
1696
1697 switch (door->state) {
1698
1699 case D_NOTHING:
1700 break;
1701
1702 case D_WAITING:
1703 stayopen=0;
1704 for( i=0 ; i < secnt ; i++ ) {
1705 sx=sexref[i];
1706 if( sx == door->sector ) {
1707 if( ((septrlist[sx]->sectorflags)&flags32[QUICKCLOSE]) != 0) {
1708 if( mission == 7 ) {
1709 stayopen=1;
1710 }
1711 else {
1712 door->delay=0;
1713 }
1714 }
1715 }
1716 }
1717 if( stayopen == 0 ) {
1718 door->delay-=TICSPERFRAME;
1719 }
1720 if( door->delay <= 0 ) {
1721 door->delay=0;
1722 if( door->type < PLATFORMELEVTAG ) {
1723 for( i=connecthead ; i >= 0 ; i=connectpoint2[i] ) {
1724 if( cursectnum[i] == s ) {
1725 door->delay=DOORDELAY;
1726 break;
1727 }
1728 }
1729 }
1730 if( door->delay == 0 ) {
1731 door->state=D_CLOSEDOOR;
1732 }
1733 }
1734 break;
1735
1736 case D_OPENDOOR:
1737 switch (door->type) {
1738 case DOORUPTAG:
1739 switch( door->subtype ) {
1740 case DST_BAYDOOR:
1741 playsound(S_BAYDOOR_OPEN,door->centx,door->centy,0,ST_UPDATE);
1742 if( baydoorloop == -1 ) {
1743 baydoorloop=playsound(S_BAYDOORLOOP,door->centx,door->centy,20,ST_UNIQUE);
1744 }
1745 break;
1746 case DST_HYDRAULICDOOR:
1747 playsound(S_AIRDOOR_OPEN,door->centx,door->centy,0,ST_UPDATE);
1748 playsound(S_AIRDOOR,door->centx,door->centy,0,ST_UPDATE);
1749 break;
1750
1751 case DST_ELEVATORDOOR:
1752 playsound(S_ELEVATOR_DOOR,door->centx,door->centy,0,ST_UPDATE);
1753 break;
1754
1755 case DST_MATRIXDOOR1:
1756 playsound(S_MATRIX1,door->centx,door->centy,0,ST_UPDATE);
1757 break;
1758
1759 case DST_MATRIXDOOR2:
1760 playsound(S_MATRIX2,door->centx,door->centy,0,ST_UPDATE);
1761 break;
1762 case DST_MATRIXDOOR3:
1763 playsound(S_MATRIX3,door->centx,door->centy,0,ST_UPDATE);
1764 break;
1765 case DST_MATRIXDOOR4:
1766 playsound(S_MATRIX4,door->centx,door->centy,0,ST_UPDATE);
1767 break;
1768
1769 default:
1770 if( mission == 7 ) {
1771 playsound(S_MATRIXDOOR2,door->centx,door->centy,0,ST_UPDATE);
1772 }
1773 else {
1774 playsound(S_UPDOWNDR2_OP,door->centx,door->centy,0,ST_UPDATE);
1775 }
1776 break;
1777 }
1778 door->goalz[0]=sectptr[nextsectorneighborz(s,sectptr[s]->floorz,-1,-1)]->ceilingz;
1779 break;
1780 case DOORDOWNTAG:
1781 playsound(S_BIGSWINGOP,door->centx,door->centy,0,ST_UPDATE);
1782
1783 door->goalz[0]=sectptr[nextsectorneighborz(s,sectptr[s]->ceilingz,1,1)]->floorz;
1784
1785 break;
1786
1787
1788 case PLATFORMDROPTAG:
1789 door->goalz[0]=sectptr[nextsectorneighborz(s,sectptr[s]->ceilingz,1,1)]->floorz;
1790 break;
1791 case DOORSPLITHOR:
1792 if( mission == 7 ) {
1793 playsound(S_MATRIXDOOR1,door->centx,door->centy,0,ST_UPDATE);
1794 }
1795 else {
1796 playsound(S_WH_7,door->centx,door->centy,0,ST_UPDATE);
1797 }
1798 door->goalz[0]=sectptr[nextsectorneighborz(s,sectptr[s]->ceilingz,-1,-1)]->ceilingz;
1799 door->goalz[2]=sectptr[nextsectorneighborz(s,sectptr[s]->floorz,1,1)]->floorz;
1800 break;
1801 case DOORSPLITVER:
1802 playsound(S_SIDEDOOR1,door->centx,door->centy,0,ST_UPDATE);
1803 door->goalz[0]=door->points[0];
1804 door->goalz[1]=door->points[1];
1805 door->goalz[2]=door->points[2];
1806 door->goalz[3]=door->points[3];
1807 break;
1808 case BOXDELAYTAG:
1809 case PLATFORMDELAYTAG:
1810 playsound(S_PLATFORMSTART,door->centx,door->centy,0,ST_UPDATE);
1811 if( loopinsound == -1 ) {
1812 loopinsound=playsound(S_PLATFORMLOOP,door->centx,door->centy,20,ST_UNIQUE);
1813 }
1814 door->goalz[0]=evptrlist[s]->lolevel;
1815 break;
1816 default:
1817 break;
1818 }
1819 door->state=D_OPENING;
1820 break;
1821
1822 case D_CLOSEDOOR:
1823 switch (door->type) {
1824 case DOORUPTAG:
1825 switch( door->subtype ) {
1826 case DST_BAYDOOR:
1827 playsound(S_BAYDOOR_OPEN,door->centx,door->centy,0,ST_UPDATE);
1828 if( baydoorloop == -1 ) {
1829 baydoorloop = playsound(S_BAYDOORLOOP,door->centx,door->centy,20,ST_UNIQUE);
1830 }
1831 break;
1832
1833 case DST_HYDRAULICDOOR:
1834 playsound(S_AIRDOOR_OPEN,door->centx,door->centy,0,ST_UPDATE);
1835 playsound(S_AIRDOOR,door->centx,door->centy,0,ST_UPDATE);
1836 break;
1837
1838 case DST_ELEVATORDOOR:
1839 playsound(S_ELEVATOR_DOOR,door->centx,door->centy,0,ST_UPDATE);
1840 break;
1841
1842 case DST_MATRIXDOOR1:
1843 playsound(S_MATRIX1,door->centx,door->centy,0,ST_UPDATE);
1844 break;
1845
1846 case DST_MATRIXDOOR2:
1847 playsound(S_MATRIX2,door->centx,door->centy,0,ST_UPDATE);
1848 break;
1849 case DST_MATRIXDOOR3:
1850 playsound(S_MATRIX3,door->centx,door->centy,0,ST_UPDATE);
1851 break;
1852 case DST_MATRIXDOOR4:
1853 playsound(S_MATRIX4,door->centx,door->centy,0,ST_UPDATE);
1854 break;
1855
1856 default:
1857 if( mission == 7 ) {
1858 playsound(S_MATRIXDOOR2,door->centx,door->centy,0,ST_UPDATE);
1859 }
1860 else {
1861 playsound(S_UPDOWNDR2_CL,door->centx,door->centy,0,ST_UPDATE);
1862 }
1863 break;
1864 }
1865 door->goalz[0]=sectptr[nextsectorneighborz(s,sectptr[s]->ceilingz,1,1)]->floorz;
1866 break;
1867 case DOORDOWNTAG:
1868 playsound(S_BIGSWINGOP,door->centx,door->centy,0,ST_UPDATE);
1869 door->goalz[0]=sectptr[s]->ceilingz;
1870 break;
1871 case DOORSPLITHOR:
1872 if( mission == 7 ) {
1873 playsound(S_MATRIXDOOR1,door->centx,door->centy,0,ST_UPDATE);
1874 }
1875 else {
1876 playsound(S_WH_7,door->centx,door->centy,0,ST_UPDATE);
1877 }
1878 door->goalz[0]=door->centz;
1879 door->goalz[2]=door->centz;
1880 break;
1881 case DOORSPLITVER:
1882 playsound(S_SIDEDOOR2,door->centx,door->centy,0,ST_UPDATE);
1883 if( wallptr[door->walls[0]]->x == wallptr[door->walls[3]]->x ) {
1884 door->goalz[0]=door->centy;
1885 door->goalz[2]=door->centy;
1886 }
1887 else {
1888 door->goalz[0]=door->centx;
1889 door->goalz[2]=door->centx;
1890 }
1891 door->goalz[1]=door->points[0];
1892 door->goalz[3]=door->points[2];
1893 break;
1894 case BOXELEVTAG:
1895 case PLATFORMELEVTAG:
1896 door->state=D_NOTHING;
1897 break;
1898 case BOXDELAYTAG:
1899 case PLATFORMDELAYTAG:
1900 playsound(S_PLATFORMSTART,door->centx,door->centy,0,ST_UPDATE);
1901 if( loopinsound == -1 ) {
1902 loopinsound=playsound(S_PLATFORMLOOP,door->centx,door->centy,20,ST_UNIQUE);
1903 }
1904 door->goalz[0]=evptrlist[s]->hilevel;
1905 break;
1906 default:
1907 break;
1908 }
1909 door->state=D_CLOSING;
1910 if( (hitag=sectptr[s]->hitag) > 0 ) {
1911 for( i=0 ; i < MAXSPRITES ; i++ ) {
1912 spr=sprptr[i];
1913 if( spr->hitag == hitag ) {
1914 switch (spr->picnum) {
1915 case SWITCH2ON:
1916 spr->picnum=SWITCH2OFF;
1917 break;
1918 case SWITCH3ON:
1919 spr->picnum=SWITCH3OFF;
1920 break;
1921 }
1922 }
1923 }
1924 for( i=0 ; i < numwalls ; i++ ) {
1925 wall=wallptr[i];
1926 if( wall->hitag == hitag ) {
1927 switch (wall->picnum) {
1928 case SWITCH2ON:
1929 wall->picnum=SWITCH2OFF;
1930 break;
1931 case SWITCH3ON:
1932 wall->picnum=SWITCH3OFF;
1933 break;
1934 }
1935 }
1936 }
1937 }
1938 break;
1939
1940 case D_OPENING:
1941 switch (door->type) {
1942 case DOORUPTAG:
1943 case DOORDOWNTAG:
1944 case PLATFORMDROPTAG:
1945 if( door->type == DOORUPTAG ) {
1946 z=sectptr[s]->ceilingz;
1947 }
1948 else {
1949 z=sectptr[s]->floorz;
1950 }
1951 z=stepdoor(z,door->goalz[0],door,D_OPENSOUND);
1952 if( door->type == DOORUPTAG ) {
1953 sectptr[s]->ceilingz=z;
1954 }
1955 else {
1956 sectptr[s]->floorz=z;
1957 }
1958 break;
1959 case DOORSPLITHOR:
1960 z=sectptr[s]->ceilingz;
1961 z=stepdoor(z,door->goalz[0],door,D_OPENSOUND);
1962 sectptr[s]->ceilingz=z;
1963 z=sectptr[s]->floorz;
1964 z=stepdoor(z,door->goalz[2],door,D_OPENSOUND);
1965 sectptr[s]->floorz=z;
1966 break;
1967 case DOORSPLITVER:
1968 if( wallptr[door->walls[0]]->x == wallptr[door->walls[3]]->x ) {
1969 for( i=0 ; i < 8 ; i++ ) {
1970 j=door->walls[i];
1971 z=wallptr[j]->y;
1972 z=stepdoor(z,door->goalz[i>>1],door,D_OPENSOUND);
1973 dragpoint(j,wallptr[j]->x,z, 0);
1974 }
1975 }
1976 else {
1977 for( i=0 ; i < 8 ; i++ ) {
1978 j=door->walls[i];
1979 z=wallptr[j]->x;
1980 z=stepdoor(z,door->goalz[i>>1],door,D_OPENSOUND);
1981 dragpoint(j,z,wallptr[j]->y, 0);
1982 }
1983 }
1984 break;
1985 case BOXELEVTAG:
1986 case PLATFORMELEVTAG:
1987 case BOXDELAYTAG:
1988 case PLATFORMDELAYTAG:
1989 size=sectptr[s]->ceilingz-sectptr[s]->floorz;
1990 z=sectptr[s]->floorz;
1991 z=stepdoor(z,door->goalz[0],door,D_OPENSOUND);
1992 sectptr[s]->floorz=z;
1993 if( door->type == BOXDELAYTAG || door->type == BOXELEVTAG ) {
1994 sectptr[s]->ceilingz=sectptr[s]->floorz+size;
1995 }
1996 break;
1997 default:
1998 break;
1999 }
2000 break;
2001
2002 case D_CLOSING:
2003 switch (door->type) {
2004 case DOORUPTAG:
2005 case DOORDOWNTAG:
2006 if( door->type == DOORUPTAG ) {
2007 z=sectptr[s]->ceilingz;
2008 }
2009 else {
2010 z=sectptr[s]->floorz;
2011 }
2012 z=stepdoor(z,door->goalz[0],door,D_SHUTSOUND);
2013 if( door->type == DOORUPTAG ) {
2014 sectptr[s]->ceilingz=z;
2015 }
2016 else {
2017 sectptr[s]->floorz=z;
2018 }
2019 break;
2020 case DOORSPLITHOR:
2021 z=sectptr[s]->ceilingz;
2022 z=stepdoor(z,door->goalz[0],door,D_SHUTSOUND);
2023 sectptr[s]->ceilingz=z;
2024 z=sectptr[s]->floorz;
2025 z=stepdoor(z,door->goalz[2],door,D_SHUTSOUND);
2026 sectptr[s]->floorz=z;
2027 break;
2028 case DOORSPLITVER:
2029 i=headspritesect[s];
2030 if (i != -1) {
2031 door->state=D_OPENDOOR;
2032 }
2033 for (i=connecthead ; i >= 0 ; i=connectpoint2[i]) {
2034 if (inside(posx[i],posy[i],s)) {
2035 door->state=D_OPENDOOR;
2036 }
2037 }
2038 if( wallptr[door->walls[0]]->x == wallptr[door->walls[3]]->x ) {
2039 for( i=0 ; i < 8 ; i++ ) {
2040 j=door->walls[i];
2041 z=wallptr[j]->y;
2042 z=stepdoor(z,door->goalz[i>>1],door,D_SHUTSOUND);
2043 dragpoint(j,wallptr[j]->x,z, 0);
2044 }
2045 }
2046 else {
2047 for( i=0 ; i < 8 ; i++ ) {
2048 j=door->walls[i];
2049 z=wallptr[j]->x;
2050 z=stepdoor(z,door->goalz[i>>1],door,D_SHUTSOUND);
2051 dragpoint(j,z,wallptr[j]->y, 0);
2052 }
2053 }
2054 break;
2055 case BOXDELAYTAG:
2056 case PLATFORMDELAYTAG:
2057 size=sectptr[s]->ceilingz-sectptr[s]->floorz;
2058 z=sectptr[s]->floorz;
2059 z=stepdoor(z,door->goalz[0],door,D_SHUTSOUND);
2060 sectptr[s]->floorz=z;
2061 if( door->type == BOXDELAYTAG ) {
2062 sectptr[s]->ceilingz=sectptr[s]->floorz+size;
2063 }
2064 break;
2065 default:
2066 break;
2067 }
2068 break;
2069
2070 case D_OPENSOUND:
2071 switch (door->type) {
2072 case DOORUPTAG:
2073 switch( door->subtype ) {
2074 case DST_BAYDOOR:
2075 playsound(S_BAYDOOR_CLOSE,door->centx,door->centy,0,ST_UPDATE);
2076 if( baydoorloop>=0 ) {
2077 stopsound(baydoorloop);
2078 baydoorloop=-1;
2079 }
2080 break;
2081 case DST_HYDRAULICDOOR:
2082 playsound(S_AIRDOOR_CLOSE,door->centx,door->centy,0,ST_UPDATE);
2083 break;
2084
2085
2086 case DST_ELEVATORDOOR:
2087 case DST_MATRIXDOOR1:
2088 case DST_MATRIXDOOR2:
2089 case DST_MATRIXDOOR3:
2090 case DST_MATRIXDOOR4:
2091 break;
2092 default:
2093 if( mission != 7 ) {
2094 playsound(S_DOORKLUNK,door->centx,door->centy,0,ST_UPDATE);
2095 }
2096 break;
2097 }
2098 door->state=D_WAITING;
2099 showsect2d(door->sector,door->goalz[0]);
2100 break;
2101
2102 case DOORDOWNTAG:
2103 playsound(S_WH_6,door->centx,door->centy,0,ST_UPDATE);
2104 showsect2dtoggle(door->sector,0);
2105 door->state=D_WAITING;
2106 break;
2107
2108 case BOXELEVTAG:
2109 case PLATFORMELEVTAG:
2110 case PLATFORMDROPTAG:
2111 door->state=D_WAITING;
2112 showsect2d(door->sector,door->goalz[0]);
2113 break;
2114 case PLATFORMDELAYTAG:
2115 default:
2116 if( door->type == BOXDELAYTAG || door->type == PLATFORMDELAYTAG ) {
2117 playsound(S_PLATFORMSTOP,door->centx,door->centy,0,ST_UPDATE);
2118 if( loopinsound >= 0 ) {
2119 stopsound(loopinsound);
2120 loopinsound=-1;
2121 }
2122 showsect2d(door->sector,door->goalz[0]);
2123 }
2124 else {
2125 showsect2dtoggle(door->sector,0);
2126 }
2127 door->state=D_WAITING;
2128 break;
2129 }
2130 break;
2131
2132 case D_SHUTSOUND:
2133 switch (door->type) {
2134 case DOORUPTAG:
2135 switch( door->subtype ) {
2136 case DST_BAYDOOR:
2137 playsound(S_BAYDOOR_CLOSE,door->centx,door->centy,0,ST_UPDATE);
2138 if( baydoorloop>=0 ) {
2139 stopsound(baydoorloop);
2140 baydoorloop=-1;
2141 }
2142 break;
2143
2144 case DST_HYDRAULICDOOR:
2145 playsound(S_AIRDOOR_CLOSE,door->centx,door->centy,0,ST_UPDATE);
2146 break;
2147
2148 case DST_ELEVATORDOOR:
2149 case DST_MATRIXDOOR1:
2150 case DST_MATRIXDOOR2:
2151 case DST_MATRIXDOOR3:
2152 case DST_MATRIXDOOR4:
2153 break;
2154 default:
2155 if( mission != 7 ) {
2156 playsound(S_DOORKLUNK,door->centx,door->centy,0,ST_UPDATE);
2157 }
2158 break;
2159 }
2160 door->state=D_NOTHING;
2161 showsect2d(door->sector,door->goalz[0]);
2162 break;
2163
2164 case DOORDOWNTAG:
2165 showsect2dtoggle(door->sector,1);
2166 playsound(S_WH_6,door->centx,door->centy,0,ST_UPDATE);
2167 break;
2168
2169 case BOXELEVTAG:
2170 case PLATFORMELEVTAG:
2171 case BOXDELAYTAG:
2172 case PLATFORMDELAYTAG:
2173 playsound(S_PLATFORMSTOP,door->centx,door->centy,0,ST_UPDATE);
2174 if( loopinsound>=0 ) {
2175 stopsound(loopinsound);
2176 loopinsound=-1;
2177 }
2178 showsect2d(door->sector,door->goalz[0]);
2179 break;
2180 default:
2181 showsect2dtoggle(door->sector,1);
2182 break;
2183 }
2184 door->state=D_NOTHING;
2185 break;
2186 }
2187
2188 }
2189
2190 void
movesprelevs(int e)2191 movesprelevs(int e)
2192 {
2193 int i,j,n,tics;
2194 int goalz;
2195 struct spriteelev *s;
2196 spritetype *spr;
2197
2198 s=sprelevptr[e];
2199 tics=TICSPERFRAME<<6;
2200 switch (s->state) {
2201 case E_WAITING:
2202 s->delay-=TICSPERFRAME;
2203 if (s->delay <= 0) {
2204 s->state=E_CLOSINGDOOR;
2205 }
2206 return;
2207 case E_CLOSINGDOOR:
2208 s->doorpos-=tics;
2209 if (s->doorpos <= 0) {
2210 s->doorpos=0;
2211 s->state=E_NEXTFLOOR;
2212 }
2213 break;
2214 case E_OPENINGDOOR:
2215 s->doorpos+=tics;
2216 if (s->doorpos >= E_DOOROPENPOS) {
2217 s->doorpos=E_DOOROPENPOS;
2218 s->state=E_WAITING;
2219 s->delay=E_WAITDELAY;
2220 }
2221 break;
2222 case E_MOVING:
2223 goalz=s->floorz[s->curfloor];
2224 if (s->curdir == E_GOINGUP) {
2225 s->floorpos-=tics;
2226 if (s->floorpos <= goalz) {
2227 s->floorpos+=labs(s->floorpos-goalz);
2228 s->state=E_OPENINGDOOR;
2229 }
2230 }
2231 else {
2232 s->floorpos+=tics;
2233 if (s->floorpos >= goalz) {
2234 s->floorpos-=labs(s->floorpos-goalz);
2235 s->state=E_OPENINGDOOR;
2236 }
2237 }
2238 break;
2239 case E_NEXTFLOOR:
2240 if (s->curdir == E_GOINGUP) {
2241 s->curfloor++;
2242 if (s->curfloor > s->floors) {
2243 s->curfloor-=2;
2244 s->curdir=E_GOINGDOWN;
2245 //playsound(S_COPSEE1,sprptr[s->sprnum[0]]->x,sprptr[s->sprnum[0]]->y,0,ST_UNIQUE);
2246 }
2247 }
2248 else if (s->curdir == E_GOINGDOWN) {
2249 s->curfloor--;
2250 if (s->curfloor < 0) {
2251 s->curfloor+=2;
2252 s->curdir=E_GOINGUP;
2253 //playsound(S_COPSEE2,sprptr[s->sprnum[0]]->x,sprptr[s->sprnum[0]]->y,0,ST_UNIQUE);
2254 }
2255 }
2256 s->state=E_MOVING;
2257 break;
2258 }
2259 for (i=0 ; i < s->parts ; i++) {
2260 j=s->sprnum[i];
2261 spr=sprptr[j];
2262 spr->z=s->startz[i]+s->floorpos-s->floorz[0];
2263 for (n=0 ; n < s->doors ; n++) {
2264 if (j == s->door[n]) {
2265 spr->z-=s->doorpos;
2266 }
2267 }
2268 }
2269 }
2270
2271 void
movefloordoor(int d)2272 movefloordoor(int d)
2273 {
2274 int j,s,tics;
2275 struct floordoor *dptr;
2276
2277 tics=TICSPERFRAME<<2;
2278 dptr=floordoorptr[d];
2279 switch (dptr->state) {
2280 case DOOROPENING:
2281 if (dptr->dist1 > 0) {
2282 s=tics;
2283 dptr->dist1-=s;
2284 if (dptr->dist1 < 0) {
2285 s+=dptr->dist1;
2286 dptr->dist1=0;
2287 }
2288 switch (dptr->dir) {
2289 case 0:
2290 j=dptr->wall1;
2291 dragpoint(j,wallptr[j]->x,wallptr[j]->y-s, 0);
2292 j=wallptr[j]->point2;
2293 dragpoint(j,wallptr[j]->x,wallptr[j]->y-s,0 );
2294 break;
2295 case 1:
2296 j=dptr->wall1;
2297 dragpoint(j,wallptr[j]->x+s,wallptr[j]->y, 0);
2298 j=wallptr[j]->point2;
2299 dragpoint(j,wallptr[j]->x+s,wallptr[j]->y, 0);
2300 break;
2301 case 2:
2302 j=dptr->wall1;
2303 dragpoint(j,wallptr[j]->x,wallptr[j]->y+s, 0);
2304 j=wallptr[j]->point2;
2305 dragpoint(j,wallptr[j]->x,wallptr[j]->y+s, 0);
2306 break;
2307 case 3:
2308 j=dptr->wall1;
2309 dragpoint(j,wallptr[j]->x-s,wallptr[j]->y, 0);
2310 j=wallptr[j]->point2;
2311 dragpoint(j,wallptr[j]->x-s,wallptr[j]->y, 0);
2312 break;
2313 }
2314 }
2315 if (dptr->dist2 > 0) {
2316 s=tics;
2317 dptr->dist2-=s;
2318 if (dptr->dist2 < 0) {
2319 s+=dptr->dist2;
2320 dptr->dist2=0;
2321 }
2322 switch (dptr->dir) {
2323 case 0:
2324 j=dptr->wall2;
2325 dragpoint(j,wallptr[j]->x,wallptr[j]->y+s, 0);
2326 j=wallptr[j]->point2;
2327 dragpoint(j,wallptr[j]->x,wallptr[j]->y+s, 0);
2328 break;
2329 case 1:
2330 j=dptr->wall2;
2331 dragpoint(j,wallptr[j]->x-s,wallptr[j]->y, 0);
2332 j=wallptr[j]->point2;
2333 dragpoint(j,wallptr[j]->x-s,wallptr[j]->y, 0);
2334 break;
2335 case 2:
2336 j=dptr->wall2;
2337 dragpoint(j,wallptr[j]->x,wallptr[j]->y-s, 0);
2338 j=wallptr[j]->point2;
2339 dragpoint(j,wallptr[j]->x,wallptr[j]->y-s, 0);
2340 break;
2341 case 3:
2342 j=dptr->wall2;
2343 dragpoint(j,wallptr[j]->x+s,wallptr[j]->y, 0);
2344 j=wallptr[j]->point2;
2345 dragpoint(j,wallptr[j]->x+s,wallptr[j]->y, 0);
2346 break;
2347 }
2348 }
2349 if (dptr->dist1 <= 0 && dptr->dist2 <= 0) {
2350 dptr->state=DOOROPENED;
2351 }
2352 break;
2353 case DOORCLOSING:
2354 case DOOROPENED:
2355 case DOORCLOSED:
2356 break;
2357 }
2358 }
2359
2360 void
clearvehiclesoundindexes()2361 clearvehiclesoundindexes()
2362 {
2363 int i;
2364
2365 for( i=0; i < MAXSECTORVEHICLES; i++ ) {
2366 sectvehptr[i]->soundindex=-1;
2367 }
2368 }
2369
2370 void
movevehicles(int v)2371 movevehicles(int v)
2372 {
2373 short a,angv,ato,angto,curang,i,n,p,rotang,s,sto,stoptrack,track;
2374 int distx,disty,px,py,x,y;
2375 int xvect,xvect2,yvect,yvect2;
2376 int lox,loy,hix,hiy;
2377 short onveh[MAXPLAYERS];
2378 struct sectorvehicle *vptr;
2379
2380 vptr=sectvehptr[v];
2381
2382 if( vptr->soundindex == -1 ) {
2383
2384 for( i=0; i<32; i++) { //find mapno using names array
2385 if( !(Bstrcasecmp(boardfilename,mapnames[i]) ) )
2386 break;
2387 }
2388 switch( v ) {
2389 case 0:
2390 switch( i ) {
2391 case 4: //level1.map
2392 vptr->soundindex=playsound(S_TRAMBUSLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2393 break;
2394 case 8: //city1.map
2395 vptr->soundindex=playsound(S_TRUCKLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2396 break;
2397 case 11: //beach1.map
2398 vptr->soundindex=playsound(S_FORKLIFTLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2399 break;
2400 case 17: //mid3.map
2401 vptr->soundindex=playsound(S_TRAMBUSLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2402 break;
2403 case 19: //sewer2.map
2404 vptr->soundindex=playsound(S_FORKLIFTLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2405 break;
2406 case 20: //inds1.map
2407 vptr->soundindex=playsound(S_FORKLIFTLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2408 break;
2409 case 25: //ware1.map
2410 vptr->soundindex=playsound(S_FORKLIFTLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2411 break;
2412 case 26: //ware2.map
2413 vptr->soundindex=playsound(S_TRUCKLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2414 break;
2415 default:
2416 break;
2417 }
2418 break;
2419 case 1:
2420 switch( i ) {
2421 case 4: //level1.map
2422 vptr->soundindex=playsound(S_TRAMBUSLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2423 break;
2424 case 11: //beach1.map
2425 vptr->soundindex=playsound(S_BOATLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2426 break;
2427 case 26: //ware2.map
2428 vptr->soundindex=playsound(S_CARTLOOP,vptr->pivotx,vptr->pivoty,-1,ST_VEHUPDATE);
2429 break;
2430 default:
2431 break;
2432 }
2433 break;
2434 default:
2435 break;
2436 }
2437 }
2438
2439 if( vptr->waittics > 0 ) {
2440 vptr->waittics-=TICSPERFRAME;
2441 if( vptr->soundindex != -1 ) {
2442 updatevehiclesnds(vptr->soundindex, vptr->pivotx, vptr->pivoty);
2443 }
2444 return;
2445 }
2446
2447 px=vptr->pivotx;
2448 py=vptr->pivoty;
2449
2450 track=vptr->track;
2451 distx=vptr->distx;
2452 disty=vptr->disty;
2453 stoptrack=vptr->stoptrack;
2454 if( vptr->stop[track] && (x=distx+disty) > 0L && x < 8192L ) {
2455 vptr->accelto=2;
2456 vptr->speedto=32;
2457 }
2458 else if( vptr->accelto != 8 ) {
2459 vptr->accelto=8;
2460 vptr->speedto=vptr->movespeed;
2461 }
2462 if( distx == 0L && disty == 0L ) {
2463 if( vptr->stop[stoptrack] ) {
2464 for( i=0 ; i < vptr->numsectors ; i++ ) {
2465 s=vptr->sector[i];
2466 if( sectptr[s]->lotag != 0 ) {
2467 operatesector(s);
2468 }
2469 }
2470 vptr->waittics=vptr->waitdelay;
2471 vptr->acceleration=0;
2472 vptr->speed=0;
2473
2474 }
2475 distx=vptr->trackx[track]-px;
2476 disty=vptr->tracky[track]-py;
2477 vptr->angleto=getangle(distx,disty);
2478 vptr->accelto=8;
2479 vptr->distx=labs(distx);
2480 vptr->disty=labs(disty);
2481 distx=vptr->distx;
2482 disty=vptr->disty;
2483 }
2484 a=vptr->acceleration;
2485 ato=vptr->accelto;
2486 if( a < ato ) {
2487 a+=TICSPERFRAME;
2488 if( a > ato ) {
2489 a=ato;
2490 }
2491 vptr->acceleration=a;
2492 }
2493 else if( a > ato ) {
2494 a-=TICSPERFRAME;
2495 if( a < ato ) {
2496 a=ato;
2497 }
2498 vptr->acceleration=a;
2499 }
2500 s=vptr->speed;
2501 sto=vptr->speedto;
2502 if( s > sto ) {
2503 s-=a;
2504 if( s <= sto ) {
2505 s=sto;
2506 }
2507 vptr->speed=s;
2508 }
2509 else if( s < sto ) {
2510 s+=a;
2511 if( s > sto ) {
2512 s=sto;
2513 }
2514 vptr->speed=s;
2515 }
2516 rotang=curang=vptr->angle;
2517 if( curang != vptr->angleto ) {
2518 vptr->angle=vptr->angleto;
2519 curang=vptr->angle;
2520 }
2521 xvect=(s*(int)TICSPERFRAME*(int)sintable[((curang+2560)&2047)])>>3;
2522 xvect2=xvect>>13;
2523 yvect=(s*(int)TICSPERFRAME*(int)sintable[((curang+2048)&2047)])>>3;
2524 yvect2=yvect>>13;
2525 distx-=labs(xvect2);
2526 if( distx < 0L ) {
2527 if( xvect2 < 0L ) {
2528 xvect2-=distx;
2529 }
2530 else {
2531 xvect2+=distx;
2532 }
2533 distx=0L;
2534 vptr->angleto=getangle(vptr->trackx[track]-px,vptr->tracky[track]-py);
2535 }
2536 disty-=labs(yvect2);
2537 if( disty < 0L ) {
2538 if( yvect2 < 0L ) {
2539 yvect2-=disty;
2540 }
2541 else {
2542 yvect2+=disty;
2543 }
2544 disty=0L;
2545 vptr->angleto=getangle(vptr->trackx[track]-px,vptr->tracky[track]-py);
2546 }
2547 if( distx == 0L && disty == 0L ) {
2548 vptr->stoptrack=track;
2549 track=(track+1)%vptr->tracknum;
2550 vptr->track=track;
2551 switch( v ) {
2552 //jsa vehicles
2553 case 0:
2554 if( !(Bstrcasecmp(boardfilename,"CITY1.MAP")) || !(Bstrcasecmp(boardfilename,"WARE2.MAP")))
2555 playsound(S_TRUCKSTOP,vptr->pivotx,vptr->pivoty,0,ST_AMBUPDATE);
2556 break;
2557 default:
2558 break;
2559 }
2560 }
2561 vptr->distx=distx;
2562 vptr->disty=disty;
2563 px+=xvect2;
2564 py+=yvect2;
2565 n=vptr->numpoints;
2566 for( i=0 ; i < n ; i++ )
2567 {
2568 p=vptr->point[i];
2569 x=vptr->pointx[i];
2570 y=vptr->pointy[i];
2571
2572 vec2_t pivot;
2573 pivot.x = px;
2574 pivot.y = py;
2575 vec2_t p1;
2576 p1.x = px - x;
2577 p1.y = py - y;
2578 vec2_t p2;
2579
2580 rotatepoint(pivot,p1,curang,&p2);
2581 x = p2.x; y = p2.y;
2582 dragpoint(p,x,y, 0);
2583 }
2584 vptr->pivotx=px;
2585 vptr->pivoty=py;
2586 rotang=((curang-rotang)+2048)&2047;
2587 n=vptr->numsectors;
2588 lox=loy=0x7FFFFFFF;
2589 hix=hiy=-(0x7FFFFFFF);
2590 for( i=0 ; i < 4 ; i++ ) {
2591 a=vptr->killw[i];
2592 if( wallptr[a]->x < lox ) {
2593 lox=wallptr[a]->x;
2594 }
2595 else if( wallptr[a]->x > hix ) {
2596 hix=wallptr[a]->x;
2597 }
2598 if( wallptr[a]->y < loy ) {
2599 loy=wallptr[a]->y;
2600 }
2601 else if (wallptr[a]->y > hiy) {
2602 hiy=wallptr[a]->y;
2603 }
2604 }
2605 memset(onveh,0,sizeof(short)*MAXPLAYERS);
2606 for( i=0 ; i < n ; i++ ) {
2607 p=headspritesect[vptr->sector[i]];
2608 while (p >= 0)
2609 {
2610 s=nextspritesect[p];
2611 x=sprptr[p]->x;
2612 y=sprptr[p]->y;
2613 x+=xvect2;
2614 y+=yvect2;
2615
2616 vec2_t pivot;
2617 pivot.x = px; pivot.y = py;
2618 vec2_t p1;
2619 p1.x = x; p1.y = y;
2620 vec2_t p2;
2621 rotatepoint(pivot,p1,rotang,&p2);
2622 sprptr[p]->x = p2.x;
2623 sprptr[p]->y = p2.y;
2624
2625 sprptr[p]->ang+=rotang;
2626 p=s;
2627 }
2628 for( p=connecthead ; p >= 0 ; p=connectpoint2[p] ) {
2629 x=posx[p];
2630 y=posy[p];
2631 if( cursectnum[p] == vptr->sector[i] ) {
2632 x+=xvect2;
2633 y+=yvect2;
2634 vec2_t pivot;
2635 pivot.x = px; pivot.y = py;
2636 vec2_t p2;
2637 p2.x = x; p2.y = y;
2638 vec2_t pos;
2639 rotatepoint(pivot,p2,rotang,&pos);
2640 posx[p] = pos.x; posy[p] = pos.y;
2641 ang[p]+=rotang;
2642 onveh[p]=1;
2643 }
2644 }
2645 }
2646 for( p=connecthead ; p >= 0 ; p=connectpoint2[p] ) {
2647 if( onveh[p] ) {
2648 continue;
2649 }
2650 x=posx[p];
2651 y=posy[p];
2652 if( x > lox && x < hix && y > loy && y < hiy ) {
2653 if( (health[p] > 0) && (posz[p] > VEHICLEHEIGHT) ) {
2654 changehealth(p,-9999);
2655 changescore(p,-100);
2656 if( goreflag ) {
2657 tekexplodebody(playersprite[p]);
2658 }
2659 }
2660 }
2661 }
2662 if( vptr->soundindex != -1 ) {
2663 updatevehiclesnds(vptr->soundindex, vptr->pivotx, vptr->pivoty);
2664 }
2665 }
2666
2667 void // kick off function after specified tics elapse
teksetdelayfunc(void (* delayfunc)(short),int tics,short parm)2668 teksetdelayfunc(void (*delayfunc)(short),int tics,short parm)
2669 {
2670 int i,n;
2671
2672 if (delayfunc == NULL) {
2673 return;
2674 }
2675 n=numdelayfuncs;
2676 for (i=0 ; i < n ; i++) {
2677 if (delayfuncptr[i]->func == delayfunc) {
2678 if (tics == 0) {
2679 memmove(delayfuncptr[i],delayfuncptr[numdelayfuncs-1],
2680 sizeof(struct delayfunc));
2681 memset(delayfuncptr[numdelayfuncs-1],0,
2682 sizeof(struct delayfunc));
2683 numdelayfuncs--;
2684 return;
2685 }
2686 else {
2687 delayfuncptr[i]->tics=tics;
2688 delayfuncptr[i]->parm=parm;
2689 return;
2690 }
2691 }
2692 }
2693 delayfuncptr[numdelayfuncs]->func=delayfunc;
2694 delayfuncptr[numdelayfuncs]->tics=tics;
2695 delayfuncptr[numdelayfuncs]->parm=parm;
2696 numdelayfuncs++;
2697 }
2698
2699 void
tekdodelayfuncs(void)2700 tekdodelayfuncs(void)
2701 {
2702 int i,n,p;
2703
2704 n=numdelayfuncs;
2705 for (i=0 ; i < n ; i++) {
2706 if (delayfuncptr[i]->func == NULL) {
2707 continue;
2708 }
2709 delayfuncptr[i]->tics-=TICSPERFRAME;
2710 if (delayfuncptr[i]->tics <= 0) {
2711 p=delayfuncptr[i]->parm;
2712 (*delayfuncptr[i]->func)(p);
2713 memmove(delayfuncptr[i],delayfuncptr[numdelayfuncs-1],
2714 sizeof(struct delayfunc));
2715 memset(delayfuncptr[numdelayfuncs-1],0,
2716 sizeof(struct delayfunc));
2717 numdelayfuncs--;
2718 }
2719 }
2720 }
2721
2722 void
setanimpic(short * pic,short tics,short frames)2723 setanimpic(short *pic,short tics,short frames)
2724 {
2725 int i;
2726
2727 for (i=0 ; i < numanimates ; i++) {
2728 if (animpicptr[i]->pic == pic) {
2729 return;
2730 }
2731 }
2732 if (numanimates+1 < MAXANIMPICS) {
2733 animpicptr[numanimates]->pic=pic;
2734 animpicptr[numanimates]->tics=tics;
2735 animpicptr[numanimates]->frames=frames;
2736 animpicptr[numanimates]->nextclock=lockclock+tics;
2737 numanimates++;
2738 }
2739 }
2740
2741 void
tekdoanimpic(void)2742 tekdoanimpic(void)
2743 {
2744 short pic;
2745 int i,n;
2746
2747 n=numanimates;
2748 for (i=0 ; i < n ; i++) {
2749 if (lockclock < animpicptr[i]->nextclock) {
2750 continue;
2751 }
2752 if (animpicptr[i]->frames > 0) {
2753 if (--animpicptr[i]->frames > 0) {
2754 pic=*animpicptr[i]->pic;
2755 pic++;
2756 *animpicptr[i]->pic=pic;
2757 animpicptr[i]->nextclock=lockclock+animpicptr[i]->tics;
2758 }
2759 }
2760 else if (animpicptr[i]->frames < 0) {
2761 if (++animpicptr[i]->frames < 0) {
2762 pic=*animpicptr[i]->pic;
2763 pic--;
2764 *animpicptr[i]->pic=pic;
2765 animpicptr[i]->nextclock=lockclock+animpicptr[i]->tics;
2766 }
2767 }
2768 else {
2769 numanimates--;
2770 if (numanimates > 0) {
2771 memmove(animpicptr[i],animpicptr[numanimates],
2772 sizeof(struct animpic));
2773 memset(animpicptr[numanimates],0,sizeof(struct animpic));
2774 }
2775 }
2776 }
2777 }
2778
2779 void
checkmapsndfx(short p)2780 checkmapsndfx(short p)
2781 {
2782
2783 int i,s;
2784 int dist;
2785 unsigned int effect;
2786 struct sectoreffect *septr;
2787
2788 s=cursectnum[p];
2789 septr=septrlist[s];
2790
2791 for( i=0; i<totalmapsndfx; i++ ) {
2792 switch(mapsndfxptr[i]->type) {
2793 case MAP_SFX_AMBIENT:
2794 dist=labs(posx[p]-mapsndfxptr[i]->x)+labs(posy[p]-mapsndfxptr[i]->y);
2795 if( (dist > AMBUPDATEDIST) && (mapsndfxptr[i]->id!=-1) ) {
2796 stopsound(mapsndfxptr[i]->id);
2797 mapsndfxptr[i]->id=-1;
2798 }
2799 else if( (dist < AMBUPDATEDIST) && (mapsndfxptr[i]->id==-1) ) {
2800 mapsndfxptr[i]->id=playsound(mapsndfxptr[i]->snum, mapsndfxptr[i]->x,mapsndfxptr[i]->y, mapsndfxptr[i]->loops, ST_AMBUPDATE);
2801 }
2802 break;
2803 case MAP_SFX_SECTOR:
2804 if((cursectnum[p] != ocursectnum[p]) && (cursectnum[p] == mapsndfxptr[i]->sector) ) {
2805 mapsndfxptr[i]->id=playsound(mapsndfxptr[i]->snum, mapsndfxptr[i]->x,mapsndfxptr[i]->y, mapsndfxptr[i]->loops, ST_UNIQUE);
2806 }
2807 break;
2808 default:
2809 break;
2810 }
2811 }
2812
2813 if( !Bstrncasecmp("SUBWAY",boardfilename,6) ) {
2814 if( ambsubloop == -1 ) {
2815 ambsubloop=playsound(S_SUBSTATIONLOOP, 0, 0, -1, ST_IMMEDIATE);
2816 }
2817 }
2818 else {
2819 if( ambsubloop != -1 ) {
2820 stopsound(ambsubloop);
2821 ambsubloop=-1;
2822 }
2823 }
2824
2825 if( septr != NULL ) {
2826 effect=septr->sectorflags;
2827 if( (effect&flags32[SOUNDON]) != 0 ) {
2828 for( i=0; i<totalmapsndfx; i++ ) {
2829 if( mapsndfxptr[i]->type == MAP_SFX_TOGGLED ) {
2830 if( sectptr[mapsndfxptr[i]->sector]->hitag == septr->hi ) {
2831 if( mapsndfxptr[i]->id == -1 ) {
2832 mapsndfxptr[i]->id=playsound(mapsndfxptr[i]->snum, mapsndfxptr[i]->x,mapsndfxptr[i]->y, mapsndfxptr[i]->loops,ST_UNIQUE | ST_IMMEDIATE);;
2833 }
2834 }
2835 }
2836 }
2837 }
2838 if( (effect&flags32[SOUNDOFF]) != 0 ) {
2839 for( i=0; i<totalmapsndfx; i++ ) {
2840 if( mapsndfxptr[i]->type == MAP_SFX_TOGGLED ) {
2841 if( sectptr[mapsndfxptr[i]->sector]->hitag == septr->hi ) {
2842 if( mapsndfxptr[i]->id != -1 ) {
2843 stopsound(mapsndfxptr[i]->id);
2844 mapsndfxptr[i]->id=-1;
2845 }
2846 }
2847 }
2848 }
2849 }
2850 }
2851
2852 // ambupdateclock=totalclock;
2853 ambupdateclock=lockclock;
2854 }
2855
2856 void
tektagsave(int fil)2857 tektagsave(int fil)
2858 {
2859 int i,rv;
2860
2861 rv=write(fil,&numanimates,sizeof(int));
2862 for (i=0 ; i < numanimates ; i++) {
2863 write(fil,&animpic[i],sizeof(struct animpic));
2864 }
2865 rv=write(fil,&numdelayfuncs,sizeof(short));
2866 for (i=0 ; i < numdelayfuncs ; i++) {
2867 write(fil,&delayfunc[i],sizeof(struct delayfunc));
2868 }
2869 rv=write(fil,onelev,MAXPLAYERS);
2870 rv=write(fil,&secnt,sizeof(int));
2871 for (i=0 ; i < secnt ; i++) {
2872 write(fil,§oreffect[i],sizeof(struct sectoreffect));
2873 }
2874 rv=write(fil,sexref,MAXSECTORS*sizeof(int));
2875 rv=write(fil,&numdoors,sizeof(int));
2876 for (i=0 ; i < numdoors ; i++) {
2877 write(fil,&doortype[i],sizeof(struct doortype));
2878 }
2879 write(fil,&numfloordoors,sizeof(int));
2880 for (i=0 ; i < numfloordoors ; i++) {
2881 write(fil,&floordoor[i],sizeof(struct floordoor));
2882 }
2883 write(fil,fdxref,MAXSECTORS*sizeof(int));
2884 write(fil,&numvehicles,sizeof(int));
2885 for (i=0 ; i < numvehicles ; i++) {
2886 write(fil,§orvehicle[i],sizeof(struct sectorvehicle));
2887 }
2888 write(fil,elevator,MAXSECTORS*sizeof(struct elevatortype));
2889 write(fil,&sprelevcnt,sizeof(int));
2890 for (i=0 ; i < sprelevcnt ; i++) {
2891 write(fil,&spriteelev[i],sizeof(struct spriteelev));
2892 }
2893 write(fil,&totalmapsndfx,sizeof(int));
2894 for (i=0 ; i < totalmapsndfx ; i++) {
2895 write(fil,&mapsndfx[i],sizeof(struct mapsndfxtype));
2896 }
2897 }
2898
2899 void
tektagload(int fil)2900 tektagload(int fil)
2901 {
2902 int i,rv;
2903
2904 rv=read(fil,&numanimates,sizeof(int));
2905 for (i=0 ; i < numanimates ; i++) {
2906 read(fil,&animpic[i],sizeof(struct animpic));
2907 }
2908 rv=read(fil,&numdelayfuncs,sizeof(short));
2909 for (i=0 ; i < numdelayfuncs ; i++) {
2910 read(fil,&delayfunc[i],sizeof(struct delayfunc));
2911 }
2912 rv=read(fil,onelev,MAXPLAYERS);
2913 rv=read(fil,&secnt,sizeof(int));
2914 for (i=0 ; i < secnt ; i++) {
2915 read(fil,§oreffect[i],sizeof(struct sectoreffect));
2916 }
2917 rv=read(fil,sexref,MAXSECTORS*sizeof(int));
2918 rv=read(fil,&numdoors,sizeof(int));
2919 for (i=0 ; i < numdoors ; i++) {
2920 read(fil,&doortype[i],sizeof(struct doortype));
2921 }
2922 read(fil,&numfloordoors,sizeof(int));
2923 for (i=0 ; i < numfloordoors ; i++) {
2924 read(fil,&floordoor[i],sizeof(struct floordoor));
2925 }
2926 read(fil,fdxref,MAXSECTORS*sizeof(int));
2927 read(fil,&numvehicles,sizeof(int));
2928 for (i=0 ; i < numvehicles ; i++) {
2929 read(fil,§orvehicle[i],sizeof(struct sectorvehicle));
2930 }
2931
2932 // must reinvoke vehicle sounds since all sounds were stopped
2933 // else updatevehiclesounds will update whatever is using
2934 // dsoundptr[vptr->soundindex]
2935 clearvehiclesoundindexes();
2936
2937 read(fil,elevator,MAXSECTORS*sizeof(struct elevatortype));
2938 read(fil,&sprelevcnt,sizeof(int));
2939 for (i=0 ; i < sprelevcnt ; i++) {
2940 read(fil,&spriteelev[i],sizeof(struct spriteelev));
2941 }
2942 read(fil,&totalmapsndfx,sizeof(int));
2943 for (i=0 ; i < totalmapsndfx ; i++) {
2944 read(fil,&mapsndfx[i],sizeof(struct mapsndfxtype));
2945 // did we leave with a TOGGLED sound playong ?
2946 if( (mapsndfx[i].type == MAP_SFX_TOGGLED) && (mapsndfx[i].id != -1) ) {
2947 mapsndfxptr[i]->id=playsound(mapsndfxptr[i]->snum, mapsndfxptr[i]->x,mapsndfxptr[i]->y, mapsndfxptr[i]->loops, ST_UNIQUE);
2948 }
2949 }
2950 }
2951
2952 void
tekheadbob(void)2953 tekheadbob(void)
2954 {
2955 if( headbobon && (activemenu == 0) ) {
2956 headbob+=bobstep;
2957 if( headbob < -BOBBMAX || headbob > BOBBMAX ) {
2958 bobstep=-bobstep;
2959 }
2960 }
2961 }
2962
2963 void
tekswitchtrigger(short snum)2964 tekswitchtrigger(short snum)
2965 {
2966 int i,j;
2967 int nexti;
2968 int dax,day;
2969
2970 j=sprite[neartagsprite].picnum;
2971
2972 switch( j ) {
2973 case SWITCH2OFF:
2974 if( invredcards[snum] == 0 ) {
2975 showmessage("PASSAGE REQUIRES RED KEYCARD");
2976 return;
2977 }
2978 break;
2979 case SWITCH4OFF:
2980 if( invbluecards[snum] == 0 ) {
2981 showmessage("PASSAGE REQUIRES BLUE KEYCARD");
2982 return;
2983 }
2984 break;
2985 }
2986
2987 switch( j ) {
2988 case SWITCH2ON:
2989 case SWITCH2OFF:
2990 case SWITCH3ON:
2991 case SWITCH3OFF:
2992 case SWITCH4ON:
2993 case SWITCH4OFF:
2994 dax = sprite[neartagsprite].x;
2995 day = sprite[neartagsprite].y;
2996 playsound(S_KEYCARDBLIP, dax,day,0, ST_UPDATE);
2997 break;
2998 default:
2999 break;
3000 }
3001
3002 if (j == SWITCH2ON) sprite[neartagsprite].picnum = SWITCH2OFF;
3003 if (j == SWITCH2OFF) sprite[neartagsprite].picnum = SWITCH2ON;
3004 if (j == SWITCH3ON) sprite[neartagsprite].picnum = SWITCH3OFF;
3005 if (j == SWITCH3OFF) sprite[neartagsprite].picnum = SWITCH3ON;
3006 if (j == SWITCH4ON) sprite[neartagsprite].picnum = SWITCH4OFF;
3007 if (j == SWITCH4OFF) sprite[neartagsprite].picnum = SWITCH4ON;
3008
3009 if (j == 3708) sprite[neartagsprite].picnum = 3709;
3010 if (j == 3709) sprite[neartagsprite].picnum = 3708;
3011
3012 for(i=0;i<numsectors;i++)
3013 if (sector[i].hitag == sprite[neartagsprite].hitag)
3014 if (sector[i].lotag != 1)
3015 operatesector(i);
3016
3017 i = headspritestat[0];
3018 while (i != -1)
3019 {
3020 nexti = nextspritestat[i];
3021 if (sprite[i].hitag == sprite[neartagsprite].hitag)
3022 operatesprite(i);
3023 i = nexti;
3024 }
3025
3026
3027 }
3028
3029 int
krand_intercept(const char * stg)3030 krand_intercept(const char *stg)
3031 {
3032 if (dbgflag) {
3033 if (dbgcolumn > 80) {
3034 fprintf(dbgfp,"\n");
3035 dbgcolumn=0;
3036 }
3037 else {
3038 fprintf(dbgfp,"%s(%-9d) ",stg,randomseed);
3039 dbgcolumn+=20;
3040 }
3041 }
3042 return(krand());
3043 }
3044
3045